Once upon a time I nearly bricked my system by fucking around with my XKB layout file and not being able to get into a system shell – though I eventually did. That was a stressful few hours starting at 4am. My housemates had had a night out and I remember hearing them come home and I went into the kitchen and we were all about as done with the night as each other. Had some tasty biscuits though.
Anyway, lets learn how the whole thing worked!
It is unfortunately extremely complicated. XKB is extremely flexible, and made from a number of interfacing layers, all of which can be configured independently. You can see why custom firmware that handles all the weird stuff and just outputs the scancodes you want got popular.
There are two sets of files, the KcCGST files(??) and the RMLVO files(???). Okay then.
KcCGST
These are the Keycodes, Compat, Geometry, Symbols and Types files. Keycodes is scancodes from your keyboard serial line into internal (arbitrary) codenames, like AE01. These keycodes then get mapped into symbols like ! and 1, and that depends on the keys type which defines the combination of modifiers to produce a certain symbol e.g., shift and ctrl and so on.Geometry lets you draw a pretty picture of your keyboard if its defined, which it probably won’t be.
RMLVO
To actually make a layout, you shouldn’t touch the above (hahaha). You should use the RMLVO files, which are Rules, Models, Layouts, Variants and Options. “Layouts” is country (modulo global politics), Variants are variants of a county’s layout e.g., us = qwerty, fr = azerty, but us(dvorak) gives whatever dvorak variant of the us layout applies to those physical keys. Options let you remap caps lock to compose and so on.”Models” is clever magic thats mostly obsolete but that was responsible for making the keyboards look consistent to the OS regardless of weirdness the scancodes were coming out as.
Rules
Okay so this is the useful bit. These tell the tools how to go from
RMLVO to KcCGST. The rules are inside
/usr/share/X11/xkb/rules/evdev. I’m writing this in
vim so lets show off and use r!head ... to
look at the first bit.
// DO NOT EDIT THIS FILE - IT WAS AUTOGENERATED BY merge.py FROM rules/*.part
//
//
// Rules for resolving XKB components for use with XFree86
// Copyright 1996 by Joseph Moss
//
// 2002 Modifier: Ivan Pascal The XFree86 Project
//
// If you want non-latin layouts to implicitly include the en_US layout,
// then uncomment the following lines:
//! $nonlatin = af am ara bd bg bt by eg et ge gn gr id il in ir \
// jp jv kg kh kr kz la lk ma me mk mm mn mv my \
// pk rs ru sy th tj tz ua uz
// PC models
! $pcmodels = pc86 pc101 pc102 pc104 pc104alt pc105
// Jolla devices and keyboards
! $jollamodels = jollasbj
// Microsoft models (using MS geometry)
! $msmodels = microsoft microsoft4000 microsoft7000 microsoftpro microsoftprousb microsoftprose microsoftsurface
// Nokia devices and keyboards
! $nokiamodels = nokiasu8w nokiarx44 nokiarx51
Gosh. Jolla?? Nokia?? The whole thing is generated by merge.py?? Wow.
It turns out that when the standard linux keyboard drivers changed from the basic UNIX one to evdev, which uses different keycodes, everything broke and to fix this they just made this standard rules file and stopped letting users changed the rules. XKBRules is a noop. lmao.
But now its different! (As of mid 2020). Now the $XDG_CONFIG_HOME/xkb/ is in the lookup path for rules, so you can use that. That’s nice. Also the rules support an include statement and your custom rules better start off by including the standard evdev ones.
Then you can make some custom symbols files, label them, include them in your custom rules and baddabing baddaboom.
As of 2020, this doesn’t work in gnome-shell (I think it must do by now) but gosh. They’re working on all of this, including graphical editing. Yayyy!