Custom Sway keyboard mapping
I thought that I had a problem: I’m an avid user of the EurKEYS keyboard layout and I wanted to type a character I (thought) I didn’t had available: §
. Even though it turned out it actually is available (AltGr+Shift+s
), it was a fun rabbit hole and I feel like it’s worth sharing, in case anyone wants to tweak the keyboard layout.
When you press a key on your keyboard, it sends a scancode to your computer. This scancode is a unique number that corresponds to that specific key. To find the scan code for a key, you can use e.g. extra/wev, and see that (on my machine) a
has the scan code 38, s
39, and so on:
[14: wl_keyboard] key: serial: 183354; time: 65458672; key: 38; state: 1 (pressed)
sym: a (97), utf8: ’a’
[14: wl_keyboard] key: serial: 183667; time: 65512523; key: 39; state: 1 (pressed)
sym: s (115), utf8: ’s’
There are many layouts, and their scancodes differ. wayland-book has more details, if you are interested in a deep-dive on that topic.
This scancode has to be mapped to a specific character. There are different ways how this mapping is done, the most common way is to use xkb, especially since this is shipped by default in many distros. In general, wayland is able to support different input methods, but the only defined one is xkb.
The X in XKB
“There is something odd though: XKB stands for the X keyboard extension, but Sway is on Wayland. Sway uses wlroots for Wayland building blocks. This further uses libxkbcommon to parse and handle keyboard layouts. This library implements the XKB specification and does not have any relation with the X server itself. The symbols in
/usr/share/X11/xkb
are distributed in the xkeyboard-config package.”© Sameer Puri, licensed under CC BY-SA 4.0
Step 1: Generate custom XKB mapping
Let’s create ~/.xkb/symbols/eurokeys-custom
with the following content:
default partial alphanumeric_keys
xkb_symbols "basic" {
include "eu"
name[Group1] = "Custom eurokey adaption";
key <AD10> { [ p, P, section] };
};
default
: specifies the variant of the layout.partial
: Rather than writing our own mapping table from scratch, we (only) want to extend an existing definition.alphanumeric_keys
: Indicates that this configuration specifically applies to the alphanumeric section of the keyboard (letters, numbers, and standard symbols), as opposed to function keys, keypad keys, or other special keys.xkb_symbols "basic"
: Definition block for the layout variant "basic".include "eu"
: This includes all definitions from this layout as a base. The new layout will inherit all key mappings from the European layout and then apply its own modifications on top. The file can be found in/usr/share/X11/xkb/symbols/eu
.name[Group1] = "Custom eurokey adaption";
: Name of our modification-
key <AD10> { [ p, P, section] };
: This is our actual replaced mapping. XKB does not directly use the scancode, but a more abstract naming scheme. TheAD10
part was found by looking into the original EurKEY layour (/usr/share/X11/xkb/symbols/eu
). Then, we can write up to 4 mappings:- No modifier: just pressing the key by itself (should produce a lowercase
p
in our case) Shift
-modifier: should produce an uppercaseP
AltGr
-modifier: should produce our desired§
AltGr
+Shift
-modifier: not set in our example
- No modifier: just pressing the key by itself (should produce a lowercase
Step 2: Use new XKB mapping
Depending on your desktop enviroment, set the new keyboard layout. In Sway, you can do this by setting the following code in .config/sway/config
:
input type:keyboard {
xkb_layout eurokeys-custom
}