Branch :
| Author | Commit | Date | CI | Message |
|---|---|---|---|---|
| 44fad8a0 | 2025-09-14 10:29:41 | keysyms: Update to Unicode 17.0 See: https://www.unicode.org/versions/Unicode17.0.0/ | ||
| 87042776 | 2025-08-21 19:30:37 | logging: Encode verbosity values in an enum This enables to provide semantics and to ensure we use the values uniformly in the code base. While one could expect that verbosity `0` silences the logging, it is actually our default verbosity level for a long time. So this commit does not change that in order to avoid possible breakage. Silencing the logging is achieved by using a negative value for the verbosity level. | ||
| 135b3204 | 2025-08-16 12:59:20 | compose: Add fallback for custom locales Before this commit, loading a Compose file based on the locale would fail if the locale is not in the X11 Compose locale registry. While there are workarounds (e.g. `~/.XCompose` file or `$XCOMPOSEFILE`), it does not work if the corresponding file has `include "%L"`. This commit adds the fallback `en_US.UTF-8` in case the locale is installed but not registered in the X11 Compose locale registry. The choice is motivated by the fact that most locales use `en_US.UTF-8` anyway. Ideally we should have a mechanism to extend the Compose locale registry at the *system* level. Mechanisms at the user level (e.g. custom Compose file, environment variable) are deemed sufficient. We could still improve it by first trying to fallback to the locale without the country bits, but there is no function to do such function in the stdlib and we do not want to mess with locales manually. Unfortunately is not possible to test it in our test suite. One can still check it works following these instructions: 1. Create a custom locale, e.g. `en_XX.UTF-8`. `glibc-i18ndata` or similar package may be required to get the required files in `/usr/share/i18n/`. `sudo localedef -i en_US -f UTF-8 en_XX.UTF-8` 2. `xkbcli compile-compose --verbose --locale en_XX.UTF-8` | ||
| 3449f69f | 2025-08-16 12:57:49 | doc: Add new message XKB_ERROR_INVALID_COMPOSE_LOCALE | ||
| b5d969dd | 2025-08-06 17:22:38 | compose: Move constants to dedicated header | ||
| 39726cac | 2025-08-06 20:29:26 | Add xkb_keymap_mod_get_mask2() Retrospectively, `xkb_keymap_mod_get_mask()` should have used a modifier index rather that a modifier name in its type. Since we already published a version with this API, it’s too late to change that, so instead add a new function `xkb_keymap_mod_get_mask2()`. | ||
| 6fac73f3 | 2025-08-02 09:49:44 | log: Fix NULL string Fixed regression introduced in 05d13d5f41d94c7776456d856fccb5969e8f5b0a. | ||
| 1e0c5790 | 2025-07-23 12:09:32 | keysyms: Fix XF86MediaSelectAuxiliary typo | ||
| e9fd95a5 | 2025-07-23 10:01:45 | keysyms: Update using latest xorgproto xorgproto commit: 7fc33fe6d9cf0abc9b62ee976e5cb7ddcd050d1f Relevant MR: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/93 | ||
| d60b3213 | 2025-07-16 08:00:30 | Make the ref counting invariants explicit with assertions | ||
| 93818226 | 2025-07-15 11:34:06 | Add xkb_rmlvo_builder_ref() | ||
| dc63e5f8 | 2025-07-07 12:28:24 | Ensure config.h is always included first While `config.h` may not be necessary in every file, it ensures consistency and makes code refactoring safer. | ||
| b21a58d0 | 2025-07-01 14:52:11 | Add support for all level indices to LevelN constants Note that serialization must use numbers instead of names for levels > 8, to ensure backward compatibility. | ||
| e73d1a4d | 2025-07-01 13:05:44 | Add support for all layout indices to GroupN constants This commit enables to use the pattern `Group<INDEX>` for any valid group index `<INDEX>`. Note that the original code in xkbcomp allows constants up to `Group8`, but then will fail if the resulting group is > 4. There does not seem to be any use case for this for such “feature”; it seems rather to be a relic from times were the 4-groups limit was not hopelessly fixed in X. So for consistency in our code base, starting with this commit we now disallow `Group5`..`Group8` for keymap format v1, since it is limited to 4 groups. Also fixed a regression in the serialization of group action, when the group is relative. | ||
| 64b1b9d7 | 2025-07-01 13:03:59 | utils: Optimize istreq_prefix | ||
| 84914512 | 2025-07-01 18:37:22 | chore: Rename indexes to indices Before this commit there was a mix between the two forms. While “indexes” is correct, “indices” is more usual and also the historical form used in this project. | ||
| 58373807 | 2025-06-27 18:21:19 | keysym: Do not convert UTF-32 to deprecated keysyms Before this commit, some code points could be converted to deprecated keysym. This is incorrect, because the relevant keysyms are all deprecated because their mapping to Unicode is uncertain! Ensure that `xkb_utf32_to_keysym()` never returns deprecated keysyms, because there is either another non-deprecated keysym or in last resort we always have the correct keysym available in the Unicode keysym range. | ||
| 05d13d5f | 2025-06-26 16:58:50 | include: Fix infinite loop Fixed including an absolute path with no default map triggering an infinite loop. | ||
| c4f4ba41 | 2025-06-23 18:15:18 | state: Fix modifier and group latch Prior to this commit, the sequences: - 1. latch A ↓ 2. latch B ↓ 3. latch B ↑ 4. latch A ↑ - 1. latch A ↓ 2. latch B ↓ 3. latch A ↑ 4. latch B ↑ would result in only B being latched, because the XKB protocol specifies that latches are triggered only if keys are *sequentially* tapped, i.e. a strict sequence of press and release of each key. It seems an unnecessary limitation: - `SlowKeys` and `XkbAX_TwoKeys` are the proper accessibility features to control accidental key presses, not latches nor `StickyKeys`. - Latches are also used outside their original accessibility role. A user may activate multiple latch keys simultaneously: - same hand: two latch keys being close to each other; - different hand: two keys being activated independently. Changed the latching behavior so that the rules used to break a latch are the same than those used to prevent it. Depressing and releasing two latching keys simultaneously will now activate both latches, as expected. Since this is a breaking change, it is enabled only by the keymap format `XKB_KEYMAP_FORMAT_TEXT_V2`. | ||
| 3d00222e | 2025-06-21 18:26:34 | keymap: Add option `unlockOnPress` for LatchMods() It mirrors the feature of `SetMods()`, so that `StickyKeys` can be implemented. | ||
| d192b3b6 | 2025-06-19 21:57:46 | keymap: Add option `unlockOnPress` for SetMods() It enables e.g. to deactivate `CapsLock` *on press* rather than on release, as in other platforms such as Windows. It fixes a [18-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [18-year old issue]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/74 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions | ||
| ee87f6ed | 2025-06-21 19:28:53 | state: Fix broken latch not honoring clearLocks=no Before this commit, breaking a latch (modifier & group) would always clear locks, even if `clearLocks=no`. | ||
| 94d8e341 | 2025-06-21 13:17:16 | state: Fix LatchMods mutation to SetMods or LockMods Previously we use inlined version of the corresponding filter functions of the `SetMods()` and `LockMods()` actions, but they were incomplete and did not set some fields (`priv`, `refcnt`) properly. Also, it is error-prone: it requires discipline to keep it in sync. E.g. before this commit, converting to `LockMods()` would always try to unlock `CapsLock` due to the wrong value of the `priv` field. Fixed by using the corresponding filter functions directly, so that we always mutate the filter properly, as in `xkb_filter_group_latch_func`. | ||
| 7a7a3b38 | 2024-02-14 09:47:15 | keymap: Canonically map unmapped virtual modifiers Traditionally, *virtual* modifiers were merely name aliases for *real* modifiers (X *core* modifiers), e.g. `NumLock` was usually mapped to `Mod2` (see `modifier_map` statement). Virtual modifiers that were never mapped to a real ones had no effect on the keymap state. xkbcommon already supports the concept of “pure” virtual modifiers, i.e. virtual modifiers that are *encoded* using the full 32-bit range, not just the first 8 bits corresponding to the real modifiers. But until this commit, one had to declare such mapping *explicitly*: e.g. `virtual_modifiers M = 0x100;`. This has at least two drawbacks: - Numerical values may look quite arbitrary and are not user-friendly. It’s OK in the resulting compiled keymap, but it requires careful sync between sections when developing KcCGST files. - If the modifier is *also* mapped *implicitly* using the traditional `vmodmap`/`modifier_map`, then both mappings are OR-combined. This patch enables to automatically map unmapped virtual modifiers to their *canonical* mapping, i.e. themselves: their corresponding virtual and real modifier masks are identical: `1u << mod_index`. Since this feature is incompatible with X11, this is guarded by requiring at least keymap text format **v2**. Note that for now, canonical virtual modifiers cannot be used in an interpret action’s `AnyOf()`. An interpret action for a canonical virtual modifier must be `AnyOfOrNone()` to take effect: virtual_modifiers APureMod, …; interpret a+AnyOfOrNone(all) { virtualModifier= APureMod; action= SetMods(modifiers=APureMod); }; The above adds a virtual modifier `APureMod` for keysym `a`. It will be canonical iff it is not mapped implicitly. | ||
| 69c3d257 | 2025-06-17 16:43:05 | keymap: Add parameter `latchOnPress` for LatchMods() Some keyboard layouts use `ISO_Level3_Latch` or `ISO_Level5_Latch` to define “built-in” dead keys: - they do not rely on the installation of custom Compose file; - they do not clash with other layouts. However, layout projects usually want the exact same behavior on all OS, but the XKB latch behavior (often misunderstood) also acts as a *set* modifier, which is not expected. The usual behavior of a dead key on Linux, macOS and Windows is: - latch on press; - deactivate as soon as another (non-modifier) key is pressed. Added the parameter `latchOnPress` to `LatchMods()` to enable the aforementioned behavior. As it is incompatible with X11, this feature is available only using the keymap text format v2. [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions | ||
| c58c7df1 | 2025-06-17 21:05:08 | Serialize multiple actions per level to VoidAction() in v1 format When using `XKB_KEYMAP_FORMAT_TEXT_V1`, multiple actions per level are now serialized using `VoidAction()`, in order to maintain compatibility with X11. | ||
| 4f2fa718 | 2025-06-17 16:47:20 | dump: Fix typo Fixed copy-paste error. It worked for now, as both struct have the same first fields, but it is obviously semantically incorrect and not future-proof. | ||
| d9d82355 | 2025-06-12 09:13:27 | keymap: Add option `lockOnRelease` for LockGroup() It enables to use e.g. the combination `Control + Shift` *alone* to switch layouts, while keeping the use of `Control + Shift + other key` (typically for keyboard shortcuts). The specification of `LockGroup()` is changed to: - On key *press*: - If `lockOnRelease` is set, then key press has no effect. - Otherwise: - if the `group` is absolute, key press sets the *locked* keyboard group to `group`; - otherwise, key press adds `group` to the *locked* keyboard group. In either case, the resulting *locked* and *effective* group is brought back into range depending on the value of the `GroupsWrap` control for the keyboard. - On key *release*: - If `lockOnRelease` is not set, then key release has no effect. - Otherwise, if any other key was *pressed* after the locking key, then key release has no effect. - Otherwise, it has the same effect than a key press *without* `lockOnRelease` set. This is really useful for people coming from other platforms, such as Windows. It fixes a [20-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [20-year old issue]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/258 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions | ||
| c2896b32 | 2025-06-12 09:16:54 | messages: Add new error "incompatible-keymap-text-format" | ||
| ee50e0c9 | 2025-06-12 20:14:50 | keymap: Add option `unlockOnPress` for LockMods() It enables e.g. to deactivate CapsLock on press rather than on release, as in other platforms such as Windows. The specification of `LockMods()` is changed to: - On key *press*: - If `unlockOnPress` is true and some of the target modifiers were *locked* before the key press, then unlock them if `noUnlock` false. - Otherwise: - add target modifiers to *depressed* modifiers; - if `noLock` is false, add target modifiers to the *locked* modifiers. - On key *release*: - If `unlockOnPress` is true and triggered unlocking on key press, do nothing. - Otherwise: - remove modifiers from the *depressed* modifiers, if no other key that affect the same modifiers is down; - if `noUnlock` is false and if any target modifiers was locked before the key press, *unlock* them. It fixes a [12-year old issue] inherited from the X11 ecosystem, by extending the [XKB protocol key actions]. As it is incompatible with X11, this feature is available only using the keymap text format v2. [12-year old issue]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/312 [XKB protocol key actions]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Key_Actions | ||
| 0106b357 | 2025-06-17 12:06:32 | registry: Add rxkb_option_is_layout_specific() Enable to query if an option accepts layout index specifiers to restrict its application to the corresponding layouts. | ||
| c4c531da | 2025-06-17 11:43:50 | rules: Add layout-specific options for RMLVO builder Change the signature of `xkb_rmlvo_builder_append_layout()` to accept an array of options. Also add tests for layout-specific options. | ||
| fab9d25b | 2025-06-17 11:43:22 | rules: Add support for layout-specific options Enabled specifying a layout index for each option, so that it applies only if the layout matches. The layout index is specified by appending immediately after the option name the `!` specifier delimiter and then the layout index, in decimal form and 1-indexed. Note that `!` was chosen instead of the usual `:` specifier delimiter, because some options contains `:`, e.g. `grp:menu_toggle`. `!` *cannot* clash with component names, because `!` is a token in the rules files and thus cannot be used as in component names. It is also vaguely similar to `:`, compared to e.g. `@` or `#`. Example: given the following rules: ! layout[any] option = symbol * opt1 = +s1:%i l2 opt2 = +s2:%i it may result in the following configurations: | Layout | Option | Symbols | | -------- | -------- | ------------ | | `l1` | `opt1` | `+s1:1` | | `l2` | `opt1` | `+s1:1` | | `l1` | `opt2` | `` | | `l2` | `opt2` | `+s2:1` | | `l1,l2` | `opt1` | `+s1:1+s1:2` | | `l1,l2` | `opt1!1` | `+s1:1` | | `l1,l2` | `opt1!2` | `+s1:2` | | `l1,l2` | `opt2` | `+s2:2` | | `l1,l2` | `opt2!1` | `` | | `l1,l2` | `opt2!2` | `+s2:2` | | ||
| 52a4d9b0 | 2025-06-17 11:03:12 | rules: Require layout or variant to enable %i expansion Before this commit, the following rule would always match: ! model = symbols * = s:%i and set symbols to `s:1`, but the `:%i` is aimed to be used only when the rules header specifies the layout or the variant. Let’s be strict and disallow matching this kind of buggy rule. Emit an error message so that we can detect it. | ||
| ef6a550f | 2025-06-16 15:48:25 | Add xkb_keymap_new_from_rmlvo() Use the new RMLVO builder API to compile keymaps. | ||
| da5caabb | 2025-06-16 15:45:42 | Add RMLVO builder API Before this commit, the API to work with RMLVO was quite minimal: it only uses raw strings from the `xkb_rule_names` struct. However: - it forces the users to deal with error-prone string formatting; - it does not enforce tying together layouts and variants; - it limits adding new features by requiring defining delimiter characters and the corresponding parsing. Added the following API: - `xkb_rmlvo_builder_new()` - `xkb_rmlvo_builder_append_layout()` - `xkb_rmlvo_builder_append_option()` - `xkb_rmlvo_builder_unref()` There is no intermediate `layout` nor `option` object, in order to to keep the API simple. The only foreseen extension is enabling configuring layout-specific options. | ||
| 2906c7ec | 2025-06-14 13:19:41 | rules: Fix parsing group index There was a typo that made parsing hexadecimal instead of the expected decimal format. | ||
| 80b8d9d1 | 2025-06-10 17:34:15 | dump: Adapt groups count to keymap format | ||
| 62fe73cb | 2025-06-10 17:33:14 | parser: Raise the layout limit to 32 | ||
| 2535a3f9 | 2025-06-11 15:55:25 | rules: Convert macros into enums & inline functions This provides semantics and better type-check. | ||
| 9f3078eb | 2025-06-10 15:46:31 | dump: Use explicit format | ||
| 0f89ad97 | 2025-06-09 19:26:13 | dump: Always use numeric group indexes The upcoming raise of the maximum groups count will require to use numeric group indexes instead of the syntax `GroupN` if groups > 8. Let’s not bother with handling two cases (group count ≤ 8 or > 8) and always serialize group indexes as numeric values. | ||
| 44c8deb2 | 2025-05-07 10:20:25 | Introduce keymap format v2 and make it the default for parsing - Added `XKB_KEYMAP_FORMAT_TEXT_V2`. - Made `xkb_keymap_new_from_names()` use the new keymap format. - Made the tools default to the new keymap format for input. This is in preparation for changes in the parsing & state handling. For now it changes nothing. | ||
| 08149dae | 2025-05-06 16:23:04 | Add internal API to query and parse supported keymap formats | ||
| 1a10f858 | 2025-05-06 18:05:06 | Add xkb_keymap_new_from_names2 This is just `xkb_keymap_new_from_names()` with an explicit keymap format. | ||
| 16c079d6 | 2025-06-06 20:27:45 | chore: Rename is_absolute to is_absolute_path | ||
| 39b4b670 | 2025-06-06 18:40:29 | Support including keymap components using %-expansion and absolute path Enable to use the same `include` features than *rules* files in *keymap components*: - *`%`-expansion*: `%H` home directory, `%S` sytem root and `%E` extra. - absolute file paths. This is useful if one wants to overwrite the system file with a user config (i.e. same name, but in `~/.config/xkb`), but still include the system file: ``` // File: ~/.config/xkb/symbols/de xkb_symbols "basic" { include "%S/de(basic)" key <AB01> { [z, Z] }; key <AD06> { [y, Y] }; } ```` Without the commit, using a mere `include "de(basic)"` would result in an include loop. Refactored by using the same code for rules and keymap components. | ||
| 324984f1 | 2025-05-17 06:49:49 | xkbcomp: Fix log for unknown default field | ||
| e9394b9f | 2025-05-13 10:47:22 | utils: Use explicit cast to prevent warnings | ||
| fb9fec18 | 2025-05-10 10:18:38 | xkbcomp: Checked arithmetic Use a polyfill for C23 checked arithmetic. This is a bit paranoid, as we expect the user to use only 32 bit integers, so the signed 64 bit integer we use to store the result should be more than enough. Use jtckdint v1.0: - repository: https://github.com/jart/jtckdint - commit: 339450d13d8636f05dcb71ba36efddb226db481e - removed all C++-specific code | ||
| 7a2aa9c9 | 2024-12-20 22:53:11 | Always retain later Compose sequence in case of conflict This ensures that it is always possible to override previous definitions, for example when `include`ing the system Compose file. Signed-off-by: Jules Bertholet <julesbertholet@quoi.xyz> | ||
| 3a8bb1a1 | 2025-05-16 13:13:55 | compose: Fix sequence not fully overriden Previously if a new sequence did not produce a keysym or a string, the corresponding property was not overriden, possibly leaking the previous entry. - Fixed by always writting all the properties. - Also try to reuse the previous string entry, if possible, so that we avoid allocating. | ||
| 556d00a0 | 2025-05-12 17:52:12 | keymap: Ensure proper type for layouts count | ||
| 3bfc1bc1 | 2025-05-12 18:52:05 | misc: Ensure proper type for darray size | ||
| 1d361b8f | 2025-05-12 10:01:10 | scanner: Ensure proper type for string length | ||
| 13e7114d | 2025-05-12 09:08:49 | rules: Ensure proper type of MLVO and KcCGST indexes | ||
| ac2aa2df | 2025-05-12 07:47:03 | keymap: Ensure proper type for LEDs count | ||
| 903c16da | 2025-05-12 07:42:32 | keymap: Ensure proper type for key types counts | ||
| c3953a96 | 2025-05-12 07:37:29 | keymap: Ensure proper type for key codes aliases | ||
| 2617ebc5 | 2025-05-12 07:32:04 | keymap: Ensure proper type for modifiers count | ||
| 41bb797d | 2025-05-12 07:31:33 | symbols: Ensure proper type for keysyms count | ||
| f7c94bfc | 2025-05-12 07:08:11 | symbols: Ensure proper type for levels count | ||
| 2f4d30c2 | 2025-05-12 07:07:50 | context: Ensure proper type for include paths count | ||
| 10457563 | 2025-05-12 06:41:28 | keymap: Ensure proper type for actions count | ||
| 3911f786 | 2025-05-12 07:06:42 | keymap: Ensure proper type for num_sym_interprets | ||
| 8f5270c0 | 2025-05-12 07:07:57 | utils: Improve darray - Introduce `darray_size_t` - Document struct fields: the `alloc` field may be particularly confusing | ||
| 61d8ec67 | 2025-05-12 18:20:47 | misc: Fix string format specifiers Ensure better portability. | ||
| 3031f6c3 | 2025-05-12 10:38:15 | misc: Always use `unsigned` with `int` Better semantics & facilitate search. | ||
| 01742b77 | 2025-05-12 20:40:59 | misc: Ensure explicit conversion in gperf code | ||
| 9951184e | 2025-05-10 10:15:54 | actions: Properly reset type to NoAction on error If we do not reset the type, the action may lready have been initialized to with a default action and thus will not be ignored. | ||
| 22d27277 | 2025-05-10 10:12:31 | actions: Reject arguments if they are not expected `NoAction`, `VoidAction` and `TerminateServer` do not accept arguments. | ||
| d239a3f0 | 2025-05-11 11:42:20 | actions: Improve unsupported legacy X11 actions handling - Display a warning - Document drawbacks of degrading to `NoAction()` | ||
| 137c5e90 | 2025-05-11 12:37:23 | actions: Improve unknown action logging | ||
| b4c89600 | 2025-05-09 15:15:10 | actions: Add VoidAction(), mirroring NoSymbol/VoidSymbol. Added `VoidAction()` action to match the keysym pair `NoSymbol` / `VoidSymbol`. It enables overriding a previous action and breaks latches. This is a libxkbcommon extension. When serializing it will be converted to `LockControls(controls=none,affect=neither)` for backward compatibility. We cannot serialize it to `NoAction()`, as it would be dropped in e.g. the context of multiple actions. | ||
| 845d2fee | 2025-05-09 16:45:36 | xkbcomp: Fix affect field wrongly accepted in SetControls() action | ||
| 551cca2a | 2024-12-03 10:12:03 | state: Add server API for updating latched and locked mods & layout Up to now, the “server state” `xkb_state` API only offered one entry point to update the server state – `xkb_state_update_key`, which reflects the direct keyboard keys state. But some updates come out-of-band from keyboard input events stream, for example, a GUI layout switcher. The X11 XKB protocol has a request which allows for such updates, `XkbLatchLockState`[^1], but xkbcommon does not have similar functionality. So server applications ended up using `xkb_state_update_state` for this, but that’s a function intended for client applications, not servers. Add support for updating the latched & locked state of the mods and layout. Note that the depressed states cannot be updated in this way -- XKB does not expect them to be updated out of band. [^1]: https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Querying_and_Changing_Keyboard_State Fixes: #310 Signed-off-by: Ran Benita <ran@unusedvar.com> Co-authored-by: Ran Benita <ran@unusedvar.com> Co-authored-by: Pierre Le Marre <dev@wismill.eu> | ||
| 662ce937 | 2024-12-03 10:09:10 | state: Avoid keycode lookup when key ref is available | ||
| 7cd1180b | 2025-05-06 11:07:47 | modifiers: Add xkb_keymap_mod_get_mask() Added a dedicated API to query modifier masks rather than relying on a hack using `xkb_state_update_mask` and `xkb_state_serialize_mods`. Furthermore, this hack may not work in the future if we remove virtual mods resolution in `xkb_state_update_mask` to avoid corner-cases issues. | ||
| a3f1a9d3 | 2025-02-04 20:45:38 | xkbcomp/parser: enable Bison detailed syntax error It's not much, but instead of xkbcommon: ERROR: [XKB-769] (unknown file):5:25: syntax error we get xkbcommon: ERROR: [XKB-769] (unknown file):5:25: syntax error, unexpected +, expecting INTEGER which is at least a little helpful. Signed-off-by: Ran Benita <ran@unusedvar.com> | ||
| e6aec067 | 2025-04-29 17:14:01 | build: drop support for byacc It doesn't support `%define parse.error detailed` which we want to use. If needed, we can probably bring back support using some macro hackery. Signed-off-by: Ran Benita <ran@unusedvar.com> | ||
| c2d3694b | 2025-05-06 07:01:01 | xkbcomp: Do not discard extra bits in vmod masks Since we accept numeric values for the vmod mask in the keymap, we may have extra bits set that encode *no* real/virtual modifier. Keep them unchanged for consistency. E.g. the following keymap: xkb_keymap { xkb_keycodes { <a> = 38; }; xkb_symbols { virtual_modifiers X = 0xf0000000; key <a> { [ SetMods(mods = 0x00001100) ] }; }; }; would compile to: xkb_keymap { xkb_keycodes { <a> = 38; }; xkb_symbols { virtual_modifiers X = 0xf0000000; // Internal state key <a> { [ SetMods(mods = 0xf0001000) ] }; // Serialization key <a> { [ SetMods(mods = 0x00001100) ] }; }; }; | ||
| dddffd51 | 2025-05-05 13:22:57 | state: Fix virtual modifiers with non-real mod mapping Currently there are 2 issues with the handling of virtual modifiers in the keyboard state: 1. We assume that the input modifiers masks encode the indexes of all the modifiers of the keymap, but this is true only for the *real* modifiers (at least in xkbcommon and X11). Indeed, since the virtual modifiers *indexes* are implementation-specific, the input modifier masks merely *encode* the modifiers via their *mapping*. Consider the following keymap: ```c xkb_keymap { xkb_compat { virtual_modifiers M1 = 0x100; }; xkb_types { virtual_modifiers M2 = 0x200; }; }; ``` Now to illustrate, consider the following 2 implementation variants of libxkbcommon (assuming indexes 0-7 are the usual real modifiers): 1. Process `xkb_compat` then `xkb_types`. M1 and M2 have the respective indexes 8 and 9 and map to themselves (with the current assumption about mask denotation). 2. Process `xkb_types` then `xkb_compat`. M1 and M2 have the respective indexes 9 and 8 and map to each other. With the current `xkb_state_update_mask`, implementation 2 will swap M1 and M2 (compared to impl. 1) at each update! Indeed, we can see that `xkb_state_serialize_mods` doesn’t roundtrip via `xkb_state_update_mask`. 2. We assume that modifier masks use only bits denoting modifiers in the keymap, but when parsing the keymap we accept explicit virtual modifiers mapping of arbitrary values. E.g. if `M1` is the only virtual modifier and it is defined by: ```c virtual_modifiers M1 = 0x80000000; // 1 << (32 - 1) ``` then the 32th bit of a modifier mask input does *not* denote the 32th virtual modifier of the keymap, but merely the encoding of the mapping of `M1`. So when calling `xkb_state_update_mask`, we may discard some bits of the modifiers masks and end up with an incorrect state. These 2 issues may break interoperability with other implementations of XKB (e.g. kbvm) and make pure virtual modifiers handling fragile. We introduce the notion of *canonical state modifier mask*: the mask with the smallest population count that denotes all bits used to encode the modifiers in the keyboard state. It is equal to the bitwise OR of real modifiers mask and all the virtual modifiers mappings. This commit fixes the 2 issues by making *weaker* assumptions about the input modifier masks: 1. Modifiers may map to arbitrary values, not only real modifiers. 2. Input modifier masks merely encode modifiers via their *mapping*: - *real* modifiers map to themselves; - *virtual* modifiers map to the bitwise OR of their *explicit* mapping (via `virtual_modifiers`) and their *implicit* mapping (via keys’ real and virtual modmaps). - modifiers indexes are implementation-specific. Since the implementation before this commit also resolved virtual modifiers to their mappings, we continue doing so, but using only the bits that are *not* set in the canonical state modifier mask, so that we enable roundtrip of `xkb_state_serialize_mods` via `xkb_state_update_mask`. 3. Input modifier masks do not denote modifiers indexes (apart from real modifiers), so it is safe to discard only the bits that are not set in the canonical state modifier mask. | ||
| d5b779e1 | 2025-05-06 21:07:28 | keymap: Fix empty compat interpretation map serialization X11’s `xkbcomp` requires at least one compat interpretation entry. | ||
| 87f9ac76 | 2025-05-06 21:02:23 | keymap: Fix empty compat interpretation statement serialization Statements such as `interpret VoidSymbol {};` can cannot be parsed by X11’s `xkbcomp`. Fixed by using a dummy action. | ||
| 230b6a6a | 2025-05-06 14:35:26 | Fix key type map entry with unbound vmod not ignored Currently we only ignore key type map entries with non-zero mods and with a zero modifier mask. However, the XKB protocol states ([source]): > Map entries which specify unbound virtual modifiers are not considered. So we currently handle `map[Unbound]` key type map entries (all modifiers unbound) but not `map[Bound+Unbound]` entries (mix of bound and unbound modifiers). Fixed by properly checking unbound modifiers on each key type map entry. This also fixes a test that was accidentally passing. [source]: https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#:~:text=Map%20entries%20which%20specify%20unbound%20virtual%20modifiers,not%20considered | ||
| f8148744 | 2025-05-06 11:26:21 | Define the mapping of real modifiers explicitly When querying for a modifier mapping, we should treat all modifiers equally. So simply store real modifier mapping as we do for the virtual ones. Also fixed useless boolean conversions. | ||
| e1aca42e | 2025-05-05 12:06:18 | state: Minor refactor - Move variable declaration close to their use. - Make them constant whenever possible. | ||
| 8bc60ee3 | 2025-05-05 13:20:45 | modifiers: Minor optimization It has low impact, but it also adds better semantics. | ||
| cd512b8f | 2025-05-02 19:21:09 | x11: Fix capitalization transformation | ||
| 411e9a6f | 2025-04-28 06:56:19 | ExprKeySym: add comment about error recovery | ||
| 76683d92 | 2025-04-29 11:37:46 | symbols: Fix clang-tidy false positive | ||
| 95c5c859 | 2025-03-25 05:50:02 | xkbcomp: Quote erroneous field in logging | ||
| d66a65c2 | 2025-03-20 17:34:07 | xkbcomp: Consistent keycodes logging | ||
| 9b0b8c68 | 2025-04-15 19:53:28 | xkbcomp: Stricter handling of default map include Before this commit, including a *default* map, i.e. without an explicit section name (e.g. `include "au"` vs `include "au(basic)"`) would match the first section of the first matching file in the XKB include paths, even if this section is not an *explicit* default map (i.e. tagged with `default`) but an *implicit* default map (i.e. the first map of the file, i.e. a weak match). It makes user configuration risky: say a user wants to create a custom version `au(custom)` of the `au` layout: - `./config/xkb/symbols/au`: custom layout in section “custom”. - `/usr/share/X11/xkb/symbols/au`: system layout, with *default* section “basic”. In this setup *any* layout that imports the default map from `au` would in fact import the *implicit* default map `au(custom)` instead of the *explicit* default map `au(basic)`. This incorrect behavior may thus break setups with multiple layouts. This is especially true for symbols files such as: `pc`, `us` or `latin`. Fixed by trying harder to found the exact default map, defaulting to the old behavior (weak match) only if no *explicit* default map (exact match) has been found in the XKB include paths. | ||
| 9ede705b | 2025-04-13 09:50:18 | state: Capitalization transformation in xkb_state_key_get_syms Previously `xkb_state_key_get_syms()` did not perform capitalization tranformation, while `xkb_state_key_get_one_sym()` does perform it. This is unfortunate if we want to promote the use of multiple keysyms per levels. The API make it difficult to change now though: we return a pointer to an immutable array rather than filling a buffer. While we could use an internal buffer in `xkb_state`, this option would limit the API to *sequential* calls of `xkb_state_key_get_syms()` or require some buffer handling (e.g. rotation). Instead we now store the capitalization directly in `xkb_level`. We modified `xkb_level` like so (see below for discussion about the size): ```diff struct xkb_level { - unsigned int num_syms; + uint16_t num_syms; - unsigned int num_actions; + uint16_t num_actions; + union { + /** num_syms == 1: Upper keysym */ + xkb_keysym_t upper; + /** num_syms > 1: Indicate if `syms` contains the upper case + * keysyms after the lower ones. */ + bool has_upper; + }; union { xkb_keysym_t sym; /* num_syms == 1 */ xkb_keysym_t *syms; /* num_syms > 1 */ } s; union { union xkb_action action; /* num_actions == 1 */ union xkb_action *actions; /* num_actions > 1 */ } a; }; ``` - When `level.num_syms` <= 1, we store the upper keysym in `level.upper`. - Else if there no cased syms, we set `level.has_upper` to false. - Else if there are some cased syms, we set `level.has_upper`` to `true` and we double the original size of `level.s.syms`, but *without* modifying `level.num_syms`. We then append the transformed keysyms right after the original ones, so that we can access them by a simple pointer operation: `level.s.syms + level.num_syms`. The memory footprint is *unchanged*, thanks to the reduced fields for actions and keysyms counts. | ||
| 9e93e5e5 | 2025-04-13 10:25:02 | symbols: Restrict the number of actions and keysyms per level In preparation to support capitalization in `xkb_state_key_get_syms()`, this commit reduces the number of supported actions and keysyms per level, going from UINT_MAX to UINT16_MAX. This is most likely still more than enough and could be even reduced further, but deemed unnecessary at the moment: alignment of `struct xkb_level` is driven by the fields `a` and `s`. - Switched the item count type from `unsigned int` to `uint16_t`. - Introduced `xkb_{action,keysym}_count_t` type for the respective item count for exact typing. - Added relevant bounds checks. | ||
| 44bcdb73 | 2025-04-13 10:24:13 | symbols: Avoid keysyms allocation by stealing darray | ||
| 53d80b87 | 2025-03-20 15:29:17 | xkbcomp: Safer keycode max_key_code Since we now always keep the keycodes array at the minimal dimensions, `max_key_code` is redundant and error prone. Let’s use `darray_size` directly. | ||
| 256be1ea | 2025-03-25 08:13:21 | xkbcomp: Fix merge mode for defaults actions - Keep defaults local: do not share accross includes. - Do not allocate default actions. | ||
| b1865376 | 2025-03-25 07:46:11 | xkbcomp: Fix merge mode for defaults in symbols |