20

I created the following ~/.Xmodmap file as per this answer.

keysym Delete = Menu
keysym Menu = Delete

clear Lock
keycode 0x42 = Escape

In other words, swap Delete and Menu, and make Caps Lock an additional Escape.

The next time I logged in, Ubuntu asked me if I wanted to load ~/.Xmodmap as expected. I loaded it, but nothing happened (either then or on subsequent logins). If I manually run xmodmap ~/.Xmodmap, it works as expected.

I know that this worked early in the 10.10 beta, but it's failing on my fresh 10.10 install. I haven't tried in on anything earlier than 10.10. Any ideas?

Edit: I put some debugging statements in /etc/gdm/Xsession to make sure ~/.Xmodmap was loading, and everything magically started working. I didn't change anything except adding some echos, and it's still working now that I reverted my changes and restarted again. Strangest thing I ever saw.

One thing I realized is that the "remap Caps Lock to Escape" part of the Xmodmap was always working. It was just the Delete/Menu swap that failed. I'll leave this question open for now in case anyone else has the same problem, since I don't actually know why the problem stopped.

muru
  • 197,895
  • 55
  • 485
  • 740
Matthew
  • 3,094

7 Answers7

12

I know it's silly but as a workaround you could just autostart xmodmap ~/.Xmodmap.

Also you could check /etc/gdm/Xsession for the line usermodmap="$HOME/.Xmodmap" and if it isn't there just append it at the end of the file. If you're the only user of the system just put your changes into /etc/X11/Xmodmap.

turbo
  • 4,622
8

Late to the party, but this drove me nuts as well ; and, stubborn as I am, giving up was not an option.

Basically this is what I tried, (as my user, or root if necessary)

  • ~/.Xmodmap only
  • ~/.xsession, ~/.xsessionrc
  • ~/.gnomerc
  • ~/.xprofile
  • ~/.xinitrc
  • /etc/X11/Xsession.d/myscript
  • /usr/share/X11/xorg.conf.d/ (config files, didn't touch it)

(Actually, adding the xmodmap command to ~/.bashrc worked, but it requires to start a terminal each time after login)

A few years ago(?), xkb was chosen to deal with keys mapping and configuration (interfacing with X), but xmodmap might also request key related changes to X, after xkb did its work during the X session initialization.

The problem is when should these xmodmap settings happen?
It seems those above files are processed too early in the process, and either X was not ready to accept xmodmap changes, or xkb would overwrite them.

Note: I added some "tracking" to these files to ensure they were actually running at some time!

A solution that seems to work

I was not keen to add a .desktop file initially (a simple one line script had to be enough), but that works, so here it is.
The solution comes from How to remap or swap special keyboard keys in Linux? "solution 1"

Basically create ~/.config/autostart/my-xmodmap.desktop file, and put in it:

[Desktop Entry]
Name=MyXmodmap
Exec=/usr/bin/xmodmap /home/me/.Xmodmap
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true

replace me with your username (note that I didn't bother to try ~/ or $HOME that may work equally well in place of /home/me, and the full path of xmodmap is likely not necessary...), and add the exec bit

chmod +x ~/.config/autostart/my-xmodmap.desktop

The xmodmap commands have to be in a ~/.Xmodmap file in this case (or use the -e option, or choose another file name!). Log out and back in.

Note that you might create the starting program from "Startup Applications".

Another solution would be to forget xmodmap and learn how to configure xkb!

Edit (again)

Sometimes, maybe 25% of the logons, the xmodmap still seems not working - while the command is actually run (a tracker proves that). The only conclusion I might come to at this time is that the xkb process does run late in the logon process, and may end after the xmodmap has run. Looks like a race condition... So, finally, I changed the autostart desktop file exec line to

Exec=$HOME/bin/mystart &

(note the &) mystart is a script in a new directory bin I created that contains

#!/bin/bash    
sleep 5
/usr/bin/xmodmap /home/me/.Xmodmap &
date >> /tmp/xmodmap-has-run

and

chmod u+x ~/bin/mystart

The script sleeps 5 seconds before to run xmodmap, and tracks when it did run (in the file /tmp/xmodmap-has-run).

Hopefully that will be all!

Déjà vu
  • 969
4

Here is, perhaps a better answer then: http://cweiske.de/howto/xmodmap/ar01s06.html

You may have to tweak it a little bit to work for you but the instructions are all there.

  • 1
    This instructions are for KDE, but if I look at the Gnome equivalent (/etc/gdm/Xsession), the lines that link says to add are already in it. – Matthew Oct 15 '10 at 14:16
3

Unfortunately, this looks like a (very) long standing issue, and it is just because after Gnome 3.6, xmodmap support was dropped.

This is discussed in Remap keys on GNOME3.8 using xmodmap? and Bug 873656 - .Xmodmap file not loaded by Gnome 3.x .

The solution is to move to xkb. There is a bit of help from comment 29 in the second link.

Lorenz Keel
  • 8,905
3

Perhaps you have a syntax error in your ~/.Xmodmap file?

Try running:

$ xmodmap ~/.Xmodmap

That should fire an error if there are any.

gpmcadam
  • 189
1

I had the same weird problem, trying to start up my xmodmap while logging in my session (Ubuntu 13.04). I finally made it work with a .xinitrc file in my Home folder where I put my command, but with absolute paths to it, that is:

/usr/bin/xmodmap /home/MYNAME/.Xmodmap

Then I had to reboot (not just relog) so that it would be executed.

Lorenz Keel
  • 8,905
greguti
  • 495
  • 1
  • 4
  • 13
0

There are a few ways:

  1. Autostart xmodmap ~/.Xmodmap as explained here: https://askubuntu.com/a/749662

  2. Add it "properly" to the Xsession file (to know what Display Manager you are using you can do this: https://unix.stackexchange.com/a/20376/548454):

    • If you are using "GNOME Display Manager" (gdm) you can check /etc/gdm/Xsession for the line

      usermodmap="$HOME/.Xmodmap"
      

      and if it isn't there just append it at the end of the file.

    • If you are using "Simple Desktop Display Manager" (sddm) you can get this same functionality by checking /etc/sddm/Xsession for the block:

      usermodmap=$HOME/.Xmodmap
      sysmodmap=/etc/X11/xinit/.Xmodmap
      

      if [ -f "$usermodmap" ]; then xmodmap "$usermodmap" fi

      if [ -f $sysmodmap ]; then xmodmap $sysmodmap fi

      and if it isn't there just append it at the end of the file. (from: https://www.reddit.com/r/linuxquestions/comments/8e7em8/comment/dxtg314/)

  3. Directly edit /usr/share/X11/xkb/keycodes/evdev as explained here: https://askubuntu.com/a/1161870

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. – Community Apr 13 '23 at 16:00