1372 lines
47 KiB
Markdown
1372 lines
47 KiB
Markdown
# The XKB keymap text format, V1 {#keymap-text-format-v1}
|
||
|
||
<!--
|
||
NOTE:
|
||
• The Markdown supported in Doxygen is limited and buggy.
|
||
Current issues and solutions:
|
||
• In headers, only plain text is supported.
|
||
• Use the language tag “c” for block code to give them a nice (approximated)
|
||
syntax highlighting.
|
||
-->
|
||
|
||
This document describes the `XKB_KEYMAP_FORMAT_TEXT_V1` keymap format,
|
||
as implemented by libxkbcommon.
|
||
|
||
The standard database of keyboard configuration data is
|
||
[xkeyboard-config].
|
||
|
||
@note Due to the complexity of the format, this document is still is construction.
|
||
Some additional resources are:
|
||
|
||
@note
|
||
- [Ivan Pascal's XKB documentation][ivan-pascal]
|
||
- [An Unreliable Guide to XKB Configuration][unreliable-guide]
|
||
- [The X Keyboard Extension: Protocol Specification][XKB Protocol]
|
||
- [How to enhance XKB configuration][xkeyboard-config doc]
|
||
- [ArchWiki XKB page][arch-wiki]
|
||
|
||
[xkeyboard-config]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config
|
||
[ivan-pascal]: https://web.archive.org/web/20190724015820/http://pascal.tsu.ru/en/xkb/
|
||
[unreliable-guide]: https://www.charvolant.org/doug/xkb/html/index.html
|
||
[XKB Protocol]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html
|
||
[xkeyboard-config doc]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/docs/README.enhancing
|
||
[arch-wiki]: https://wiki.archlinux.org/index.php/X_keyboard_extension
|
||
|
||
|
||
@tableofcontents{html:2}
|
||
|
||
<!--
|
||
## Table of contents
|
||
|
||
1. [Terminology][terminology]
|
||
2. [Introduction to the XKB text format][introduction]
|
||
3. [The xkb_keymap block][xkb_keymap]
|
||
4. [The xkb_keycodes section][xkb_keycodes]
|
||
5. [The xkb_types section][xkb_types]
|
||
6. [The xkb_compat section][xkb_compat]
|
||
7. [The xkb_symbols section][xkb_symbols]
|
||
8. [Virtual modifier statements][virtual modifier statements]
|
||
9. [Modifiers bindings][modifiers bindings]
|
||
10. [Key actions][actions]
|
||
-->
|
||
|
||
[terminology]: @ref terminology
|
||
[introduction]: @ref introduction
|
||
[xkb_keymap]: @ref the-xkb_keymap-block
|
||
[xkb_keycodes]: @ref the-xkb_keycodes-section
|
||
[xkb_types]: @ref the-xkb_types-section
|
||
[xkb_compat]: @ref the-xkb_compat-section
|
||
[xkb_symbols]: @ref the-xkb_symbols-section
|
||
[virtual modifier statements]:@ref virtual-modifier-statements
|
||
[modifiers bindings]: @ref modifiers-bindings
|
||
[actions]: @ref key-actions
|
||
|
||
## Terminology {#terminology}
|
||
|
||
<dl>
|
||
<dt><a name="keycode-def">Keycode</a><dt>
|
||
<dd>
|
||
Code that identifies a physical key on a keyboard.
|
||
|
||
- _Raw_ keycodes are the numeric identifiers used as input in XKB.
|
||
They are the result of the low-level processing of the data that
|
||
keyboards send to a computer. For instance `36` may represent
|
||
the return key.
|
||
- _XKB_ keycodes are _symbolic_ names assigned to raw keycodes in
|
||
order to facilitate their mapping to symbols. For instance the
|
||
keycode for the return key is the abbreviation `RTRN`.
|
||
|
||
See [xkb_keycodes] for further details.
|
||
</dd>
|
||
<dt><a name="keysym-def">Symbols</a></dt>
|
||
<dd>
|
||
A _keysym_ (short for “key symbol”) is a numeric encoding of a
|
||
symbol on the cap of a key.
|
||
|
||
They have a canonical name for convenience. It can be:
|
||
|
||
- A _character:_ e.g. `a` and `A` for Latin scripts,
|
||
`alpha` “α” and `ALPHA` “Α” for Greek, etc.
|
||
- A _dead key:_ e.g. `dead_grave` and `dead_diaeresis`, corresponding
|
||
respectively to the [grave accent](https://en.wikipedia.org/wiki/Grave_accent)
|
||
and the [diaeresis](https://en.wikipedia.org/wiki/Diaeresis_%28diacritic%29)
|
||
diacritics.
|
||
|
||
A [dead key](https://en.wikipedia.org/wiki/Dead_key) is a special kind of key
|
||
that does not generate a character by itself, but modifies the character
|
||
generated by the key struck(s) immediately after.
|
||
- A <em>[modifier]:</em> e.g. `Shift_L`, `Control_R`, `Caps_Lock`.
|
||
See hereinafter.
|
||
- A _system action:_ e.g. the arrow `Left`, `Pause`, `Escape`, `F1`.
|
||
|
||
The complete list of keysyms is defined in `xkbcommon/xkbcommon-keysyms.h`.
|
||
|
||
See [xkb_symbols] for further details on binding keysyms to keycodes.
|
||
</dd>
|
||
<dt><a name="modifier-def">Modifier</a></dt>
|
||
<dd>
|
||
A _modifier key_ is a key that modifies the effect of other keys:
|
||
e.g. Shift, Control, Caps Lock, etc.
|
||
|
||
The state of a modifier key (active/inactive) is encoded as a
|
||
_modifier index_ (or modifier bit or simply modifier) and has
|
||
an associated _unique name_.
|
||
|
||
For historical reasons, modifiers are divided in two categories:
|
||
|
||
<dl>
|
||
<dt><a name="real-modifier-def">Real modifiers</a></dt>
|
||
<dd>
|
||
They are the 8 _predefined_ (AKA core, X11) modifiers
|
||
(see [usual modifiers] hereinafter).
|
||
|
||
Real modifiers ensure backward compatibility: indeed
|
||
they are the actual bits used to compute the [levels][level]
|
||
and are communicated via the API of xkbcommon.
|
||
|
||
Some are generic modifiers (`Mod[1-5]`) that do not have a
|
||
conventional interpretation and are the motivation of the
|
||
introduction of [virtual modifiers].
|
||
</dd>
|
||
<dt><a name="virtual-modifier-def">Virtual modifiers</a>
|
||
<dd>
|
||
They are the modifiers that are _not_ predefined.
|
||
</dd>
|
||
</dl>
|
||
|
||
Each modifier defines a _mapping_ to one or multiple
|
||
_real_ modifier. Real modifiers map to themselves.
|
||
|
||
The following table lists the
|
||
<a name="usual-modifiers">usual modifiers</a>
|
||
present in the [standard keyboard configuration][xkeyboard-config].
|
||
Note that this is provided for information only, as it may change
|
||
depending on the user configuration.
|
||
|
||
| Modifier | Type | Usual mapping | Comment |
|
||
| ------------ | ------- | ------------- | --------------------------- |
|
||
| `Shift` | Real | `Shift` | The usual [Shift] |
|
||
| `Lock` | Real | `Lock` | The usual [Caps Lock][Lock] |
|
||
| `Control` | Real | `Control` | The usual [Control] |
|
||
| `Mod1` | Real | `Mod1` | Not conventional |
|
||
| `Mod2` | Real | `Mod2` | Not conventional |
|
||
| `Mod3` | Real | `Mod3` | Not conventional |
|
||
| `Mod4` | Real | `Mod4` | Not conventional |
|
||
| `Mod5` | Real | `Mod5` | Not conventional |
|
||
| `Alt` | Virtual | `Mod1` | The usual [Alt] |
|
||
| `Meta` | Virtual | `Mod1` or `Mod4` | The legacy [Meta] key |
|
||
| `NumLock` | Virtual | `Mod2` | The usual [NumLock] |
|
||
| `Super` | Virtual | `Mod4` | The usual [Super]/GUI |
|
||
| `LevelThree` | Virtual | `Mod3` | [ISO][ISO9995] level 3, aka [AltGr] |
|
||
| `LevelFive` | Virtual | `Mod5` | [ISO][ISO9995] level 5 |
|
||
|
||
[usual modifiers]: @ref usual-modifiers
|
||
[Shift]: https://en.wikipedia.org/wiki/Control_key
|
||
[Lock]: https://en.wikipedia.org/wiki/Caps_Lock
|
||
[Control]: https://en.wikipedia.org/wiki/Control_key
|
||
[Alt]: https://en.wikipedia.org/wiki/Alt_key
|
||
[AltGr]: https://en.wikipedia.org/wiki/AltGr_key
|
||
[NumLock]: https://en.wikipedia.org/wiki/Num_Lock
|
||
[Meta]: https://en.wikipedia.org/wiki/Meta_key
|
||
[Super]: https://en.wikipedia.org/wiki/Super_key_(keyboard_button)
|
||
|
||
A modifier key can report its state in one of the following 3 ways:
|
||
|
||
<dl>
|
||
<dt><a name="depressed-mod-def">Depressed</a></dt>
|
||
<dd>Active while depressed; e.g. the usual Shift.</dd>
|
||
<dt><a name="latched-mod-def">Latched</a></dt>
|
||
<dd>
|
||
Activated when pressed and deactivated after the next
|
||
non-modifier key press.
|
||
</dd>
|
||
<dt><a name="locked-mod-def">Locked</a></dt>
|
||
<dd>
|
||
Activated when pressed and deactivated when pressed again;
|
||
e.g. the usual Caps Lock.
|
||
</dd>
|
||
</dl>
|
||
|
||
See [modifiers bindings] for further details.
|
||
</dd>
|
||
|
||
[depressed]: @ref depressed-mod-def
|
||
[latched]: @ref latched-mod-def
|
||
[locked]: @ref locked-mod-def
|
||
|
||
<dt><a name="level-def">Shift Level</a></dt>
|
||
<dd>
|
||
A key may produce different
|
||
results depending of the active modifiers: e.g. for a Latin script,
|
||
pressing the key A produces “a” and holding Shift while pressing A
|
||
produces “A”.
|
||
|
||
This various results are organized in an ordered list; the _index_
|
||
of each entry is called a <a name="level-index-def">shift level</a>
|
||
or simply level. By convention the lowest level is the result when
|
||
no modifier is active.
|
||
Example for the key `A` on latin script keyboard:
|
||
|
||
| Level | Description | Keysym | Active key modifiers |
|
||
|-------|--------------------------------|--------|----------------------|
|
||
| 1 | Lower case letters | `a` | None |
|
||
| 2 | Upper case letters. | `A` | `Shift` |
|
||
| 3 | Alternative lower case letters | `ae` | `AltGr` |
|
||
| 4 | Alternative upper case letters | `AE` | `Shift` + `AltGr` |
|
||
|
||
A key shift level is the logical _state_ of a key corresponding to
|
||
the current shift level it used.
|
||
|
||
Key shift levels are derived from the modifiers states, but not
|
||
necessarily in the same way for all keys. For example, for Latin
|
||
script the Caps Lock modifier selects the level 2 for alphabetic
|
||
keys such as `A` but has no effect on a numeric key.
|
||
|
||
There are groups of keys with the same characteristics: letters,
|
||
punctuation, numeric keypad, etc. The meaning of their levels is
|
||
identical and thus can be shared: this generalization is called
|
||
a _key type_ (see hereinafter).
|
||
</dd>
|
||
<dt><a name="key-type-def">Key type</a></dt>
|
||
<dd>
|
||
A key type defines the levels available for a key and
|
||
how to derive the active level from the modifiers states. Examples:
|
||
- `ONE_LEVEL`: the key has only one level, i.e. it is not affected
|
||
by any modifiers. Example: the modifiers themselves.
|
||
- `TWO_LEVEL`: the key has two levels:
|
||
- Level 1: default level, active when the `Shift` modifier is _not_ active.
|
||
- Level 2: level activated with the `Shift` modifier.
|
||
- `FOUR_LEVEL`: see the example in the previous section.
|
||
|
||
See [xkb_types] for further details.
|
||
</dd>
|
||
<dt><a name="layout-def">Layout</a></dt>
|
||
<dd>
|
||
A mapping of keycodes to symbols, actions and key types.
|
||
|
||
A user who deals with multiple languages may need two or more
|
||
different layouts: e.g. a layout for Arabic and another one for
|
||
English. In this context, layouts are called _groups_ in XKB,
|
||
as defined in the [standard ISO/IEC 9995][ISO9995].
|
||
|
||
Layouts are ordered and identified by their index. Example:
|
||
|
||
- Layout 1: Arabic
|
||
- Layout 2: English
|
||
|
||
</dd>
|
||
<dt><a name="key-action-def">Key Action</a></dt>
|
||
<dd>
|
||
In XKB world, a key action defines the effect a key
|
||
has on the state of the keyboard or the state of the display server.
|
||
Examples:
|
||
|
||
- Change the state of a modifier.
|
||
- Change the active group.
|
||
- Move the mouse pointer.
|
||
|
||
See the section “[Key actions][actions]” for further details.
|
||
</dd>
|
||
<dt><a name="indicator-def">Indicator</a></dt>
|
||
<dd>
|
||
A keyboard indicator is a mean to report a specific aspect of the
|
||
keyboard state.
|
||
|
||
<dl>
|
||
<dt><em>Physical</em> indicator</dt>
|
||
<dd>
|
||
Typically a labelled LED on the keyboard, e.g. “Caps Lock” and
|
||
“Num Lock”.
|
||
</dd>
|
||
<dt><em>Logical</em> indicator</dt>
|
||
<dd>
|
||
A customizable derived state of the keyboard.
|
||
Its changes creates events that can be monitored.
|
||
|
||
There are two categories:
|
||
|
||
- _Real_ indicators are those associated to a physical indicator.
|
||
For example, the “Caps Lock” logical modifier controls the
|
||
corresponding physical LED.
|
||
|
||
Because indicators are customizable, if one misses a “Num Lock”
|
||
LED, one could define instead the “Caps Lock” _indicator_ to
|
||
activate its LED when the “Num Lock” _modifier_ is active.
|
||
- _Virtual_ indicators are not associated to a physical indicator.
|
||
Their effect is only visible for programs monitoring them.
|
||
|
||
Note that the meanings of _real_ and _virtual_ is slightly
|
||
different than the one used for [modifier].
|
||
</dd>
|
||
</dl>
|
||
|
||
See: <code>[xkb_keycodes][indicator name]</code> to define indicators and
|
||
<code>[xkb_compat][indicator effect]</code> to define their effects.
|
||
</dd>
|
||
<dt><a name="keymap-def">Keymap</a></dt>
|
||
<dd>
|
||
The _complete_ definition of the
|
||
mapping of raw keycodes to symbols and actions.
|
||
It fully defines the behavior of a keyboard.
|
||
|
||
See [xkb_keymap] for further details.
|
||
</dd>
|
||
</dl>
|
||
|
||
[keycode]: @ref keycode-def
|
||
[keysym]: @ref keysym-def
|
||
[keysyms]: @ref keysym-def
|
||
[modifier]: @ref modifier-def
|
||
[modifiers]: @ref modifier-def
|
||
[real modifier]: @ref real-modifier-def
|
||
[real modifiers]: @ref real-modifier-def
|
||
[virtual modifier]: @ref virtual-modifier-def
|
||
[virtual modifiers]: @ref virtual-modifier-def
|
||
[level]: @ref level-def
|
||
[shift level]: @ref level-def
|
||
[level index]: @ref level-index-def
|
||
[key type]: @ref key-type-def
|
||
[key types]: @ref key-type-def
|
||
[layout]: @ref layout-def
|
||
[action]: @ref key-action-def
|
||
[indicator]: @ref indicator-def
|
||
[keymap]: @ref keymap-def
|
||
[ISO9995]: https://en.wikipedia.org/wiki/ISO/IEC_9995
|
||
|
||
|
||
## Introduction to the XKB text format {#introduction}
|
||
|
||
The XKB text format uses a syntax similar to the [C programming language][C].
|
||
|
||
@todo general comment on syntax: section, values, etc.
|
||
|
||
@todo the import mechanism
|
||
|
||
@todo recommended ways to feed xkbcommon
|
||
|
||
[C]: https://en.wikipedia.org/wiki/C_(programming_language)#Syntax
|
||
|
||
### Keywords
|
||
|
||
@todo keywords, other settings such as “SetMods”
|
||
|
||
<!--
|
||
TODO: SetMods is not a keyword, but how call it for using-facing doc?
|
||
|
||
There are many keywords
|
||
|
||
The key words are _case-insensitive_, e.g. the following strings denote
|
||
the same key word: `SETMODS`, `SetMods`, `setMods` and `setmods`.
|
||
-->
|
||
|
||
### Literals
|
||
|
||
<dl>
|
||
<dt>String literal</dt>
|
||
<dd>
|
||
A string is surrounded by double quotes: “<code>"</code>”.
|
||
The following _escape sequences_ are supported:
|
||
|
||
| Escape sequence | Meaning |
|
||
| ------------------ | ------------------------------------------------------- |
|
||
| `\\` | Backslash “`\`” |
|
||
| `\b` | Backspace |
|
||
| `\e` | Escape |
|
||
| `\f` | Form feed |
|
||
| `\n` | Line feed (newline) |
|
||
| `\r` | Carriage return |
|
||
| `\t` | Horizontal tabulation |
|
||
| `\v` | Vertical tabulation |
|
||
| `\` + octal number | Corresponding ASCII character: `\0` → NULL, `\42` → `"` |
|
||
|
||
@note The string _encoding_ is unspecified and not validated, but for best
|
||
results, stick to ASCII.
|
||
|
||
<!-- TODO: check UTF-8 encoding result -->
|
||
|
||
</dd>
|
||
<dt>Number literal</dt>
|
||
<dd>
|
||
A number can be written in three forms:
|
||
|
||
- _decimal integer:_ `1`, `123`, etc.
|
||
- _decimal floating-point number:_ `1.23`, etc.
|
||
- _hexadecimal integer:_ prefixed with `0x`: `0x123`, `0xff`, `0xAB`, etc.
|
||
</dd>
|
||
</dl>
|
||
|
||
|
||
## The “xkb_keymap” block {#the-xkb_keymap-block}
|
||
|
||
A <strong>[keymap]</strong> consists of a single top-level `xkb_keymap`
|
||
block, under which are nested the following sections:
|
||
|
||
<dl>
|
||
<dt><code>[xkb_keycodes]</code></dt>
|
||
<dd>
|
||
A translation of the hardware/evdev scancodes from the keyboard into
|
||
XKB symbolic keycodes.
|
||
</dd>
|
||
<dt><code>[xkb_types]</code></dt>
|
||
<dd>
|
||
A specification of the modifier mask, target level and preserved
|
||
modifiers various modifiers combination produce.
|
||
</dd>
|
||
<dt><code>[xkb_compat]</code></dt>
|
||
<dd>
|
||
A specification of what actions various special-purpose keys produce.
|
||
</dd>
|
||
<dt><code>[xkb_symbols]</code></dt>
|
||
<dd>
|
||
A translation of symbolic key codes into actual symbols and actions.
|
||
</dd>
|
||
</dl>
|
||
|
||
Overview of a keymap file:
|
||
|
||
```c
|
||
xkb_keymap {
|
||
xkb_keycodes "XXX" {
|
||
// ...
|
||
}
|
||
xkb_types "XXX" {
|
||
// ...
|
||
};
|
||
xkb_compatibility "XXX" {
|
||
// ...
|
||
};
|
||
xkb_symbols "XXX" {
|
||
// ...
|
||
};
|
||
};
|
||
```
|
||
|
||
## The “xkb_keycodes” section {#the-xkb_keycodes-section}
|
||
|
||
This is the simplest section type, and is the first one to be
|
||
compiled. The purpose of this is mostly to map between the
|
||
hardware/evdev scancodes and XKB [keycodes]. Each key is given a name
|
||
by which it can be referred to later, e.g. in the symbols section.
|
||
|
||
### Keycode statements
|
||
|
||
Statements of the form:
|
||
|
||
<TLDE> = 49;
|
||
<AE01> = 10;
|
||
|
||
The above would let 49 and 10 be valid keycodes in the keymap, and
|
||
assign them the names `TLDE` and `AE01` respectively. The format
|
||
`<WXYZ>` is always used to refer to a key by name.
|
||
|
||
The naming convention `<AE01>` is based on the
|
||
[standard ISO/IEC 9995-1][ISO9995-1]. It denotes the position of the
|
||
key in the keyboard grid. It means: the main alphanumeric section
|
||
(`A`), row `E` and column `01`.
|
||
|
||
The following figure illustrates the grid on a staggered standard
|
||
US QWERTY keyboard. `<AE01>` corresponds to the key `1`.
|
||
|
||
```
|
||
\ 99 \ 00 \ 01 \ 02 \ 03 \ 04 \ 05…
|
||
\ \ \ \ \ \ \
|
||
-----------------------------------------
|
||
E \ \ ^ \ 1 \ 2 \ 3 \ 4 \ 5…
|
||
------------------------------------------
|
||
D \ Tab \ Q \ W \ E \ R \ T…
|
||
-------------------------------------------
|
||
C \Caps \ A \ S \ D \ F \ G…
|
||
--------------------------------------------
|
||
B \Shift \ Z \ X \ C \ V \ B…
|
||
---------------------------------------------
|
||
A \Ctrl\GUI \Alt \Space…
|
||
----------------------------------------------
|
||
```
|
||
|
||
[ISO9995-1]: https://en.wikipedia.org/wiki/ISO/IEC_9995#ISO/IEC_9995-1
|
||
|
||
In the common case this just maps to the evdev scancodes from
|
||
`/usr/include/linux/input.h`, e.g. the following definitions:
|
||
|
||
#define KEY_GRAVE 41
|
||
#define KEY_1 2
|
||
|
||
correspond to the ones above. Similar definitions appear in the
|
||
xf86-input-keyboard driver. Note that in all current keymaps there's a
|
||
constant offset of 8 (for historical reasons).
|
||
|
||
Note that contrary to xkbcommon, the X11 protocol supports keycodes
|
||
only up to `255`. Therefore, when interfacing with X11, keymaps and applications
|
||
using keycodes beyond `255` should expect warnings.
|
||
|
||
If there's a conflict, like the same name given to different keycodes,
|
||
or same keycode given different names, it is resolved according to the
|
||
merge mode which applies to the definitions.
|
||
|
||
### Alias statements
|
||
|
||
Statements of the form:
|
||
|
||
alias <MENU> = <COMP>;
|
||
|
||
Allows to refer to a previously defined key (here `<COMP>`) by another
|
||
name (here `<MENU>`). Conflicts are handled similarly to keycode
|
||
statements.
|
||
|
||
### LED name statements {#indicator-name}
|
||
|
||
[indicator name]: @ref indicator-name
|
||
|
||
Statements of the form:
|
||
|
||
indicator 1 = "Caps Lock";
|
||
indicator 2 = "Num Lock";
|
||
indicator 3 = "Scroll Lock";
|
||
|
||
Assigns a name to the keyboard LED (AKA [indicator]) with the given
|
||
index. The LED may be referred by this name later in the compat
|
||
section and by the user.
|
||
|
||
|
||
## The “xkb_types” section {#the-xkb_types-section}
|
||
|
||
This section is the second to be processed, after `xkb_keycodes`.
|
||
However, it is completely independent and could have been the first to
|
||
be processed (it does not refer to specific keys as specified in the
|
||
`xkb_keycodes` section).
|
||
|
||
This section defines [key types], which, given a key and a keyboard
|
||
state (i.e. modifier state and group), determine the [shift level] to
|
||
be used in translating the key to [keysyms]. These types are assigned to
|
||
each group in each key, in the `xkb_symbols` section.
|
||
|
||
Key types are called this way because, in a way, they really describe
|
||
the "type" of the key (or more correctly, a specific group of the
|
||
key). For example, an ordinary keymap will provide a type called
|
||
`KEYPAD`, which consists of two levels, with the second level being
|
||
chosen according to the state of the Num Lock (or Shift) modifiers.
|
||
Another example is a type called `ONE_LEVEL`, which is usually
|
||
assigned to keys such as Escape; these have just one level and are not
|
||
affected by the modifier state. Yet more common examples are
|
||
`TWO_LEVEL` (with Shift choosing the second level), `ALPHABETIC`
|
||
(where Caps Lock may also choose the second level), etc.
|
||
|
||
### Type definitions
|
||
|
||
Statements of the form:
|
||
|
||
type "FOUR_LEVEL" { ... }
|
||
|
||
The above would create a new type named `FOUR_LEVEL`.
|
||
The body of the definition may include statements of the following
|
||
forms:
|
||
|
||
#### “level_name” statements
|
||
|
||
level_name[Level1] = "Base";
|
||
|
||
Mandatory for each level in the type.
|
||
|
||
Gives each level in this type a descriptive name. It isn't used
|
||
for anything.
|
||
|
||
Note: A level may be specified as Level\[1-8\] or just a number (can
|
||
be more than 8).
|
||
|
||
#### “modifiers” statement
|
||
|
||
modifiers = Shift+Lock+LevelThree;
|
||
|
||
Mandatory, should be specified only once.
|
||
|
||
A mask of real and virtual [modifiers]. These are the only modifiers
|
||
being considered when matching the modifier state against the type.
|
||
The other modifiers, whether active or not, are masked out in the
|
||
calculation.
|
||
|
||
#### “map” entry statements
|
||
|
||
map[Shift+LevelThree] = Level4;
|
||
|
||
Should have at least as many mappings as there are levels in the type.
|
||
|
||
If the active modifiers, masked with the type's modifiers (as stated
|
||
above), match (i.e. equal) the modifiers inside the `map[]` statement,
|
||
then the level in the right hand side is chosen. For example, in the
|
||
above, if in the current keyboard state the `Shift` and `LevelThree`
|
||
modifiers are active, while the `Lock` modifier is not, then the
|
||
keysym(s) in the 4th level of the group will be returned to the user.
|
||
|
||
#### “preserve” statements
|
||
|
||
map[Shift+Lock+LevelThree] = Level5;
|
||
preserve[Shift+Lock+LevelThree] = Lock;
|
||
|
||
When a key type is used for keysym translation, its modifiers are said
|
||
to be "consumed". For example, in a simple US keymap, the "g" "g" key
|
||
is assigned an ordinary `ALPHABETIC` key type, whose modifiers are
|
||
Shift and Lock; then for the "g" key, these two modifiers are consumed
|
||
by the translation. This information is relevant for applications
|
||
which further process the modifiers, since by then the consumed
|
||
modifiers have already "done their part" and should be masked out.
|
||
|
||
However, sometimes even if a modifier had already affected the key
|
||
translation through the type, it should *not* be reported as consumed,
|
||
for various reasons. In this case, a `preserve[]` statement can be
|
||
used to augment the map entry. The modifiers inside the square
|
||
brackets should match one of the map[] statements in the type (if
|
||
there is no matching map entry, one mapping to Level1 is implicitly
|
||
added). The right hand side should consists of modifiers from the
|
||
type's modifiers; these modifiers are then "preserved" and not
|
||
reported as consumed.
|
||
|
||
|
||
## The “xkb_compat” section {#the-xkb_compat-section}
|
||
|
||
This section is the third to be processed, after `xkb_keycodes` and
|
||
`xkb_types`.
|
||
|
||
### Interpret statements {#interpret-statements}
|
||
|
||
Statements of the form:
|
||
|
||
interpret Num_Lock+Any { ... }
|
||
interpret Shift_Lock+AnyOf(Shift+Lock) { ... }
|
||
|
||
The <code>[xkb_symbols]</code> section (see below)
|
||
allows the keymap author to perform, among other things, the following
|
||
things for each key:
|
||
|
||
- Bind an [action], like `SetMods` or `LockGroup`, to the key.
|
||
Actions, like symbols, are specified for each level of each group
|
||
in the key separately.
|
||
|
||
- Add a [virtual modifier] to the key's virtual modifier mapping
|
||
(`vmodmap`).
|
||
|
||
- Specify whether the key should repeat or not.
|
||
|
||
However, doing this for each key (or level) is tedious and inflexible.
|
||
Interpret's are a mechanism to apply these settings to a bunch of
|
||
keys/levels at once.
|
||
|
||
Each interpret specifies a condition by which it attaches to certain
|
||
levels. The condition consists of two parts:
|
||
|
||
- A <strong>[keysym]</strong>. If the level has a different (or more than one)
|
||
keysym, the match fails. Leaving out the keysym is equivalent to using the
|
||
special value `Any` or the `NoSymbol` keysym, which always matches
|
||
successfully.
|
||
|
||
- A <strong>[modifier] predicate</strong>. The predicate consists of:
|
||
- A __mask__ of _real_ modifiers: a `+`-separated list of modifiers or
|
||
the special value `all`, which denotes all the modifiers.
|
||
|
||
The modifiers are matched against the key's modifier map (`modmap`).
|
||
- A __matching operation__, that is one of the following:
|
||
|
||
* `AnyOfOrNone` – The modmap must either be empty or include at
|
||
least one of the specified modifiers.
|
||
* `AnyOf` – The modmap must include at least one of the specified
|
||
modifiers.
|
||
* `Any` – Alias for `AnyOf(all)`.
|
||
* `NoneOf` – The modmap must not include any of the specified
|
||
modifiers.
|
||
* `AllOf` – The modmap must include all of the specified modifiers
|
||
(but may include others as well).
|
||
* `Exactly` – The modmap must be exactly the same as the specified
|
||
modifiers.
|
||
|
||
Leaving out the predicate is equivalent to using `AnyOfOrNone(all)`.
|
||
Leaving out just the matching condition is equivalent to using
|
||
`Exactly`.
|
||
|
||
An interpret may also include `useModMapMods = level1;` – see below.
|
||
|
||
If a [level] fulfils the conditions of several interprets, only the
|
||
most specific one is used:
|
||
|
||
- A specific keysym will always match before a generic `NoSymbol`
|
||
condition.
|
||
|
||
- If the keysyms are the same, the interpret with the more specific
|
||
matching operation is used. The above list is sorted from least to
|
||
most specific.
|
||
|
||
- If both the keysyms and the matching operations are the same (but the
|
||
modifiers are different), the first interpret is used.
|
||
|
||
As described above, once an interpret "attaches" to a level, it can bind
|
||
an action to that level, add one virtual modifier to the key's vmodmap,
|
||
or set the key's repeat setting. You should note the following:
|
||
|
||
- The key repeat is a property of the entire key; it is not
|
||
level-specific. In order to avoid confusion, it is only inspected
|
||
for the first level of the first group; the interpret's repeat
|
||
setting is ignored when applied to other levels.
|
||
|
||
- If one of the above fields was set directly for a key in
|
||
`xkb_symbols`, the explicit setting takes precedence over the
|
||
interpret.
|
||
|
||
The body of the statement may include statements of the following
|
||
forms (all of which are optional):
|
||
|
||
#### “useModMapMods” statement
|
||
|
||
useModMapMods = level1;
|
||
|
||
When set to `level1`, the interpret will only match keysyms which are
|
||
on the first level of the first group of the keys. This can be useful
|
||
in conjunction with e.g. a `virtualModifier` statement, because
|
||
`virtualModifier` is an attribute of the key rather than a specific
|
||
level.
|
||
|
||
Note: the other possible value is `any` and is the default value.
|
||
|
||
#### “action” statement
|
||
|
||
action = LockMods(modifiers=NumLock);
|
||
|
||
Bind this action to the matching levels. See [key actions][actions]
|
||
for the list of available key actions.
|
||
|
||
#### “virtualModifier” statement
|
||
|
||
virtualModifier = NumLock;
|
||
|
||
Add this virtual modifier to the key's `vmodmap`. The given virtual
|
||
modifier must be declared at the top level of the file with a
|
||
`virtual_modifiers` statement, e.g.:
|
||
|
||
virtual_modifiers NumLock;
|
||
|
||
#### “repeat” statement
|
||
|
||
repeat = True;
|
||
|
||
Set whether the key should repeat or not. Must be a boolean value.
|
||
|
||
### LED map statements {#indicator-effect}
|
||
|
||
[indicator effect]: @ref indicator-effect
|
||
|
||
Statements of the form:
|
||
|
||
indicator "Shift Lock" { ... }
|
||
|
||
This statement specifies the behavior and binding of the LED (AKA
|
||
[indicator]) with the given name ("Shift Lock" above). The name should
|
||
have been declared previously in the `xkb_keycodes` section (see
|
||
[LED name][indicator name] statement), and given an index there.
|
||
If it wasn't, it is created with the next free index.
|
||
|
||
The body of the statement describes the conditions of the keyboard
|
||
state which will cause the LED to be lit. It may include the following
|
||
statements:
|
||
|
||
#### “modifiers” statement
|
||
|
||
modifiers = ScrollLock;
|
||
|
||
If the given [modifiers] are in the required state (see below), the
|
||
LED is lit.
|
||
|
||
#### “whichModState” statement
|
||
|
||
whichModState = Latched+Locked;
|
||
|
||
Can be any combination of:
|
||
|
||
* `base`, `latched`, `locked`, `effective`
|
||
* `any` (i.e. all of the above)
|
||
* `none` (i.e. none of the above)
|
||
* `compat` (legacy value, treated as effective)
|
||
|
||
This will cause the respective portion of the modifier state (see
|
||
`struct xkb_state`) to be matched against the modifiers given in the
|
||
`modifiers` statement.
|
||
|
||
Here's a simple example:
|
||
|
||
indicator "Num Lock" {
|
||
modifiers = NumLock;
|
||
whichModState = Locked;
|
||
};
|
||
|
||
Whenever the NumLock modifier is locked, the Num Lock LED will light
|
||
up.
|
||
|
||
#### “groups” statement
|
||
|
||
groups = All - group1;
|
||
|
||
If the given groups are in the required state (see below), the LED is
|
||
lit.
|
||
|
||
#### “whichGroupState” statement
|
||
|
||
whichGroupState = Effective;
|
||
|
||
Can be any combination of:
|
||
|
||
* `base`, `latched`, `locked`, `effective`
|
||
* `any` (i.e. all of the above)
|
||
* `none` (i.e. none of the above)
|
||
|
||
This will cause the respective portion of the group state (see
|
||
`struct xkb_state`) to be matched against the groups given in the
|
||
`groups` statement.
|
||
|
||
Note: the above conditions are disjunctive, i.e. if any of them are
|
||
satisfied the LED is lit.
|
||
|
||
### Default values
|
||
|
||
@todo e.g. `setMods.clearLocks= True;`
|
||
|
||
|
||
## The “xkb_symbols” section {#the-xkb_symbols-section}
|
||
|
||
@todo complete this section.
|
||
|
||
This section is the fourth to be processed, after `xkb_keycodes`,
|
||
`xkb_types` and `xkb_compat`.
|
||
|
||
Statements of the form:
|
||
|
||
xkb_symbols "basic" {
|
||
...
|
||
}
|
||
|
||
Declare a symbols map named `basic`. Statements inside the curly braces only
|
||
affect the symbols map.
|
||
|
||
A map can have various flags applied to it above the statement, separated by
|
||
whitespace:
|
||
|
||
partial alphanumeric_keys
|
||
xkb_symbols "basic" {
|
||
...
|
||
}
|
||
|
||
The possible flags are:
|
||
|
||
* `partial` - Indicates that the map doesn't cover a complete keyboard.
|
||
* `default` - Marks the symbol map as the default map in the file when no
|
||
explicit map is specified. If no map is marked as a default, the first map
|
||
in the file is the default.
|
||
* `hidden` - Variant that can only be used internally
|
||
* `alphanumeric_keys` - Indicates that the map contains alphanumeric keys
|
||
* `modifier_keys` - Indicates that the map contains modifier keys
|
||
* `keypad_keys` - Indicates that the map contains keypad keys
|
||
* `function_keys` - Indicates that the map contains function keys
|
||
* `alternate_group` - Indicates that the map contains keys for an alternate
|
||
group
|
||
|
||
If no `*_keys` flags are supplied, then the map is assumed to cover a complete
|
||
keyboard.
|
||
|
||
At present, except for `default`, none of the flags affect key processing in
|
||
libxkbcommon, and only serve as metadata.
|
||
|
||
### Name statements
|
||
|
||
Statements of the form:
|
||
|
||
name[Group1] = "US/ASCII";
|
||
groupName[1] = "US/ASCII";
|
||
|
||
Gives the name "US/ASCII" to the first group of symbols. Other groups can be
|
||
named using a different group index (ex: `Group2`), and with a different name.
|
||
A group must be named.
|
||
|
||
`group` and `groupName` mean the same thing, and the `Group` in `Group1` is
|
||
optional.
|
||
|
||
### Include statements
|
||
|
||
Statements of the form:
|
||
|
||
include "nokia_vndr/rx-51(nordic_base)"
|
||
|
||
Will include data from another `xkb_symbols` section, possibly located in
|
||
another file. Here it would include the `xkb_symbols` section called
|
||
`nordic_base`, from the file `rx-51` located in the `nokia_vndr` folder, itself
|
||
located in an XKB include path.
|
||
|
||
### Key statement
|
||
|
||
Statements of the form:
|
||
|
||
key <AD01> { [ q, Q ] };
|
||
|
||
Describes the mapping of a keycode `<AD01>` to a given group of symbols. The
|
||
possible keycodes are the keycodes defined in the `xkb_keycodes` section.
|
||
|
||
Symbols are named using the symbolic names from the
|
||
`xkbcommon/xkbcommon-keysyms.h` file. A group of symbols is enclosed in brackets
|
||
and separated by commas. Each element of the symbol arrays corresponds to a
|
||
different modifier level. In this example, the symbol (keysym) `XKB_KEY_q` for
|
||
level 1 and `XKB_KEY_Q` for level 2.
|
||
|
||
As an extension to the XKB format, libxkbcommon supports multiple key symbols
|
||
per level.
|
||
|
||
key <AD01> { [ {a, b}, Q ] };
|
||
|
||
In this example, the keycode `<AD01>` produces two symbols on level 1
|
||
(`XKB_KEY_a` and `XKB_KEY_b`) and one symbol (`XKB_KEY_Q`) on level 2.
|
||
|
||
@warning Keymaps containing multiple key symbols per level are not supported
|
||
by the various X11-related tools (`setxkbmap`, `xkbcomp`, etc.).
|
||
|
||
#### Actions
|
||
|
||
@todo how to bind key actions
|
||
|
||
For further details see [key actions][actions].
|
||
|
||
#### Groups
|
||
|
||
Each group represents a list of symbols mapped to a keycode:
|
||
|
||
name[Group1]= "US/ASCII";
|
||
name[Group2]= "Russian";
|
||
...
|
||
key <AD01> { [ q, Q ],
|
||
[ Cyrillic_shorti, Cyrillic_SHORTI ] };
|
||
|
||
A long-form syntax can also be used:
|
||
|
||
key <AD01> {
|
||
symbols[Group1]= [ q, Q ],
|
||
symbols[Group2]= [ Cyrillic_shorti, Cyrillic_SHORTI ]
|
||
};
|
||
|
||
Groups can also be omitted, but the brackets must be present. The following
|
||
statement only defines the Group3 of a mapping:
|
||
|
||
key <AD01> { [], [], [ q, Q ] };
|
||
|
||
#### Additional attributes
|
||
|
||
@todo virtualmodifiers, repeats
|
||
|
||
## Virtual modifier statements {#virtual-modifier-statements}
|
||
|
||
@todo rework this section
|
||
|
||
Statements of the form:
|
||
|
||
virtual_modifiers LControl;
|
||
|
||
Can appear in the `xkb_types`, `xkb_compat`, `xkb_symbols` sections.
|
||
|
||
## Modifiers bindings {#modifiers-bindings}
|
||
|
||
### Real and virtual modifiers
|
||
|
||
Modifiers are a particularly tricky part of XKB. For historical reasons they are
|
||
divided in two categories: [real modifiers] and [virtual modifiers].
|
||
|
||
Note that in X11, the maximum of virtual modifiers is 16
|
||
(see `XkbNumVirtualMods`).
|
||
|
||
The following table summarizes the modifiers defined
|
||
in <code>[xkeyboard-config]</code> (this is subject to change).
|
||
|
||
| Modifier | Type | Compat files | Associated keysyms |
|
||
|--------------|---------|------------------|----------------------|
|
||
| `Shift` | Real | `compat/basic` | `Shift_L`, `Shift_R` |
|
||
| ″ | ″ | `compat/iso9995` | `Shift_L`, `Shift_R`, `ISO_Level2_Latch` |
|
||
| `Lock` | Real | `compat/basic`, | `Caps_Lock` |
|
||
| ″ | ″ | `compat/caps` | ″ |
|
||
| `Control` | Real | `compat/basic` | `Control_L`, `Control_R` |
|
||
| `Alt` | Virtual | `compat/misc`, | `Alt_L`, `Alt_R` |
|
||
| ″ | ″ | `compat/pc` | ″ |
|
||
| `Meta` | Virtual | `compat/misc` | `Meta_L`, `Meta_R` |
|
||
| `Super` | Virtual | `compat/misc` | `Super_L`, `Super_R` |
|
||
| `Hyper` | Virtual | `compat/misc` | `Hyper_L`, `Hyper_R` |
|
||
| `ScrollLock` | Virtual | `compat/misc` | `Scroll_Lock` |
|
||
| `NumLock` | Virtual | `compat/basic`, | `Num_Lock`, |
|
||
| ″ | ″ | `compat/level5` | (`ISO_Level5_Lock`) |
|
||
| `LevelThree` | Virtual | `compat/iso9995` | `ISO_Level3_Shift`, `ISO_Level3_Latch`, `ISO_Level3_Lock` |
|
||
| `LevelFive` | Virtual | `compat/level5` | `ISO_Level5_Shift`, `ISO_Level5_Latch`, `ISO_Level5_Lock` |
|
||
| `Kana_Lock` | Virtual | `compat/japan` | `Kana_Lock` |
|
||
| `Square` | Virtual | `compat/olpc` | `KP_Home` |
|
||
| `Cross` | Virtual | `compat/olpc` | `KP_Next` |
|
||
| `Circle` | Virtual | `compat/olpc` | `KP_End` |
|
||
| `Triangle` | Virtual | `compat/olpc` | `KP_Prior` |
|
||
|
||
### Define and use a modifier
|
||
|
||
We will use the example of the _real_ modifier `Shift` and the virtual
|
||
modifier `LevelThree` in `xkeyboard-config`.
|
||
|
||
In order to define and use a modifier, one must:
|
||
|
||
1. Define its behavior and [keysym] binding in the
|
||
<code>[xkb_compat]</code> section:
|
||
|
||
```c
|
||
// Declare virtual modifiers. Shift being real modifier,
|
||
// we do not need to add it here.
|
||
virtual_modifiers LevelThree;
|
||
|
||
// Set defaults. They are overridden if set directly in the xkb_symbols.
|
||
interpret.repeat= False; // only applied on first level
|
||
setMods.clearLocks= True;
|
||
latchMods.clearLocks= True;
|
||
latchMods.latchToLock= True;
|
||
|
||
// Default statement for real modifiers: any key bound to a real
|
||
// modifier via modifier_map will set this modifier at all its
|
||
// levels.
|
||
// Here only to illustrate: do not add it!
|
||
interpret Any + Any {
|
||
action= SetMods(modifiers=modMapMods);
|
||
};
|
||
|
||
// Shift being real modifier, we do not need a corresponding
|
||
// interpret statement because the previous one suffices.
|
||
|
||
// Let’s associate LevelThree to the keysym ISO_Level3_Shift
|
||
|
||
// First, match the keys and their levels with the
|
||
// ISO_Level3_Shift keysym and with any real modifier
|
||
// (Any = AnyOf(all)) in its modmap.
|
||
interpret ISO_Level3_Shift+Any {
|
||
// Only match the first level of the first group
|
||
useModMapMods= level1;
|
||
// Add the virtual modifier to the key’s vmodmap
|
||
virtualModifier= LevelThree;
|
||
// Activate the LevelThree modifier (depressed mode)
|
||
action= SetMods(modifiers=LevelThree);
|
||
};
|
||
|
||
// Then for keys and their levels with the
|
||
// ISO_Level3_Shift keysym but with either no real modifier
|
||
// in its modmap or a level higher than 1.
|
||
// Indeed:
|
||
// • In case the level is higher than 1 there is no match
|
||
// in the previous statement.
|
||
// • The condition is equivalent to
|
||
// ISO_Level3_Shift+AnyOfOrNone(all), but since
|
||
// the previous statement ISO_Level3_Shift+Any is more
|
||
// specific, it will be matched before this one.
|
||
interpret ISO_Level3_Shift {
|
||
// Activate the LevelThree modifier (depressed mode)
|
||
action= SetMods(modifiers=LevelThree);
|
||
};
|
||
```
|
||
|
||
2. Define [key types] that use it in the
|
||
<code>[xkb_types]</code> section:
|
||
|
||
```c
|
||
// Declare virtual modifiers. Shift being real modifier,
|
||
// we do not need to add it here.
|
||
virtual_modifiers LevelThree;
|
||
|
||
type "FOUR_LEVEL" {
|
||
// Key type modifier mask: all the modifiers used in the key type
|
||
modifiers = Shift + LevelThree;
|
||
map[None] = Level1;
|
||
map[Shift] = Level2;
|
||
map[LevelThree] = Level3;
|
||
map[Shift+LevelThree] = Level4;
|
||
level_name[Level1] = "Base";
|
||
level_name[Level2] = "Shift";
|
||
level_name[Level3] = "AltGr";
|
||
level_name[Level4] = "Shift AltGr";
|
||
};
|
||
```
|
||
|
||
3. Bind it to a [keycode] in the
|
||
<code>[xkb_symbols]</code> section:
|
||
|
||
1. Map [keysyms] used in the `xkb_compat` section hereinabove.
|
||
2. Bind [real modifiers] to keys using these keysyms with
|
||
`modifier_map`.
|
||
|
||
_Note:_ Only one key binding to real modifier is required.
|
||
The corresponding keysym must then be on the first level of
|
||
the first Group.
|
||
|
||
_Note:_ One can optionally bind directly a virtual modifier to a
|
||
key using `virtualmodifiers` instead of doing it in the
|
||
`xkb_compat` section. But the recommended way is to use the
|
||
`xkb_compat` section.
|
||
|
||
```c
|
||
// Shift: defined in pc symbols
|
||
key <LFSH> {[ Shift_L ]};
|
||
key <RTSH> {[ Shift_R ]};
|
||
modifier_map Shift { Shift_L, Shift_R };
|
||
// The previous will resolve to:
|
||
// modifier_map Shift { <LFSH>, <RTSH> };
|
||
// Thus the real modifier Shift is added to the modmap of
|
||
// <LFSH> and <RTSH>.
|
||
// The “Any + Any” interpret statement matches <LFSH> and <RTSH>,
|
||
// therefore these keys set the Shift modifier.
|
||
|
||
// LevelThree: defined in pc symbols
|
||
// With the following 2 lines:
|
||
// 1. The modifier keysym is on the first level of the first group.
|
||
// 2. The real modifier Mod5 is bound to <LVL3>,
|
||
// i.e. Mod5 is added to its modmap.
|
||
// 3. It matches the interpret statement “ISO_Level3_Shift+Any”,
|
||
// which adds the LevelThree modifier to the vmodmap of <LVL3>.
|
||
// 4. The mapping of LevelThree to real modifiers is the union
|
||
// of modmaps with corresponding vmodmaps containing
|
||
// LevelThree. In our case there is only one: therefore
|
||
// LevelThree maps to Mod5.
|
||
key <LVL3> {[ ISO_Level3_Shift ]};
|
||
modifier_map Mod5 { <LVL3> };
|
||
|
||
// LevelThree: defined in level3 symbols
|
||
// Not bound to a real modifier, so interpret statement
|
||
// “ISO_Level3_Shift” applies.
|
||
key <RALT> {[ISO_Level3_Shift], type[group1]="ONE_LEVEL" };
|
||
|
||
// Note: we could have the following line, but it is not necessary
|
||
// because we have the mappings of <LVL3>.
|
||
// modifier_map Mod5 { <RALT> };
|
||
|
||
// Warning: if we had the for example the following line, the
|
||
// mapping of LevelThree to real modifiers would be “Mod1+Mod5”.
|
||
// modifier_map Mod1 { <RALT> };
|
||
|
||
// Alternative definitions, without using interpret statements
|
||
virtual_modifiers LevelThree;
|
||
key <LVL3> { virtualmodifiers=LevelThree
|
||
, repeats=False
|
||
, symbols[Group1] = [ISO_Level3_Shift]
|
||
, actions[Group1] = [SetMods(modifiers=LevelThree)] };
|
||
modifier_map Mod5 { <LVL3> };
|
||
key <RALT> { repeat=False
|
||
, symbols[Group1] = [ISO_Level3_Shift]
|
||
, actions[Group1] = [SetMods(modifiers=LevelThree)]
|
||
, type[group1]="ONE_LEVEL" };
|
||
|
||
// FOUR_LEVEL key type example from latin symbols
|
||
key <AB05> {[b, B, leftdoublequotemark, leftsinglequotemark]};
|
||
```
|
||
|
||
## Key actions {#key-actions}
|
||
|
||
@todo list of all actions and their parameters
|
||
|
||
The following table provide an overview of the available actions:
|
||
|
||
| Category | Action | Alias | Description |
|
||
|----------|---------------------|------------------|------------------------------------|
|
||
| | `NoAction` | | Do nothing. |
|
||
| [Modifier action] | `SetMods` | | Modifies the _depressed_ modifiers |
|
||
| ^ | `LatchMods` | | Modifies the _latched_ modifiers |
|
||
| ^ | `LockMods` | | Modifies the _locked_ modifiers |
|
||
| [Group action] | `SetGroup` | | <span class="todo">TODO</span> |
|
||
| ^ | `LatchGroup` | | <span class="todo">TODO</span> |
|
||
| ^ | `LockGroup` | | <span class="todo">TODO</span> |
|
||
| [Legacy action] | `MovePointer` | `MovePtr` | <span class="todo">TODO</span> |
|
||
| ^ | `PointerButton` | `PtrBtn` | <span class="todo">TODO</span> |
|
||
| ^ | `LockPointerButton` | `LockPtrBtn` | <span class="todo">TODO</span> |
|
||
| ^ | `SetPointerDefault` | `SetPtrDflt` | <span class="todo">TODO</span> |
|
||
| ^ | `SetControls` | | <span class="todo">TODO</span> |
|
||
| ^ | `LockControls` | | <span class="todo">TODO</span> |
|
||
| ^ | `TerminateServer` | `Terminate` | <span class="todo">TODO</span> |
|
||
| ^ | `SwitchScreen` | | <span class="todo">TODO</span> |
|
||
| ^ | `Private` | | <span class="todo">TODO</span> |
|
||
|
||
Common syntax:
|
||
- Boolean values:
|
||
- `true`, `yes`, `on`
|
||
- `false`, `no`, `off`
|
||
|
||
### Modifiers actions {#modifiers-actions}
|
||
|
||
[modifier action]: @ref modifiers-actions
|
||
|
||
@todo default values
|
||
|
||
There are 3 modifiers actions:
|
||
|
||
<dl>
|
||
<dt>`SetMods`</dt>
|
||
<dd>
|
||
Modifies the _depressed_ modifiers.
|
||
|
||
Parameters:
|
||
- `modifiers` or `mods`: the list of modifiers to modify,
|
||
separated by `+`, or the special value `modMapMods`. The latter
|
||
means the parameter value has to be read from the `vmodmap`
|
||
attribute of the key.
|
||
- `clearLocks`: boolean (see its use hereinafter).
|
||
</dd>
|
||
<dt>`LatchMods`</dt>
|
||
<dd>
|
||
Modifies the _latched_ modifiers
|
||
|
||
Parameters:
|
||
- `modifiers` or `mods`: see `SetMods`.
|
||
- `clearLocks`: boolean (see its use hereinafter).
|
||
- `latchToLock`: boolean (see its use hereinafter).
|
||
</dd>
|
||
<dt>`LockMods`</dt>
|
||
<dd>
|
||
Modifies the _locked_ modifiers.
|
||
|
||
Parameters:
|
||
- `modifiers` or `mods`: see `SetMods`.
|
||
- `affect`:
|
||
- `lock`: the action only locks the modifier, but cannot unlock it.
|
||
- `unlock`: the action only unlocks modifier, but cannot lock it.
|
||
- `both`: the first key press locks the modifier and the second key
|
||
press releases the modifier. It is a default mode.
|
||
- `neither`: do not lock nor unlock, i.e. do nothing.
|
||
</dd>
|
||
</dl>
|
||
|
||
@todo highlight that there is reference counting for
|
||
the modifiers, e.g. to manage multiple physical keys for the same modifier.
|
||
|
||
These actions perform different tasks on key press and on key release:
|
||
|
||
<table>
|
||
<caption>
|
||
Effects of modifiers actions
|
||
</caption>
|
||
<!-- <thead> -->
|
||
<tr>
|
||
<th>Action</th>
|
||
<th>On key press</th>
|
||
<th>On key release</th>
|
||
</tr>
|
||
<!-- </thead> -->
|
||
<!-- <tbody> -->
|
||
<tr>
|
||
<th><code>SetMods</code></th>
|
||
<td>
|
||
<ul>
|
||
<li>Adds modifiers to <em>depressed</em> modifiers</li>
|
||
</ul>
|
||
</td>
|
||
<td>
|
||
<ul>
|
||
<li>
|
||
Removes modifiers from <em>depressed</em> modifiers,
|
||
provided that no other key which affects the same
|
||
modifiers is logically down.
|
||
</li>
|
||
<li>
|
||
If <code>clearLocks=yes</code> and no other key
|
||
were operated simultaneously with this key,
|
||
then the modifiers will be removed as well from
|
||
the <em>locked</em> modifiers.
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th><code>LatchMods</code></th>
|
||
<td>
|
||
<ul>
|
||
<li>Adds modifiers to <em>latched</em> modifiers.</li>
|
||
</ul>
|
||
</td>
|
||
<td>
|
||
<ul>
|
||
<li>Removes modifiers from <em>latched</em> modifiers.</li>
|
||
<li>
|
||
If <code>clearLocks=yes</code> and no other key
|
||
has been pressed since this key press, then the
|
||
modifiers will be removed as well from the
|
||
<em>locked</em> modifiers.
|
||
</li>
|
||
<li>
|
||
If <code>latchToLock=yes</code> then the modifiers
|
||
are added to the <em>locked</em> modifiers.
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>
|
||
<code>LockMods</code>
|
||
</th>
|
||
<td>
|
||
<ul>
|
||
<li>Adds modifiers to <em>depressed</em> modifiers.</li>
|
||
<li>
|
||
Toggle these modifiers in <em>locked</em> modifiers.</li>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td>
|
||
<ul>
|
||
<li>Removes modifiers from <em>depressed</em> modifiers.</li>
|
||
<li><em>Locked</em> modifiers stay unchanged.</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<!-- </tbody> -->
|
||
</table>
|
||
|
||
@todo Finish
|
||
|
||
### Group actions {#group-actions}
|
||
|
||
[group action]: @ref group-actions
|
||
|
||
There are 3 group actions:
|
||
|
||
<dl>
|
||
<dt>SetGroup</dt>
|
||
<dd>
|
||
<span class="todo">TODO</span>
|
||
</dd>
|
||
<dt>LatchGroup</dt>
|
||
<dd>
|
||
<span class="todo">TODO</span>
|
||
</dd>
|
||
<dt>LockGroup</dt>
|
||
<dd>
|
||
<span class="todo">TODO</span>
|
||
</dd>
|
||
</dl>
|
||
|
||
@todo Describe each action
|
||
|
||
### Unsupported legacy actions {#legacy-actions}
|
||
|
||
[legacy action]: @ref legacy-actions
|
||
|
||
@attention The following legacy actions are kept for compatibility only: they are parsed
|
||
and validated but have no effect. This allows to use keymaps defined in
|
||
<code>[xkeyboard-config]</code> for both X11 and Wayland.
|
||
|
||
#### Pointer actions
|
||
|
||
| Action | Alias | Description |
|
||
|---|---|---|
|
||
| `MovePointer` | `MovePtr` | |
|
||
| `PointerButton` | `PtrBtn` | |
|
||
| `LockPtrButton` | `LockPtrBtn` | |
|
||
| `LockPointerButton` | `LockPointerBtn` | |
|
||
| `SetPointerDefault` | `SetPtrDflt` | |
|
||
|
||
@todo Describe each action
|
||
|
||
#### Control flags actions
|
||
|
||
@todo `SetControls`, `LockControls`
|
||
|
||
#### Server actions
|
||
|
||
@todo `TerminateServer`, `SwitchScreen`
|
||
|
||
#### Private action
|
||
|
||
@todo `Private`
|