Remapping keys with udev
Most of the time I am working on my desk, using my stationary keyboard. But once in a while, and especially during summer time, I like to take my work laptop and sit outside, enjoying the weather while doing some work.
In these moments, the internal keyboard of my Thinkpad P14s drove me nuts. Its Meta and left Alt keys are swapped compared to the keyboard on my desk, which often resulted in a small pause to think about which key to use if I wanted to change to another window, skip a single word during writing etc.
Luckily there is a pretty simple way to remap keys for distributions using udev
and systemd
(or at least that is the way I can confirm on Arch Linux).
Udev itself has a feature where it maintains a hardware database. It is possible to extend this database with custom configurations, like remapping specific keys on a keyboard.
In my case, that configuration file looks like this:
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*
KEYBOARD_KEY_38=leftmeta
KEYBOARD_KEY_db=leftalt
The first line is the hardware identifier. In this example it has a lot of wildcards, which are catching all keyboards having the same parts in their id. This particular line matches internal Thinkpad keyboards, which I shamelessly copy pasted from the corresponding Arch Linux Wiki article. To get the specific hardware identifier evemu-describe
(part of the evemu
package on Arch Linux) can be used.
The other two lines are defining what the key remapping looks like. On the left hand side of the =
, KEYBOARD_KEY_
is being used with the physical keys scancode being appended to it. On my keyboard, the scancodes (which are in hexadecimal format) are 38
for the physical left alt key, and db
for the physical left meta (windows) key. I used evtest
to read the scancodes, which are being displayed at the end of the first line after pressing a key, e.g. for left my left meta key:
type 4 (EV_MSC), code 4 (MSC_SCAN), value db
On the right hand side are the keycodes to what the physical keys should be mapped to. There is either a list on freedesktops website or (at least on Arch Linux) at /usr/include/linux/input-event-codes.h
(just copy the needed string without the prepended KEY_
part and change it to lowercase. The same string can also be read by using evtest
again and pressing the key that you want its value mapped to the other key. This will display the keycode string on the second line.
With all information gathered, I put the configuration into /usr/lib/udev/hwdb.d/10-my_remappings.hwdb
and updated udevs hardware database via systemd-hwdb update
and reloaded it via udevadm trigger
. Ta-da, the keys are remapped and ready to use!
As a final step I added a systemd replacement file so I do not have to manually update and load the hardware database each time. I did so by running systemctl edit systemd-hwdb-update.service
which creates the replacement unit and opens an editor to directly edit it. Inside the two specific comment sections which tell you what will be used and what not, I followed the Arch Linux Wiki page and added the described line to it, resulting in the following file content:
### Editing /etc/systemd/system/systemd-hwdb-update.service.d/override.conf
### Anything between here and the comment below will become the contents of the drop-in file
# ConditionNeedsUpdate=/etc
### Edits below this comment will be discarded
With that being set, my muscle memory should be pleased now not to rethink the key mappings everytime I am using my laptop keyboard – hooray!