22. Januar 2022

Right control key on keyboard as i3 modifier in Ubuntu 20.04

If you ever wanted to use the right Ctrl button in Ubuntu 20.04 as an i3 modifier, and struggled with xmodmap, try editing the modifier mappings directly in /usr/share/X11/xkb/symbols/pc. It’s dirty, and may fail during software update─but meh until then it appears to work.

For some historical, complicated reasons, I am using the key labeled “Ctrl“─right of the space bar─as the modifier for i3. But on a different device and installation, I struggled heavily to do that via xmodmap changes applied when i3 reads the config. I found many reports on the internet where people having tried a similar thing and failed, without any obvious solution.

What I want is that the “right Ctrl” physical key on my keyboard is configured as i3 modifier.

xmodmap -pm initially shows:

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25), Control_R (0x69)
mod1        Alt_L (0x40),  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)

mod3 is unused, so I can use xmodmap to map mod3 to Control_R:

xmodmap -e "clear control"
xmodmap -e "add control = Control_L"
xmodmap -e "clear mod3"
xmodmap -e "add mod3 = Control_R"

xmodmap -pm now shows:

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

The only problem is that when I cannot get xmodmap changes to persist when I login (using GDM), and worse, the changes get lost when I e.g. switch my monitor between devices (and the keyboard gets unplugged and plugged i n again). These are the points where a lot of reports are found on the Internet. So the above path is not an attractive option.

What I ultimately resorted to: editing /usr/share/X11/xkb/symbols/pc. This might break during updates. But hey, I’ll have the recipe here on how to fix it.

The original excerpt from /usr/share/X11/xkb/symbols/pc showed Control_R mapped to the Control modifier:

// Beginning of modifier mappings.
modifier_map Shift  { Shift_L, Shift_R };
modifier_map Lock   { Caps_Lock };
modifier_map Control{ Control_L, Control_R };
modifier_map Mod2   { Num_Lock };
modifier_map Mod4   { Super_L, Super_R };

After my changes, the excerpt from /usr/share/X11/xkb/symbols/pc now shows Control_R mapped to Mod3:

// Beginning of modifier mappings.
modifier_map Shift  { Shift_L, Shift_R };
modifier_map Lock   { Caps_Lock };
modifier_map Control{ Control_L };
modifier_map Mod2   { Num_Lock };
modifier_map Mod3   { Control_R };
modifier_map Mod4   { Super_L, Super_R };

Now, the right Ctrl key is always mapped to Mod3, regardless of whether an i3 session is running or not. As long as the keyboard layout is built upon /usr/share/X11/xkb/symbols/pc.

This is what I have in my .config/i3/config, telling i3 to use Mod3 as identifier:

set $mod Mod3
exec --no-startup-id i3-sensible-terminal
exec --no-startup-id google-chrome

Finally, so that I can always fiddle with configuration if needed, I have the following in my .config/i3/config:

exec --no-startup-id i3-sensible-terminal
exec --no-startup-id google-chrome

This starts a browser and a terminal at the beginning of the i3 session. Things can go wrong after all.