Howto remap keyboard keys in Linux

Updated: May 07, 2024

Almost two years since I wrote a blog post, but learnt a lot in these past two years. I’ll be writing everything I can remember in the coming days, but first, I need to record down something I learnt recently.

I came across one challenge to generate a key press event where the key is not at all in the normal US keyboard. That special key (Hangul/English Toggle key) is only available in Korean Keyboard. So, here is how I did

We need to choose any one key available in the normal US keyboard and remap it to produce Hangul/English Toggle Key’s code. For my purpose I’m going to remap F7 key to produce Hangul/English keypress events. First, I need to know what F7 produces when it gets pressed. There is a tool called evtest which will show the code generated by physical keyboard

Event: time 1496043435.462606, type 4 (EV_MSC), code 4 (MSC_SCAN), value 41
Event: time 1496043435.462606, type 1 (EV_KEY), code 65 (KEY_F7), value 0

Here, the MSC_SCAN value of 41 (hexadecimal) is the code generated by the physical keyboard. Using this value. we need to create one file (/usr/lib/udev/hwdb.d/63-keyboard.hwdb) with the following content

keyboard:name:AT Translated Set 2 keyboard:dmi:*
 KEYBOARD_KEY_41=hangeul

Here, The first line starting with keyboard: indicates the name of the keyboard. There are lot of way to match the keyboard (see /usr/lib/udev/hwdb.d/60-keyboard.hwdb file for more details). The second line which starting with KEYBOARD_KEY_ should have one space before KEYBOARD. The hangeul string at the end of the second line is a suffixed lowercase substring of a macro defined in /usr/include/linux/input-event-codes.h file. You can use more than one KEYBOARD_KEY_= lines to remap the keys in your physical keyboard.

Once you create the 63-keyboard.hwdb file. Run the following command to update /etc/udev/hwdb.bin file which is used by udev

$ sudo udevadm hwdb --update

Once the hwdb.bin file updated, Either reboot your machine or trigger udev events for the particular keyboard (here, /dev/input/event1 may vary depend on your keyboard devfile mapping)

$ sudo udevadm trigger /dev/input/event1

Once you have the remapping, you can test it again with evtest.

Event: time 1496046275.166879, type 4 (EV_MSC), code 4 (MSC_SCAN), value 41
Event: time 1496046275.166879, type 1 (EV_KEY), code 122 (KEY_HANGUEL), value 0

In the above output, MSC_SCAN value 41 generates KEY_HANGUEL instead of KEY_F7.

Update (2018-02-06)

I recently have to remap Left Window Key to Right Window Key. So I created a new file in /etc/udev/hwdb.d/92-keyboard-override.hwdb and added following lines

# keyboard overrides
# laptop keyboard
libinput:keyboard:*
 KEYBOARD_KEY_db=rightmeta
 KEYBOARD_KEY_dd=rightmeta

# USB keyboard
evdev:*
 KEYBOARD_KEY_700e3=rightmeta

Here KEYBOARD_KEY_dd=rightmeta changes Menu key to Right Window Key, KEYBOARD_KEY_db=rightmeta and KEYBOARD_KEY_700e3=rightmeta both changes Left Window Key to Right Window Key but former is for laptop keyboard and later is for USB keyboard.