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:
To output the current settings: setxkbmap -print
To dump the current XKB keyboard description to a file xkb.dump: xkbcomp $DISPLAY xkb.dump
In one's $HOME
, create a directory .xkb and 2 or 3 subdirectories:
keymap: this directory will contain a file with the keyboard settings. It may be based on the output of setxkbmap -print.
symbols: this directory will contain a file with the remapped keys. Examples can be found thanks to xkbcomp $DISPLAY xkb.dump (see the xkb_symbols section) or files from the /usr/share/X11/xkb/symbols directory (for instance, see files latin and pc).
Example: my ~/.xkb/symbols/local file.
types (optional): this directory can contain a file with new key types, if need be.
Example: my ~/.xkb/types/local file.
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.
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.
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.
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).
I had the following two files:
0x70035 86 # Left to z: 102nd (providing backslash bar) 0x70064 grave # Left to 1: grave notsign 0x70068 insert # F13
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).
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).
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.
The Keyboards category of the Arch Linux wiki has interesting information.