58

As my keyboard layout doesn't suit me, I run xmodmap on login. The script is named .profile and it runs OK, but it breaks the Unity interface.

I want to know where to put the xmodmap line so that it executes on my login and doesn't break anything.

I have already tried putting it in the .bash_login and .bash_profile files, without success (xmodmap doesn't set my keyboard).

What are my options?

2
  • 4
    How does it break the unity interface?
    – djeikyb
    Jul 23, 2011 at 0:28
  • 1
    I would like to add that if your xmodmap execution time is too long, you should remove all entries that you did not modify by hand. Keeping only the changes in your input file will make xmodmap run much faster. Nov 29, 2016 at 1:31

8 Answers 8

45

The correct place to put xmodmap ~/.Xmodmap (so that your changes are read at startup) is in ~/.xinitrc (see explanation below), although you could alternately place the xmodmap command as a startup item (/usr/bin/xmodmap /home/user/.Xmodmap). I can say that for 12.04 (and presumably 12.10) that these two alternatives definitely do work, as either way they are read after you log in with lightdm. (I changed Return to Right Shift, and the change only took effect after entering my password and logging in).

Please note: if you are on Xfce, it is noted on the official Xfce FAQ that you may have to create a startup item instead of using ~/.xinitrc, and that you might have to delay the execution so the xmodmap changes are not overwritten by setxkbmap. You can use a delay to achieve this in your startup entry:

/bin/bash -c "sleep 20; /usr/bin/xmodmap /home/$USER/.Xmodmap"

(For the startup entry it is necessary to specify absolute paths)

Each time setxkbmap is run to change keyboard layout, you will have to run xmodmap ~/.Xmodmap again in the terminal.

Creating ~/.xinitrc

Create a file in your home folder called .xinitrc with

touch .xinitrc

and place in it:

xmodmap ~/.Xmodmap

Your Xmodmap file should not have entries in the xmodmap -e " " style as that is used in the terminal for temporarily setting the values. It must have entries in this format:

keycode 65 = Tab
keycode 23 = Space

It is often confusing which of the various X files (such as .xprofile, .xinitrc, etc) are read at startup, but .xinitrc does seem to be still read under 12.04, whereas .Xmodmap or .xinputrc are not read by themselves.

5
  • 8
    Note that if you make your changes with xmodmap -e '..., you can retrieve the right format for xmodmap .Xmodmap with xmodmap -pke, which prints out the current mapping - though you'll want to filter this down to just the lines that apply to the change you made. Sep 26, 2013 at 14:08
  • 1
    This did not worked for me. I've created .Xmodmap and .xinitrc | Then I placed xmodmap ~/.Xmodmap into .xinitrc And then inside .Xmodmad I have keycode 166 = Prior keycode 167 = Next Aug 10, 2016 at 16:53
  • 2
    it's .xinitrc doesn't seem to be getting launched automatically anymore in Ubuntu 17.10. You'll have to autolaunch it with this command: /bin/bash -c "sleep 15 && /home/USERNAME/.xinitrc" Dec 15, 2017 at 16:13
  • On my Gentoo system, ${HOME}/.Xmodmap is read by /etc/X11/xinit/xinitrc, no need for ${HOME}/.xinitrc. This should then work in any X11-based graphical environment.
    – sphakka
    Aug 30, 2020 at 15:36
  • Doesn't work for me on 16.04 Sep 2, 2020 at 0:03
18

I'm using ElementaryOS (with its GNOME based window manager) and found a solution through using xdg autostart scripts. Many window managers are using xdg so I assume this approach also will work in other environments. At least it should work with GNOME.

xdg run scripts in ~/.config/autostart upon login in a X session. To load xmodmap config upon login, add the following script to ~/.config/autostart/xmodmap.desktop:

[Desktop Entry]
Name[en_US]=Xmodmap
Comment[en_US]=xmodmap ~/.Xmodmap
Exec=/usr/bin/xmodmap .Xmodmap
Icon=application-default-icon
X-GNOME-Autostart-enabled=true
Type=Application

Then logout and login again, and your Xmodmap configuration should've been loaded.

If it's not working, try to run xmodmap in terminal to see if it's xmodmap that complains:

$ xmodmap ~/.Xmodmap

If you don't get any error, run the following command to debug:

$ sudo cat /var/log/syslog | grep -B 5 -A 5 xmodmap
4
  • 1
    On Linux Mint 17 (based on: Ubuntu 14.04.5) the auto-start approach worked perfectly for me after using a ~/.xinitrc file failed. As hxpax pointed out, Mint users (probably most/all Debian derived Linuxes) can use a GUI dialog to add auto-start entries by way of Main Menu --> Preferences --> Startup Applications.
    – mattst
    Mar 9, 2018 at 20:32
  • 2
    Worked ubuntu 18.04
    – TooTone
    Sep 22, 2018 at 10:31
  • Worked on ubuntu 20.04
    – Hieu Pham
    Dec 20, 2020 at 11:33
  • Worked on mint 21.1 Jan 27, 2023 at 11:18
4

On Mint 17/18, I can achieve that bu put my scripts into the Startup Application, with 1 second delay.

As Mint 18 is derived from Ubuntu 1604, I think you can do the same, or install Startup Application managing panel first if it is not there.

Hope it helps.

4
  • +1 Works well. I needed no delay on Linux Mint 17.
    – mattst
    Mar 9, 2018 at 20:33
  • @mattst Yeah, delay is optional.
    – Galaxy
    Jul 3, 2018 at 7:27
  • I needed a delay of 5 seconds for this to work. I used the following startup shell script therefore: gist.github.com/ghagerer/58212241e37229f9d6fe3a133b34be97 Oct 4, 2018 at 7:58
  • I'd just like to add that it is important to use full path to your script, and not just~/.Xmodemap.
    – BanAnanas
    May 15, 2020 at 12:44
4

I don't have the unity interface in front of me just now, but try clicking the Applications button on the launcher, then type startup.

There should be an app called Startup Applications (or some such). Click it and add your xmodmap command (eg xmodmap /home/thiago/.Xmodmap).

It is important to use absolute path, not ~/Xmodmap.
If it still doesn't work, you can try adding a bit of delay as suggested by hxpax.

8
  • I tried that a while ago but it didn't work out for me. I'm on windows right now but I'll try again later and I report here if it works. thx Jul 24, 2011 at 4:05
  • 2
    @Thiago Moraes Does this basic command work (if not, post the error)? xmodmap .Xmodmap
    – djeikyb
    Jul 28, 2011 at 2:18
  • 1
    +1 this does work. To be more explicit I used the full path for .Xmodmap
    – pwned
    Nov 8, 2013 at 5:52
  • 4
    this does not work. I am using 16.04 Aug 10, 2016 at 18:04
  • 1
    @djeikyb thank you, I was using ~/ for the path to the config file. I used /home/$USER and it worked. thank again Aug 16, 2016 at 14:22
3

I wasn't having much joy with any of the suggestions above (the .bashrc option wasn't really viable as it runs xmodmap on every new terminal)

I touched a script called xmodstartup.sh in my home folder

  #!/bin/bash           
  sleep 1;               
  echo "running xmodmap" 
  xmodmap ~/.Xmodmap     

with it saved, I then did sudo chmod +x xmodstartup.sh

then I simply added the executable file to gnome's "startup application preferences" window. bish bosh, English layout y Español on altgr :)

1
  • The only solution that worked for me. It's essentially the same as @GOST suggested but it runs a script which runs the command instead of directly running command. I don't know why but only this actually works on my system, even without the sleep timer.
    – Dany
    Mar 24, 2021 at 8:39
2

For gnome3:

xinitrc starts with /etc/X11/xinit/xinitrc and contains only one command: . /etc/X11/Xsession This global Xsession file sets paths that are being executed:

    USERXSESSION=$HOME/.xsession
    USERXSESSIONRC=$HOME/.xsessionrc

I put echo $(date) >> ~/sesscheck in $USERXSESSIONRC to check if this file is being executed on gnome login. It works. However, if you put xmodmap ~/.Xmodmap instead of test file record, keys mapping stays default. It means that default xmodmap overrides settings when xinitrc already started.

As said above by @kontrollanten, the most reliable way is to create a .desktop file and put it into ~/.config/autostart directory. Desktop entry example, modifying keymap after Gnome user login:

[Desktop Entry]
Version=1.0
Type=Application
Encoding=UTF-8
Name=Correct keys layout
Exec=/usr/bin/xmodmap ~/.Xmodmap
Terminal=false
StartupNotify=false
Categories=Application;
X-GNOME-Autostart-enabled=true

In my case, I lost numpad functionality at all and needed to map numpad keycodes to exact digits. So, ~/.Xmodmap is:

keycode  87 = 1 1 1 1 1 1
keycode  83 = 4 4 4 4 4 4
keycode  79 = 7 7 7 7 7 7
keycode  80 = 8 8 8 8 8 8
keycode  84 = 5 5 5 5 5 5
keycode  88 = 2 2 2 2 2 2
keycode  81 = 9 9 9 9 9 9
keycode  89 = 3 3 3 3 3 3
keycode  85 = 6 6 6 6 6 6
keycode  90 = 0 0 0 0 0 0
keycode  86 = plus plus plus plus plus plus
keycode  82 = minus minus minus minus minus minus
keycode  91 = period period period period period period
0

Seems that even .config/autostart is a bit finicky. Jay had a good solution but I've realized you could put the commands in xmodmap.desktop while just making sure to sleep the 1 second without having to make the extra bash script.

Name[en_US]=Xmodmap
Comment[en_US]=xmodmap ~/.xmodmap
Exec=/bin/bash -c "sleep 1; /usr/bin/xmodmap .xmodmap"
Icon=application-default-icon
X-GNOME-Autostart-enabled=true
Type=Application```
-1

Putting xmodmap changes in ~/.bashrc or /etc/bash.bashrc doesn't break anything.

Only downside is that one has to open a terminal after each boot to get it activated.

1
  • 3
    I'm already doing that, but the problem is that at every terminal I open, this command gets executed. It's only a moment but it's a little annoying and I would prefer a real solution. thx anyway Jul 24, 2011 at 4:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .