Contexts and Keymaps
Contexts
A context is where keymaps and compose tables are compiled. It knows
where the system keeps keymap data, and it collects what libxkbcommon logs
while compiling.
(xkb:with-context (context)
...)
;; or, for a context that outlives one dynamic extent:
(defvar *context* (xkb:make-context))
...
(xkb:destroy-context *context*)
make-context takes three keyword arguments. The first two are true by
default:
| Argument | When true | When false |
|---|---|---|
:default-includes |
keymap data is found where the system keeps it, such as /usr/share/X11/xkb |
no include paths; only keymaps from text can be compiled |
:environment |
names left out of make-keymap come from XKB_DEFAULT_RULES, XKB_DEFAULT_MODEL, XKB_DEFAULT_LAYOUT, XKB_DEFAULT_VARIANT and XKB_DEFAULT_OPTIONS |
names left out are libxkbcommon's built-in defaults, which is repeatable |
Use :environment nil in tests, and wherever a keymap must not depend on
the user's environment.
The third, :log-limit, is the most log messages the context keeps for
take-log-messages, 100 by default. See
Errors and Logging.
One context is enough for a whole program. Destroying it does not destroy the keymaps and compose tables made in it.
Keymaps from layout names
make-keymap compiles a keymap from RMLVO names (see
Concepts):
(xkb:make-keymap context :layout "se")
(xkb:make-keymap context :layout "us" :variant "dvorak")
(xkb:make-keymap context :layout "us,se") ; two layouts
(xkb:make-keymap context :layout "us,se" :variant ",nodeadkeys")
(xkb:make-keymap context :layout "us" :options "ctrl:nocaps,compose:ralt")
(xkb:make-keymap context) ; all defaults
All the arguments are strings or nil. Where several layouts are given,
:variant lists one variant per layout, separated by commas. Names left out
are the defaults, as described above.
with-keymap takes the same arguments and destroys the keymap afterwards:
(xkb:with-keymap (keymap context :layout "se" :variant "nodeadkeys")
...)
If the names make no keymap, make-keymap signals an xkb-error, which
includes what libxkbcommon logged:
libxkbcommon could not compile a keymap for layout "nosuchlayout". libxkbcommon said:
error: [XKB-338] Couldn't find file "symbols/nosuchlayout" in include paths
...
To find the names available on a system, look in
/usr/share/X11/xkb/rules/evdev.lst, or run localectl list-x11-keymap-layouts.
Keymaps from text
make-keymap-from-string compiles a keymap from the XKB text format. A
Wayland compositor sends this text in wl_keyboard.keymap, and
keymap-string writes it:
(let* ((text (xkb:keymap-string keymap)) ; "xkb_keymap {\nxkb_keycodes ..."
(copy (xkb:make-keymap-from-string context text)))
...)
Use this to receive the keymap a compositor uses, to send a keymap somewhere else, or to save one to a file. The Recipes page shows the Wayland case.
Asking a keymap about itself
(xkb:with-context (context :environment nil)
(xkb:with-keymap (keymap context :layout "us,se")
(xkb:keymap-layouts keymap)
;; => ("English (US)" "Swedish")
(xkb:keymap-modifiers keymap)
;; => ("Shift" "Lock" "Control" "Mod1" "Mod2" "Mod3" "Mod4" "Mod5"
;; "NumLock" "Alt" "LevelThree" "Super" "LevelFive" "Meta" "Hyper" "ScrollLock")
(xkb:keymap-modifier-p keymap :super) ; => T
(xkb:keymap-modifier-p keymap "Mod3") ; => T
(xkb:keymap-keycode-range keymap) ; => 9, 709
(xkb:key-name keymap 38) ; => "AC01"
(xkb:find-key keymap "RTRN") ; => 36
(xkb:find-key keymap "NOPE") ; => NIL
(xkb:key-repeats-p keymap 38) ; => T, A repeats
(xkb:key-repeats-p keymap 50))) ; => NIL, Shift does not
| Function | Returns |
|---|---|
keymap-layouts |
the layout names, in index order |
keymap-modifiers |
the modifier names, in index order: modifier n is bit n of a modifier mask |
keymap-modifier-p |
whether the keymap has a modifier, given as a keyword or a name |
keymap-keycode-range |
two values: the least and the greatest keycode the keymap may use |
key-name |
the key name of a keycode, or nil |
find-key |
the keycode of a key name, or nil |
key-repeats-p |
whether a key should repeat while it is held |
keymap-string |
the keymap in the text format |
The modifier list depends on the keymap and on the libxkbcommon version.
Do not hard-code modifier indices. Find them with keymap-modifiers, or
name modifiers by keyword.
key-repeats-p only says whether a key repeats. Repeating it is the
application's job: see Recipes.
Changing keymaps
A keymap cannot be changed after it is compiled. When the layout changes, or a Wayland compositor sends a new keymap, compile a new keymap. Then make a new keyboard state for it, and destroy the old keymap and keyboard state.