Remapping keyboard keys to allow å, ä and ö
Motivation
I have an English / Hebrew keyboard, but occasionally I also want to use the Swedish letters å, ä and ö. So idea is to sacrifice three keys on the keyboard for this purpose.
But which ones? So I went for the keypad’s /, * and – keys. But hey, I use these normally every now and then.
So why not use these keys with Alt to produce the desired letters? Here’s a simple reason: I don’t know how to do that. What I managed to achieve with xmodmap isn’t sensitive to Alt. Only Shift.
And why not use the keys that are commonly used in Swedish keyboards? Because the relevant keys are used for colon and double quotes. These are useful in Swedish as well. This is normally solved by using the right-Alt button to select the Swedish letters. But as just mentioned, I didn’t find the way to use Alt buttons as a modifier.
And why don’t I just install the Swedish keyboard layout? I might do that later on, but right now I don’t use Swedish often enough to justify another language candidate. It makes language switching more cumbersome.
So my solution was to write simple bash scripts that turn the said keys into å, ä and ö, and another bash script that bring them back to their default use. I’m sure there’s a way to fix it nicely with the Alt key, but I won’t bother.
All here relates to Linux Mint 19 running Cinnamon.
Making changes
First thing first: Save the current setting, in case you mess up:
$ xmodmap -pke > default-mapping.txt
Now let’s look at the default situation. Start with the mapping of modifiers:
$ xmodmap 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)
To get the current keyboard mapping, try
$ xmodmap -pk | less $ xmodmap -pke | less
The output is a list of keycode commands. Let’s look at one row:
keycode 42 = g G hebrew_ayin G U05F1
The number is the code of the physical key 42 on the keyboard.
That is followed by a number of keysyms. The first is with no modifier pressed, the second with Shift, the third when Mode_switch is used, and the forth is Switch + Mode_switch.
In my case, Mode_switch is when the language is changed to Hebrew, which is why “hebrew_ayin” is listed.
The fifth code, U05F1, is a Unicode character U+05F1, a Hebrew ligature character (ױ). Not clear what that’s for.
According to the man page, there may be up to 8 keysyms, but most X servers rarely use more than four. However, looking at the output of “xmodmap -pke”, there are 10 keysyms allocated to the function keys (F1, F2, etc.). Once again, not clear what for.
If the number codes aren’t clear, use this command to obtain X events. The keycodes are printed out (among all the mumbo-jumbo, it says e.g. “keycode 82″)
$ xev
This utility opens a small windows and dumps all X events that it gets. So this small window must have focus so that the keyboard events are directed to it.
What do these keysyms mean?
I tried this on keycode 90, which is the keypad’s zero or Ins key. Its assignment is originally
keycode 90 = KP_Insert KP_0 KP_Insert KP_0
So I changed it with
$ xmodmap -e "keycode 90 = a b c d e f g h i j"
This command takes a couple of seconds to execute, presumably because the server generates a MappingNotify event on every client each time a keycode assignment is evaluated. So it’s really slow, but it works.
After this, pressing this character plainly now just printed out “a”. No I could test a whole lot of combinations to find out what each of these positions mean:
- No modifier.
- Shift
- Hebrew mode on
- Hebrew mode on + Shift
No surprise here. As for the rest of the keysyms, I didn’t manage to get any of the e-j letter to appear, no matter what combination I tried. So I guess they’re not relevant in my setting. The man page was correct: Only four of them are actually used.
By the way, when applying Caps Lock, I got the uppercase version of the same letters. It’s really twisted.
Reverting my change from above:
$ xmodmap -e "keycode 90 = KP_Insert KP_0 KP_Insert KP_0"
The scripts
To reiterate, the purpose is to turn the keypad’s /, *, – into å, ä and ö.
Their respective 106, 63 and 82 (that was pretty random, wasn’t it?), with the following defaults:
keycode 106 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab KP_Divide KP_Divide XF86Ungrab keycode 63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab KP_Multiply KP_Multiply XF86ClearGrab keycode 82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode KP_Subtract KP_Subtract XF86Prev_VMode
So this is the script to bring back the buttons to normal (which I named “kbnormal”):
#!/bin/bash echo "Changing the keymap to normal." echo "The display will now freeze for 7-8 seconds. Don't worry..." sleep 0.5 /usr/bin/xmodmap - <<EOF keycode 106 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab KP_Divide KP_Divide XF86Ungrab keycode 63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab KP_Multiply KP_Multiply XF86ClearGrab keycode 82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode KP_Subtract KP_Subtract XF86Prev_VMode EOF
And finally, this is the script that turns these buttons into å, ä and ö:
#!/bin/bash echo "Changing the keymap to swedish letters on numpad's /, *, -" echo "The display will now freeze for 7-8 seconds. Don't worry..." sleep 0.5 /usr/bin/xmodmap - <<EOF keycode 106 = aring Aring aring Aring keycode 63 = adiaeresis Adiaeresis adiaeresis Adiaeresis keycode 82 = odiaeresis Odiaeresis odiaeresis Odiaeresis EOF
The change is temporary, and that’s fine for my purposes. I know a lot of people have been struggling with making the changes permanent, and I have no idea how to do that, nor do I have any motivation to find out.
See the notification that the screen will freeze for a few seconds? It’s for real. The mouse pointer keeps running normally, but the desktop freezes completely for a few seconds, including the clock.
That rings an old bell. Like, a six years old bell. I’ve been wondering why moving the mouse pointer in and out from a VMWare window causes the entire screen to freeze for a minute. Maybe it has to do with keyboard mapping? It’s quite plausible that moving the mouse off the virtual machine’s window would require a different keymap. Haven’t investigated this further.