Concepts
A key press goes through several stages before it becomes text. This page names each stage and the cl-xkbcommon objects that handle it.
physical key ──► keycode ──► keymap + keyboard state ──► keysym ──► compose ──► text
(integer) (layout, level, (integer) (dead keys,
modifiers) sequences)
Keycodes
A keycode identifies a physical key, regardless of what is printed on it. cl-xkbcommon takes xkb keycodes. On Linux an xkb keycode is the evdev code of the key plus 8:
| Source | What it gives | What to pass |
|---|---|---|
Wayland wl_keyboard.key |
evdev code | (evdev-keycode code): code + 8 |
| X11 key events | xkb keycode | as given |
evdev (/dev/input) |
evdev code | (evdev-keycode code): code + 8 |
Some useful xkb keycodes on a PC keyboard:
| Keycode | Key name | Key |
|---|---|---|
| 9 | ESC |
Escape |
| 21 | AE12 |
left of Backspace (= on US, dead acute on Swedish) |
| 24 | AD01 |
Q |
| 34 | AD11 |
right of P ([ on US, å on Swedish) |
| 36 | RTRN |
Return |
| 37 | LCTL |
left Control |
| 38 | AC01 |
A |
| 50 | LFSH |
left Shift |
| 64 | LALT |
left Alt |
| 66 | CAPS |
Caps Lock |
| 108 | RALT |
right Alt (AltGr on many layouts) |
| 133 | LWIN |
left Super ("Windows" key) |
Every key has a key name of up to four characters, such as AC01
(row C, column 1). Key names do not depend on the layout, so they are a
stable way to refer to a key's position. key-name and find-key convert
between keycodes and key names.
The type keycode is (unsigned-byte 32).
Keysyms
A keysym is the symbol a key produces: a, A, Return, F1,
Shift_L, dead_acute. The same key produces different keysyms depending
on the layout and the modifiers held: key 34 produces bracketleft on a US
layout and aring (å) on a Swedish one.
Keysyms are integers. Most keysyms have names, and many stand for a character. See Keysyms.
The type keysym is (unsigned-byte 32).
Text
Keysyms and text are related but not the same:
Returnis a keysym that types the character Return, butF1andShift_Ltype nothing.- A dead key such as
dead_acutetypes nothing itself. It changes the next key, so dead acute followed byetypesé. This is a compose sequence; see Compose and Dead Keys.
key-keysym gives the keysym, key-text the text without composing, and
key-press-text the text a key press types, compose sequences included.
Keymaps
A keymap describes a whole keyboard: for every key, what it produces in each layout and at each level, and which keys are modifiers. It is compiled from names, following the XKB RMLVO model:
| Name | Meaning | Examples |
|---|---|---|
| rules | which rule set maps the other names to keymap parts | "evdev" |
| model | the keyboard model | "pc105" |
| layout | the layout, or several separated by commas | "us", "se", "us,se" |
| variant | a variant of each layout | "dvorak", "nodeadkeys" |
| options | extra behaviour | "compose:ralt", "ctrl:nocaps" |
These are the names setxkbmap and desktop keyboard settings use. A keymap
can also be compiled from text, such as the text a Wayland compositor sends.
See Contexts and Keymaps.
Layouts and levels
A keymap may hold several layouts (XKB calls them groups), such as
US and Swedish. One is active at a time, and the keyboard state knows
which. Layouts are numbered from 0, in the order keymap-layouts returns
them.
Within a layout, each key has one or more levels. Level 1 is the plain
key, level 2 is usually Shift, and level 3 is usually AltGr (the
:level-3 modifier). On a Swedish layout, key 11 types 2, " with
Shift, and @ with AltGr.
cl-xkbcommon does not expose levels directly. The keyboard state picks the
level from the modifiers, and key-keysym and key-text return what that
level produces.
Modifiers
A modifier is a state that changes what keys produce, or that an application reads for shortcuts: Shift, Control, Alt, Super, Caps Lock and so on. A modifier can be
- depressed: held down, as Shift usually is;
- latched: active for the next key only, as with sticky keys;
- locked: active until it is pressed again, as Caps Lock is.
The modifier is active (in effect) if it is any of these.
cl-xkbcommon names the common modifiers with keywords:
| Keyword | Modifier |
|---|---|
:shift |
Shift |
:caps-lock |
Caps Lock |
:control |
Control |
:alt |
Alt |
:num-lock |
Num Lock |
:super |
Super, the "Windows" or "Command" key |
:level-3 |
AltGr, which selects level 3 |
:level-5 |
selects level 5, on some layouts |
:meta |
Meta |
:hyper |
Hyper |
:scroll-lock |
Scroll Lock |
The type modifier-keyword is these keywords, and active-modifiers
lists them in this order. A keymap may also have
modifiers that no keyword names. Any modifier can be named by its name in
the keymap, as a string, such as "Control" or "Mod3". Not every keymap
has every modifier: keymap-modifier-p says whether it does, and a keyword
the keymap lacks is simply never active.
Each modifier of a keymap has an index. Modifier n is bit n of a
modifier mask, the integer Wayland and X11 use to send modifier state.
keymap-modifiers lists the modifiers in index order.
Real and virtual modifiers
Underneath, X11 has eight real modifiers: Shift, Lock, Control and
Mod1 to Mod5. Alt, Super, Meta and the rest are virtual modifiers, which
a keymap maps onto real ones. Most keymaps map Alt and Meta both to Mod1, so
while Alt is held, Meta is in effect too, and modifier-active-p says so
for both.
active-modifiers lists each real mapping once: it leaves out a keyword
that sits on the same real modifiers as one before it in the table above.
Holding Alt gives (:alt), not (:alt :meta).
Consumed modifiers
When a modifier changes which keysym a key produces, the key consumes
it. Shift+A produces A, so the A key consumes Shift. This matters for
shortcuts: when Control and Shift are held and A is pressed, the keysym is
A and the user pressed Control+A. Shift is part of the A, not a
separate modifier of the shortcut. key-shortcut returns a key's keysym
with the modifiers it did not consume, and modifier-consumed-p asks about
one. See Recipes.
The objects
| Object | Made by | What it is | Shared between threads? |
|---|---|---|---|
context |
make-context |
where keymaps and compose tables are compiled; collects libxkbcommon's log | no |
keymap |
make-keymap, make-keymap-from-string |
what every key produces | yes, for reading |
keyboard-state |
make-keyboard-state |
one keyboard's modifiers and layout | no |
compose-table |
make-compose-table, make-compose-table-from-string |
a locale's compose sequences | no |
compose-state |
make-compose-state |
where a compose sequence has got to | no |
A typical program has one context and one keymap per keyboard, which it replaces when the keymap changes. It has one keyboard state per keyboard, one compose table, and one compose state per keyboard.