Keybinding in Groups for Linux

Ben Reaves
3 min readFeb 17, 2020

--

After months of working with xkb in Linux I feel like this is a big deal that does not get talked about much. When people think about rebinding keys they’re looking at xmodmap, autokey, xbindkeys, and other utilities, which all are good and have their purpose but the one area they tend to fall flat is how can you map two sets of keys to each other without creating an infinite loop?

As an example let’s say you want to map Control + Left to Alt + Left, but have Alt + Left map to Control + Left. How do you accomplish this with tools like autokey or xbindkey?

You don’t. Most, if not all 3rd party, solutions will create infinite loops.

How do you solve a problem like this? One of 2 ways, solve it by literally changing the scancode of the uvdev interface with your keyboard. There looks to be a wonderful tutorial over here. https://yulistic.gitlab.io/2017/12/linux-keymapping-with-udev-hwdb/

Another options is to learn how to work with xkb types, symbols and groups. This to me is the key element, because when you create groups you are able to specify and link the appropriate actions to be taken. Of course the xkb rabbit hole goes extremely deep and can support some crazy complicated configurations that I can’t even manage to cobble together myself, but the capabilities are there nonetheless and the idea of creating additional layers in conjuction with toggle keys or shift keys is intriguing.

Here’s an example of what a types and symbols file looks like where the Alt and Control key are aware of each other, so they do not step on each others foot.

# types file
default partial xkb_types "addmac_levels" {
type "ONE_LEVEL_CTRL" {
modifiers= Mod1+Control;
map[Mod1]= Level2;
map[Control]= Level3;
map[Mod1+Control]= Level3;
level_name[Level1]= "Base";
level_name[Level2]= "Alt";
level_name[Level3]= "With Control";
};
};

And the related symbols file

default partial xkb_symbols "mac_levelssym" {
// LEFT Ctrl and Alt Swap
replace key <LEFT> {
type[Group1]= "ONE_LEVEL_CTRL",
symbols[Group1]= [ Left, Left, NoSymbol ],
actions[Group1]= [ NoAction(), RedirectKey(key=<LEFT>,modifiers=Control,clearmods=Mod1), RedirectKey(key=<LEFT>,modifiers=Mod1,clearmods=Control)]
};
};

The key thing to note is that the number of levels in the types file goes up to 3, Base, Alt, Control. The symbols file follows that pattern under the symbols and actions groups, where there are 3 specified values inside of what appears to be an array of values.

To handle things appropriately sometimes a modifier or clearmods parameters needs to be provided. In this example the Control key + Left becomes Alt + Left and vice versa and yet there are no endless loops happening — because they are aware of each other from being in the same group.

This is a key distinction that allows for some very useful modifications that often trip me and others up while having used “simple” 3rd party tools. Simple is great until it isn’t sadly.

--

--

No responses yet