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
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!