<!DOCTYPE html><html><head><title></title></head><body><div>I'm happy to announce another large release of xkbcommon, this time fully by the careful hands of Wismill[0].</div><div>A few highlights are:</div><div>- Can now write keysyms as just Unicode strings, including multi-keysyms. Can make keymaps a lot easier</div><div>  to read and write.</div><div>- New `<none>`, `<some>` and `<any>` wildcards in rules files.</div><div>- New escaping format for Unicode - `\u{NNNN}`.</div><div>Remember that as always, these are xkbcommon extensions not supported by X.</div><div>We try to keep our docs <a href="https://xkbcommon.org/doc/current/index.html">https://xkbcommon.org/doc/current/index.html</a> up to date with all changes.</div><div><br></div><div>[0] Check out the release diff to see the extent of the work! <a href="https://github.com/xkbcommon/libxkbcommon/compare/xkbcommon-1.8.1...xkbcommon-1.9.0">https://github.com/xkbcommon/libxkbcommon/compare/xkbcommon-1.8.1...xkbcommon-1.9.0</a><br></div><div><br></div><div>libxkbcommon [1.9.0] - 2025-04-26</div><div>=================================</div><div><br></div><div>[1.9.0]: <a href="https://github.com/xkbcommon/libxkbcommon/tree/xkbcommon-1.9.0">https://github.com/xkbcommon/libxkbcommon/tree/xkbcommon-1.9.0</a></div><div><br></div><div>## API</div><div><br></div><div>### Breaking changes</div><div><br></div><div>- *Merge modes* and *include mechanism* were completely refactored to fix inconsistencies.</div><div>  Included files are now always processed in isolation and do not propagate the local</div><div>  merge modes. This makes the reasoning about included files much easier and consistent.</div><div>- Trailing `NoSymbol` and `NoAction()` are now dropped. This may affect keys that</div><div>  rely on an *implicit* key type.</div><div><br></div><div>  Example:</div><div>  - Input:</div><div>    ```c</div><div>    key <> { [a, A, NoSymbol] };</div><div>    ```</div><div>  - Compilation with xkbcommon \< 1.9.0:</div><div>    ```c</div><div>    key <> {</div><div>      type= "FOUR_LEVEL_SEMIALPHABETIC",</div><div>      [a, A, NoSymbol, NoSymbol]</div><div>    };</div><div>    ```</div><div><br></div><div>  - Compilation with xkbcommon ≥ 1.9.0:</div><div>    ```c</div><div>    key <> {</div><div>      type= "ALPHABETIC",</div><div>      [a, A]</div><div>    };</div><div>    ```</div><div><br></div><div>### New</div><div><br></div><div>- Added function `xkb_components_names_from_rules()` to compute</div><div>  <abbr title="Keycodes, Compatibility, Geometry, Symbols, Types">KcCGST</abbr></div><div>  keymap components from</div><div>  <abbr title="Rules, Model, Layout, Variant, Options">RMLVO</abbr> names resolution.</div><div>  This mainly for *debugging* purposes and to enable the `--kccgst` option in the tools.</div><div>  ([#669](<a href="https://github.com/xkbcommon/libxkbcommon/issues/669">https://github.com/xkbcommon/libxkbcommon/issues/669</a>))</div><div>- Added the following *wild cards* to the **rules** file syntax, in addition to</div><div>  the current `*` legacy wild card:</div><div>  - `<none>`: Match *empty* value.</div><div>  - `<some>`: Match *non-empty* value.</div><div>  - `<any>`: Match *any* (optionally empty) value. Its behavior does not depend on</div><div>    the context, contrary to the legacy wild card `*`.</div><div>- All keymap components are now optional, e.g. a keymap without a `xkb_types`</div><div>  section is now legal. The missing components will still be serialized explicitly</div><div>  in order to maintain backward compatibility.</div><div>- Added support for further empty compound statements:</div><div>  - `xkb_types`: `type \"xxx\" {};`</div><div>  - `xkb_compat`: `interpret x {};` and `indicator \"xxx\" {};`.</div><div><br></div><div>  Such statements are initialized using the current defaults, i.e. the</div><div>  factory implicit defaults or some explicit custom defaults (e.g.</div><div>  `indicator.modifiers = Shift`).</div><div>- Added support for actions and keysyms level list of length 0 and 1: respectively</div><div>  `{}` and `{a}`. Example: `key <A> { [{}, {a}, {a, A}] };`.</div><div>- Enable using the merge mode *replace* in include statements using the prefix `^`,</div><div>  such as: `include "a^b"`. The main motivation is to enable this new syntax in</div><div>  *rules*, which previously could not handle this merge mode.</div><div>- Added support for sequences of actions in `interpret` statements of the</div><div>  `xkb_compat` component, mirroring the syntax used in `xkb_symbols`.</div><div>  ([#695](<a href="https://github.com/xkbcommon/libxkbcommon/issues/695">https://github.com/xkbcommon/libxkbcommon/issues/695</a>))</div><div>- Added support for keysym Capitalization transformation to `xkb_state_key_get_syms()`.</div><div>  ([#552](<a href="https://github.com/xkbcommon/libxkbcommon/issues/552">https://github.com/xkbcommon/libxkbcommon/issues/552</a>))</div><div>- `xkb_utf32_to_keysym`: Allow [Unicode noncharacters].</div><div>  ([#715](<a href="https://github.com/xkbcommon/libxkbcommon/issues/715">https://github.com/xkbcommon/libxkbcommon/issues/715</a>))</div><div>- `xkb_keysym_from_name`:</div><div>  - Unicode format `UNNNN`: allow control characters C0 and C1 and use</div><div>    `xkb_utf32_to_keysym` for the conversion when `NNNN < 0x100`, for</div><div>    backward compatibility.</div><div>  - Numeric hexadecimal format `0xNNNN`: *unchanged*. Contrary to the Unicode</div><div>    format, it does not normalize any keysym values in order to enable roundtrip</div><div>    with `xkb_keysym_get_name`.</div><div><br></div><div>  [Unicode noncharacters]: <a href="https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Noncharacters">https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Noncharacters</a></div><div><br></div><div>  ([#715](<a href="https://github.com/xkbcommon/libxkbcommon/issues/715">https://github.com/xkbcommon/libxkbcommon/issues/715</a>))</div><div>- Added [Unicode code point] escape sequences `\u{NNNN}`. They are replaced with</div><div>  the [UTF-8] encoding of their corresponding code point `U+NNNN`, if legal.</div><div>  Supported Unicode code points are in the range `1‥0x10ffff`. This is intended</div><div>  mainly for writing keysyms as [UTF-8] encoded strings.</div><div><br></div><div>  [Unicode code point]: <a href="https://en.wikipedia.org/wiki/Unicode#Codespace_and_code_points">https://en.wikipedia.org/wiki/Unicode#Codespace_and_code_points</a></div><div>  [UTF-8]: <a href="https://en.wikipedia.org/wiki/UTF-8">https://en.wikipedia.org/wiki/UTF-8</a></div><div>- Enable to write keysyms as UTF-8-encoded strings:</div><div>  - *Single* Unicode code point `U+1F3BA` (TRUMPET) `"🎺"` is converted into a</div><div>    single keysym: `U1F3BA`.</div><div>  - *Multiple* Unicode code points are converted to a keysym *list* where it is</div><div>    allowed (i.e. in key symbols). E.g. `"J́"` is converted to U+004A LATIN CAPITAL</div><div>    LETTER J plus U+0301 COMBINING ACUTE ACCENT: `{J, U0301}`.</div><div>  - An empty string `""` denotes the keysym `NoSymbol`.</div><div>- Enable displaying bidirectional text in XKB files using the following Unicode</div><div>  code points, wherever a white space can be used:</div><div>  - U+200E LEFT-TO-RIGHT MARK</div><div>  - U+200F RIGHT-TO-LEFT MARK</div><div><br></div><div>### Fixes</div><div><br></div><div>- Added support for `libxml2-2.14+`, which now disallows parsing trailing `NULL` bytes.</div><div>  ([#692](<a href="https://github.com/xkbcommon/libxkbcommon/issues/692">https://github.com/xkbcommon/libxkbcommon/issues/692</a>))</div><div>- Fixed included *default* section not resolving to an *exact* match in some</div><div>  cases. It may occur if one creates a file name in a *user* XKB directory that</div><div>  also exists in the XKB *system* directory.</div><div><br></div><div>  Example: if one creates a custom variant `my_variant` in the file</div><div>  `$XDG_CONFIG_HOME/xkb/symbols/us`, then *before* libxkbcommon 1.9.0 every</div><div>  statement loading the *default* map of the `us` file, `include "us"`, would</div><div>  wrongly resolve including `us(my_variant)` from the *user* configuration</div><div>  directory instead of `us(basic)` from the XKB *system* directory. Starting</div><div>  from libxkbcommon 1.9.0, `include "us"` would correctly resolve to the system</div><div>  file, unless `$XDG_CONFIG_HOME/xkb/symbols/us` contains an *explicit default*</div><div>  section. ([#726](<a href="https://github.com/xkbcommon/libxkbcommon/issues/726">https://github.com/xkbcommon/libxkbcommon/issues/726</a>))</div><div>- Fixed floating-point number parsing failling on locales that use a decimal</div><div>  separator different than the period `.`.</div><div><br></div><div>  Note that the issue is unlikely to happen even with such locales, unless</div><div>  *parsing* a keymap with a *geometry* component which contains floating-point</div><div>  numbers.</div><div><br></div><div>  Affected API:</div><div>  - `xkb_keymap_new_from_file()`,</div><div>  - `xkb_keymap_new_from_buffer()`,</div><div>  - `xkb_keymap_new_from_string()`.</div><div><br></div><div>  Unaffected API:</div><div>  - `xkb_keymap_new_from_names()`: none of the components loaded use</div><div>    floating-point number. libxkbcommon does not load *geometry* files.</div><div>  - `libxkbcommon-x11`: no such parsing is involved.</div><div>- Fixed the handling of empty keys. Previously keys with no symbols nor actions</div><div>  would simply be skipped entirely. E.g. in the following:</div><div><br></div><div>  ```c</div><div>  key <A> { vmods = M };</div><div>  modifier_map Shift { <A> };</div><div>  ```</div><div><br></div><div>  the key `<A>` would be skipped and the virtual modifier `M` would not be</div><div>  mapped to `Shift`. This is now handled properly.</div><div>- Fixed characters not escaped properly in the keymap serialization, resulting in</div><div>  a keymap string with erroneous string literals and possible syntax errors.</div><div>- Fixed octal escape sequences valid in Xorg’s xkbcomp but not in xkbcommon. Now up</div><div>  to *4* digits are parsed, compared to *3* previously.</div><div>- Fixed the serialization of the `whichGroupState` indicator field.</div><div><br></div><div><br></div><div>## Tools</div><div><br></div><div>### New</div><div><br></div><div>- `xkbcli compile-keymap`: Added `--kccgst` option to display the result of</div><div>  <abbr title="Rules, Model, Layout, Variant, Options">RMLVO</abbr> names resolution to</div><div>  <abbr title="Keycodes, Compatibility, Geometry, Symbols, Types">KcCGST</abbr> components.</div><div><br></div><div>  This option has the same function than `setxkbmap -print`. This is particularly</div><div>  useful for debugging issues with the rules. ([#669](<a href="https://github.com/xkbcommon/libxkbcommon/issues/669">https://github.com/xkbcommon/libxkbcommon/issues/669</a>))</div><div>- Honor user locale in all tools.</div><div><br></div><div><br></div><div>## Build system</div><div><br></div><div>No significant changes.<br></div><div><br></div><div>Git tag:</div><div>--------</div><div><br></div><div>git tag: xkbcommon-1.9.0</div><div>git commit: ee1a98c5b3ba1f1981c5dfbea1a054cf7ad00140<br></div><div><br></div><div>Ran</div></body></html>