Permanently remap a key to an other xubuntu

I have seen many questions about how to remap a key, but somehow my problem is that it never remaps permanently.

Here is my ~/bootstrap-custom.sh

#!/bin/sh
# remaps Caps Lock to Ctrl
/usr/bin/setxkbmap -option "ctrl:nocaps"

I have added source ~/boostrap-custom.sh to my startup applications.

The mappings work fine.

However:

  • The mapping doesn't load on startup, or is at least overwritten by something that runs after the startup applications.
  • everytime I plug in my keyboard, the mappings seems to be forgotten.

Any way to make the mapping permanent, but keeping the same method (xkbmap) ?


Solution 1:

This might be only a partial solution (I honestly don't know how it reacts to keyboard unplugging/replugging), but since you already have a script that does what you want, this might be close enough.

On startup, X11 executes several special programs, if they are present on the system. For our purposes, the most interesting is likely ~/.xsession, which is executed after you have logged in through a display manager, which is the normal setup for a graphical environment these days. (It used to be that you normally logged in to a shell and then ran the command startx to start X; if so, you used ~/.xinitrc for the same purpose.)

We can leverage this to execute commands virtually regardless of what display manager (gdm, gdm3, kdm, ...) and desktop environment (GNOME, Xfce, KDE, ...) you are using.

  1. Create a file named .xsession and place it in your home directory.
  2. Add the following to it:
    #!/bin/bash
    /usr/bin/setxkbmap -option "ctrl:nocaps"
  3. Save, and set the file to mode 755 (chmod 755 ~/.xsession)
  4. Log out and back on, or reboot

This should set your keyboard mapping on login. It should also execute late enough that setxkbmap actually works.

If for any reason this fails to work, log in to a text terminal (Ctrl+Alt+F2 for any F2 in [F1..F6] should be your friend) and delete the file by issuing the command rm ~/.xsession.

For reference, here is my ~/.xsession, which with mode 755 drops me into a Xfce4 session (this can serve as a "known good" example):

#!/bin/sh
xscreensaver &
exec xfce4-session

The exec directive at the end replaces the script itself with the given command. Anything that does not exit more or less immediately will need to be backgrounded, hence the &. (I expect setxkbmap to exit almost immediately, hence no backgrounding of it needed.)