Remap custom keyboard keys in Linux - Tutorial

Updated: February 24, 2021

Modern problems require modern solutions. I've recently got meself a new Linux test laptop, one IdeaPad 3, which I bought (unfortunately, due to market shortages) with the UK keyboard layout instead of the US layout. This means suboptimal physical key placement - even if you do use a different keyboard variant. Namely, the bar and backspace keys and such are placed all wrong, plus the Enter key is too small.

Moreover, this also means, muscle memory and all, you end up typing \ when you actually want to jump to a new line, and this can be quite annoying. So I thought, perhaps I can remap keyboard keys in a small way? But I didn't want to just remap the backspace key (bearing the UK tilde and hash symbols) to a "second" Enter, thus effectively making a larger Enter key, I still wanted to have the bar and backspace keys available. Hence a more complex exercise. Let me show you how you can this somewhat convoluted but super-nice setup.

Keyboard

Task at hand

So, let me clearly explain what I have in mind:

Therefore, I want to do the following:

Top view

Notice the "broken" Left Shift and Enter. Just because of inefficient physical layout.

My task requires two remaps: first the Enter, then the bar/backslash. Now, it is important to actually make the remaps this way, otherwise, if we remap bar/backslash first, then the key next to Enter won't have any mapping at all. Makes sense?

Tools of the trade: xev and xmodmap

We need two utilities that are part of the X bundle - I have no idea if and how one would do this on Wayland, but then I don't use Wayland in general, because it does not have functional parity with X, plus Xorg is the default session on most of the distros I actually use, like say Ubuntu or Kubuntu.

We will remap with xmodmap, but we need to "capture" the actual key symbols so we can do the remapping. To this end, run xev from a terminal window. The tool will open a little window in the corner of your screen, and it will start capturing inputs. If you press a key on the keyboard, you will see the following output in the terminal window - just an example:

KeyRelease event, serial 40, synthetic NO, window 0x5a00001,
root 0x6a9, subw 0x0, time 2784437, (1131,438), root:(1131,475),
state 0x0, keycode 94 (keysym 0x3c, less), same_screen YES,
XLookupString gives 1 bytes: (3c) "<"
XFilterEvent returns: False

Do this to grab the keysym for the bar/backspace and the arrow keys. Don't forget to grab the "second" key mapped (with Shift), so you can map both and not just one. Otherwise, we will have either only the bar or the backslash keys, but not both available.

Before we do that, let me show you how you actually remap keys. With xev running, press once the key you want to replace and the key with which you want to replace it. Then run xmodmap like this:

xmodmap -e "keysym HEX = NAME"

You will remap a key with the HEX value to do what the key with the NAME value should do. For example:

xmodmap -e "keysym 0x5c = Return"

This command maps the key symbol 0x5c (which corresponds to bar/backslash) to be Enter. So once this command completes, in my case, the physical UK key marked with the hash/tilde symbol, mapped to the bar/backspace function in the US layout, will now act as a second Enter key. Great.

But now, we also need to map the bar/backspace function.

Modifier

Indeed, to map both the standard and second (Shift) functionality for a key, we will need a modifier. You can check what existing modifiers exist with:

xmodmap -pm
xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3     
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

Now to remap a key with TWO functions, the syntax is as follows:

xmodmap -e "keysym HEX MOD = NAME1 NAME2"

In our example:

xmodmap -e "keysym 0x3c Shift_L = backslash bar"

We remap a key that corresponds to 0x3c - this is the key marked with bar/backspace in the physical UK keyboard, mapped to left and right arrow in the US keyboard - to actually function as bar/backspace. The modifier is the Left Shift key. So if you press the key on its own, you get backslash, if you use it with Left Shift, you get the bar (pipe) symbol. And we now have the layout we want.

Once again, remember that we aren't losing the arrow keys because they are already mapped to comma and period keys near the Right Shift key. Effectively the combo of physical UK and virtual US keyboard resulted in two pairs of arrows keys, so we're getting rid of one, and gaining an extra Enter.

Autostart script

Don't worry if you make a mistake. Reboot your system, and you'll go back to normal. Therefore, to make the custom remaps permanent, we will need to create an autostart script, which runs on every user login, and makes the changes we need.

There are many ways you can do this. I will show you how to create an autostart script for the Plasma desktop, although the principles are the same for pretty much every desktop out there. This is very similar to what I did with the Show desktop button in Gnome.

Open a Konsole window, go to ~/.config/autostart-scripts. Here, create a text file with the following content:

[Desktop Entry]
Name=Key swap
Exec=key-swap.sh
Terminal=false
Type=Application

You can use any name you want, and you can name the file however you like, but make sure it has a desktop suffix. In my example, I saved this as key-swap.desktop. Make this file executable:

chmod +x ~/.config/autostart-scripts/key-swap.desktop

Now, the Exec line in the desktop file references a script, which does not exist just yet. Normally, if you look at Exec lines for other desktop scripts (you can check Firefox or Chrome or whatever), you will notice a single command written. Since we need two xmodmap commands, the easiest solution is to put those inside a separate shell script, and then use the script as the Exec command.

In the autostart-scripts directory, create a file named key-swap.sh - also make it executable.

#!/bin/bash

xmodmap -e "keysym 0x5c = Return"
xmodmap -e "keysym 0x3c Shift_L = backslash bar"

exit 0

This is my example. You may have entirely different needs, and you might need only one xmodmap, or perhaps seven. Just for reference and completeness' sake, if you were to do a single xmodmap change, you could skip the shell script and just put it in the desktop file.

[Desktop Entry]
Name=Key swap single key
Exec=xmodmap -e "keysym 0x5c = Return"
Terminal=false
Type=Application

Through the Plasma Settings utility, you can indeed verify all is good:

Remap scripts

If you ever change your mind, you can disable or remove the scripts, use different keyboard mappings, and on next reboot, things will go back to the default state or the new custom state you desire. This way you have the necessary flexibility. While things are permanent so to speak, you can always change them.

Conclusion

There you go. This is my little tutorial that shows how I improved the default ergonomics of my Lenovo IdeaPad keyboard, making better use of its physical layout, and changing the key mappings to custom values. What makes the guide even more interesting is the fact I was using a US layout, so there's another little twist, but this will definitely be useful if you use other languages, too. Remember, the physical markings on the keys and actual function don't have anything in common. It's just a visual reference to make it easier for people to find the right symbols.

Hopefully, this was practical. I've noticed instant improvement in my typing speed, plus I'm making far fewer Enter backspace mistakes. My hands can continue working fast, without having to retrain themselves for yet another physical layout, which is so drastically different from most other laptops and/or keyboards I have. With xev and xmodmap, you should have some jolly good fun. If you have any similar, or perhaps arcane requests, do ping me, and I'll see what I can do. Happy typing.

Cheers.

You may also like: