Version française

User XKB Customization

Customization

I give here some information on XKB (X keyboard extension), in particular to modify the configuration as a simple user (without root access). Thus my XKB configuration completely replaced my old .xmodmaprc file (which didn't work correctly with the new kbd driver).

Two useful commands:

In one's $HOME, create a directory .xkb and 2 or 3 subdirectories:

To use these local settings, I have the following lines in my ~/.xsession script:

if [ -d $HOME/.xkb/keymap ]; then
  setxkbmap -types local -print | \
    sed -e '/xkb_symbols/s/"[[:space:]]/+local&/' > $HOME/.xkb/keymap/custom
  xkbcomp -w0 -I$HOME/.xkb -R$HOME/.xkb keymap/custom $DISPLAY
fi

This creates a ~/.xkb/keymap/custom file looking like:

xkb_keymap {
  xkb_keycodes  { include "evdev+aliases(qwerty)" };
  xkb_types     { include "local" };
  xkb_compat    { include "complete" };
  xkb_symbols   { include "pc+gb+inet(evdev)+level3(ralt_switch)+local" };
  xkb_geometry  { include "pc(pc105)" };
};

(some parts may change depending on the keyboard, except the local's) and selects these settings when the user X session is started.

References:

Note: This is here just keyboard configuration. Character set (encoding) configuration is another matter and depends on the locales. You can check what you get with the xev utility; look at the XLookupString line.

A Remark About Modifiers in the Default Configuration

I was quite surprised to see that in the default configuration, a modifier could modify another modifier:

key <RALT> { type= "TWO_LEVEL", symbols[Group1]= [ ISO_Level3_Shift, Multi_key ] };

so that Shift+AltGr gave Multi_key while AltGr+Shift gave Shift+LevelThree.

Restoring the XKB Settings After Suspend/Resume

Unfortunately, mainly for laptop users, XKB settings are lost after suspend/resume (this was also the case with xmodmap). There is a workaround: save them and restore them via pm-utils with a script in the /etc/pm/sleep.d directory, like my xkb-save-restore script, stored as /etc/pm/sleep.d/40xkb-save-restore for instance. You may also need to execute

xhost +si:localuser:root

in your ~/.xsession since the script is executed by root at suspend and resume time, and root's environment does not have the user's xauth information (MIT-MAGIC-COOKIE-1), which would allow him to have access to the keyboard configuration without a special authorization.

Note: The drawback (or advantage) of the above command is that root can permanently have access to the user's display. This is not really a security issue since root controls everything on the machine, and in particular, can have access to the magic cookie by various means. But the user should be careful not to start some X applications as root by mistake.

The only real issue is that when the settings are to be restored, though xkbcomp terminates with no errors, it sometimes has no effect.

Low-Level Remapping of Particular Keyboards

On some keyboards, keys are misplaced and for instance, one may want to swap keys. XKB must not be used for that, as the effect would be applied to every keyboard. One needs to modify the driver-level keymap file via udev.

For instance, for my Apple Aluminum USB keyboard (which I use with my laptop, so that it is a second keyboard), I have used the following solutions, depending on the udev version.

Note: The scancode of a physical key can be obtained with the evtest utility. It suffices to type the key and look at a line like:

Event: time 1452726874.519482, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70068

The scancode is here 70068 (this is a hexadecimal value).

With udev 175 to 204

I had the following two files:

/etc/udev/keymaps/apple-aluminum

0x70035 86 # Left to z: 102nd (providing backslash bar) 0x70064 grave # Left to 1: grave notsign 0x70068 insert # F13

/etc/udev/rules.d/98-apple-keyboard.rules

ACTION!="remove", SUBSYSTEMS=="usb", ENV{ID_VENDOR_ID}=="05ac", ENV{ID_MODEL_ID}=="0221", RUN+="keymap $name /etc/udev/keymaps/apple-aluminum"

Note: due to a bug in the keymap udev utility, I had to give the key code 86 instead of the key name 102nd (the fact that it starts with a digit confuses the keymap utility).

With udev 208 to 215

As of version 208, the keymap udev utility no longer exists. There is a new, simpler remapping system. See the /lib/udev/hwdb.d/60-keyboard.hwdb file for the documentation and examples. I initially had some problems due to multiple documentation issues, now fixed (and lack of error reporting from the utilities).

I had the following /etc/udev/hwdb.d/98-apple-keyboard.hwdb file:

keyboard:usb:v05ACp0221* KEYBOARD_KEY_70035=102nd # Left to z: backslash bar KEYBOARD_KEY_70064=grave # Left to 1: grave notsign KEYBOARD_KEY_70068=insert # F13: Insert

Warning! Each key mapping line must start with a single space. Errors are not signaled!

After creating or modifying this file, one needs to update the corresponding database with: udevadm hwdb --update

Then one needs to run udevadm trigger, or just reboot (probably cleaner).

With udev 220 and Later

The prefix has changed. The new /etc/udev/hwdb.d/98-apple-keyboard.hwdb file is:

evdev:input:b0003v05ACp0221* KEYBOARD_KEY_70035=102nd # Left to z: backslash bar KEYBOARD_KEY_70064=grave # Left to 1: grave notsign KEYBOARD_KEY_70068=insert # F13: Insert

Warning! Each key mapping line must start with a space (a single one for compatibility with old udev versions).

After creating or modifying this file, one needs to update the corresponding database with: udevadm hwdb --update

Then one needs to run udevadm trigger /dev/input/eventXX on the right event file, or just reboot (probably cleaner).

Note: Some mapping choices can sometimes be controlled by driver options. This is the case here with this particular Apple keyboard for the first two KEYBOARD_KEY_ lines. But anyway I still need such a file to get an Insert key.

See Also

The Keyboards category of the Arch Linux wiki has interesting information.



webmaster@vinc17.org