src


Log

Author Commit Date CI Message
Julian Orth cb3565b1 2025-03-07T17:59:33 keymap: Fix segfault due to invalid group wrapping The modular arithmetic is incorrect for negative values, e.g. for num_groups = 1. It triggers a segfault for the following settings: - layouts count (per key or total) N: `N > 0`, and - layout index n: `n = - k * N` (`k > 0`) % returns the *remainder* of the division, not the modulus (see C11 standard 6.5.5 “Multiplicative operators”: a % b = a - (a/b)*b. While both operators return the same result for positive operands, they do not for e.g. a negative dividend: remainder may be negative (in the open interval ]-num_groups, num_groups[) while the modulus is always positive. So if the remainder is negative, we must add `num_groups` to get the modulus. Fixes: 67b03cea ("state: correctly wrap state->locked_group and ->group") Signed-off-by: Julian Orth <ju.orth@gmail.com> Co-authored-by: Julian Orth <ju.orth@gmail.com> Co-authored-by: Pierre Le Marre <dev@wismill.eu>
Pierre Le Marre e1892266 2025-02-13T16:57:46 clang-tidy: Miscellaneous fixes
Pierre Le Marre 5ef19bcf 2025-02-13T17:58:21 xkbcomp: Fix incorrect memory comparison Spotted by clang-tidy: ``` ../src/keymap-priv.c:146:16: warning: comparing object representation of type 'union xkb_action' which does not have a unique object representation; consider comparing the members of the object manually [bugprone-suspicious-memory-comparison] ```` Indeed, from “EXP42-C. Do not compare padding data”[^1]: > unnamed members of objects of structure and union type do not participate > in initialization. Unnamed members of structure objects have indeterminate > representation even after initialization. Fixed by using a dedicated comparison function for `union xkb_action`. [^1]: https://wiki.sei.cmu.edu/confluence/display/c/EXP42-C.+Do+not+compare+padding+data
Pierre Le Marre e3108182 2025-02-12T09:49:25 Fix int casts related to layout index - XkbWrapGroupIntoRange - State
Pierre Le Marre 14a816e5 2025-02-11T18:41:08 xkbcomp: Fix int cast
Pierre Le Marre 6c9806ae 2025-02-12T07:46:07 xkbcomp: Fix ExprResolveMaskLookup error message
Pierre Le Marre 558447d8 2025-02-11T17:34:27 xkbcomp: Explicit vars initialization The `Resolve*` functions do not always initialize the parameters that they can modify, so it is safer to always initialize them at the call site.
Pierre Le Marre 97698fca 2025-02-11T17:34:23 xkbcomp: Use explicit int sizes for Expr resolution
Pierre Le Marre 2d94da3d 2025-02-11T17:34:15 xkbcomp: Fix the int type of ExprInteger Avoid implicit conversion from `int64_t`.
Pierre Le Marre 350931ad 2025-02-12T14:20:58 xkbcomp: Fix compat group index
Pierre Le Marre f2dd0302 2025-02-12T14:15:26 xkbcomp: Fix LED index int type
Pierre Le Marre 2d111bbe 2025-02-12T13:54:51 xkbcomp: Fix possible overflow in numbers parser
Pierre Le Marre a4038a47 2025-02-12T09:50:36 Miscellaneous int types fixes
Pierre Le Marre 3a0b77f0 2025-02-12T16:41:09 xkbcomp: Fix parser headers
Pierre Le Marre 16e3e3cb 2025-02-12T16:12:42 utils: Fix missing headers
Pierre Le Marre ce9bcbe0 2025-02-07T16:31:37 scripts: Rename keysyms-related files Previous names were too generic. Fixed by using explicit names and add the `.py` file extension.
Ran Benita bb5e464e 2025-02-07T14:30:51 xkbcomp/expr: remove comment on ExprResolveIntegerLookup What it says mostly no longer holds, I think it's more confusing than helpful now. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita aa3e4c71 2025-02-07T14:10:16 xkbcomp/expr: remove unused ExprResolveKeyCode This function was added in commit 4e22851141d89436c0659e68da57e91bbf971461. But that commit also changed the grammar: -KeyNameDecl : KeyName EQUALS Expr SEMI +KeyNameDecl : KeyName EQUALS KeyCode SEMI i.e. while before you could write <AE01> = 9+1; now this is a syntax error, an integer literal is expected. I'm not sure if it was intended to remove this ability. In any case, this rendered `ExprResolveKeyCode` useless since there's no longer an expression to evaluate, and after some refactoring it went unused. Even if we choose to restore Expr here, I don't see a reason for the specialized function over `ExprResolveInteger` except the type (which we should probably widen from int to int64_t...). So remove it. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 9d7eb849 2025-02-06T15:25:03 xkbcomp/ast: combine expr_value_type into stmt_type This field is a funky attempt at type inference, or perhaps some optimization? Anyway, after careful examination I conclude it serves no purpose except specifying the type of a literal (string/integer/float/boolean/keyname) when `STMT_EXPR_VALUE` (i.e. literal). Remove it and replace `STMT_EXPR_VALUE` with specific statement types for each literal type. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita d9fc01b3 2025-02-06T15:12:53 xkbcomp/ast: combine expr_op_type into stmt_type It's better to have a single AST type enum. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 635c48f8 2025-02-06T14:47:15 xkbcomp: remove unused EXPR_TYPE_ACTION Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita a4d782c7 2025-02-06T16:00:19 xkbcomp/ast: remove ExprCommon It's now empty and no longer serves a purpose. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita a5c2c746 2025-02-06T12:27:25 Fix a few direct modifications to generated files Accidentally modified generated files in a couple of recent changes. Sync the templates. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita f4e95280 2025-02-02T22:29:05 xkbcomp/scanner: avoid unneeded strdup of IDENT tokens The allocation is immediately discarded, either turned into a keysym or an atom. So use an sval slice into the input string instead strdup'ing. memusage ./release/bench-compile-keymap --iter=1000 --layout us,de --variant ,neo Before: Memory usage summary: heap total: 534063576, heap peak: 581022, stack peak: 18848 total calls total memory failed calls malloc| 11240525 291897104 0 realloc| 1447657 192307328 0 (nomove:37629, dec:0, free:0) calloc| 430573 49859144 0 free| 13993903 534063576 After: Memory usage summary: heap total: 506839909, heap peak: 581022, stack peak: 18960 total calls total memory failed calls malloc| 8016419 264673437 0 realloc| 1447657 192307328 0 (nomove:37278, dec:0, free:0) calloc| 430573 49859144 0 free| 10769797 506839909 Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 113ac304 2025-01-25T03:18:01 meson: link tests and benches against shared library, not static library This makes the tests, and especially benches, more realistic, since xkbcommon is almost always used as a shared library. Also significantly reduces the build time with LTO enabled (for me, from 90s to 30s). Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita a380ba52 2025-01-25T07:00:43 Move XKB_EXPORT to headers The Windows dllexport annotation wants to be on the declarations, not the definitions. Signed-off-by: Ran Benita <ran@unusedvar.com>
Pierre Le Marre c051d0ae 2025-02-05T14:09:17 Replace include guards by `#pragma once` (again) Follow-up of df2322d70cb0922f67c41db639a5c70733b4ce66.
Ran Benita df2322d7 2025-02-05T14:41:21 Replace include guards by `#pragma once` We currently have a mix of include headers, pragma once and some missing. pragma once is not standard but is widely supported, and we already use it with no issues, so I'd say it's not a problem. Let's convert all headers to pragma once to avoid the annoying include guards. The public headers are *not* converted. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita d75702ba 2025-01-25T06:14:55 utils: remove ifdefs for some ancient or obscure compilers If someone needs this, they can let us know... Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 02456c14 2025-02-02T21:51:20 xkbcomp/keymap: avoid some allocations in ApplyInterpsToKey Reuse the darray. memusage ./release/bench-compile-keymap --iter=1000 --layout us,de --variant ,neo Before: Memory usage summary: heap total: 552866360, heap peak: 581022, stack peak: 18848 total calls total memory failed calls realloc| 2035244 211110112 0 (nomove:37629, dec:0, free:0) After: Memory usage summary: heap total: 534063576, heap peak: 581022, stack peak: 18848 total calls total memory failed calls realloc| 1447657 192307328 0 (nomove:37629, dec:0, free:0) Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 7e84c845 2025-02-01T17:04:33 xkbcomp/scanner: avoid extra copies for keynames, keywords, identifiers The tokens don't have escapes so no need to use the `buf` for them. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 43f6036d 2025-02-01T16:34:00 xkbcomp/keywords: don't require C string for keyword lookup Needed for next commit, but good regardless. No noticeable effect on performance. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita e120807b 2025-01-29T15:35:22 Update license notices to SDPX short identifiers + update LICENSE Fix #628. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 1f436703 2025-01-24T23:04:43 xkbcomp: rework KeysymList AST representation This is similar to the previous commit, for keysym lists. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 39689867 2025-01-24T22:43:45 xkbcomp: rework ActionList AST representation The AST is heavily based on intrusive lists for representing lists, but actions are an exception, instead using darray. I don't see any reason for this; it ends up allocating more, and we don't especially need a flat array for this. Change it to use the familiar linked-list style. Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 6e97f57e 2025-01-29T19:21:43 scanner: speed up token position -> location using a cache Signed-off-by: Ran Benita <ran@unusedvar.com>
Ran Benita 26807a90 2025-01-28T20:24:05 scanner: compute token line/column lazily on errors The scanner functions are hot, and the line/column location tracking is quite expensive. We only use it for errors, which don't need to be fast, because we bail if there are too many; and for warnings, which are usually not shown by default. So only keep the token start pos, and compute the line/column lazily from that. This will also allow some further improvements ahead. bench/rulescomp before: compiled 1000 keymaps in 1.669028s after: compiled 1000 keymaps in 1.550411s bench/compose: before: compiled 1000 compose tables in 2.145217s after: compiled 1000 compose tables in 2.016044s Signed-off-by: Ran Benita <ran@unusedvar.com>
Pierre Le Marre 3249223f 2025-01-30T07:58:20 test: Add check for keymap and compose compilation logs
Pierre Le Marre 502e9e5b 2025-01-29T12:19:10 xkbcomp: Add stricter bounds for keycodes and levels Our current implementation uses continuous arrays indexed by keycodes and levels. This is simple and good enough for realistic keymaps. However, they are allowed to have big values that will lead to either memory exhaustion or a waste of memory (sparse arrays). Added the much stricter upper bounds `0xfff` for keycodes[^1] and 2048 for levels[^2], which should still be plenty enough and provides stronger memory security. [^1]: Current max keycode is 0x2ff in Linux. [^2]: Should be big enough to satisfy automatically generated keymaps.
Pierre Le Marre c85c9bdc 2025-01-27T17:15:06 symbols: Allow levels with different keysyms and actions counts Contrary to groups, there is no reason for levels to restrict the same count of keysyms and actions.
Pierre Le Marre 27ac30b2 2025-01-27T17:13:44 symbols: Normalize levels by dropping NoSymbol & NoAction
Pierre Le Marre af5704dc 2025-01-25T11:01:03 state: Fix empty level not breaking latches In essence empty levels are levels with just a `NoSymbol` keysym and a `NoAction()`, which breaks latches. Fixed regression introduced in fdf2c525977e7e8af4135d593110f5bc1454abd8. Added tests also for the case where the keycode is unknown.
Pierre Le Marre 4ac22263 2025-01-16T23:22:40 keysyms: Check clashes between keysyms names and keywords Due to how our parser is implemented, keysyms names that are also valid keywords require special handling. Added a check for these clashes in the keysym generator. The only current clash, `section`, is already handled. Note that it means that e.g. `section`, `Section` and `sEcTiOn` all parse to the same keysym. This side effect is fine here, because *currently* there is no other keysym that clashes with any possible of the case variation of `section`. But in order to be extra cautious, we now test thoses clashes too. Hopefully we will never have a clash again, but while it is unlikely that we modify the keywords, the keysyms are not a frozen set.
Pierre Le Marre 7c124fd9 2025-01-22T17:20:04 rules: Fix incrementing a variable in a complex condition
Pierre Le Marre 818b1b6b 2025-01-22T17:19:41 symbols: Simplify GetGroupIndex call
Pierre Le Marre a2c9b6b4 2025-01-22T16:57:54 x11: Make assumption explicit
Pierre Le Marre fc3c8cfd 2025-01-22T16:56:45 Replace STATIC_INSERT with official C11 static_assert
Pierre Le Marre 3ee08251 2025-01-22T16:50:19 clang-tidy: Fix possible leak
Pierre Le Marre 357ab0cb 2025-01-23T16:42:30 clang-tidy: Fix missing default case in switch statement
Pierre Le Marre 842497d9 2025-01-22T16:46:11 clang-tidy: Fix implicit or incorrect integer casts
Pierre Le Marre 5389a31e 2025-01-22T17:33:03 clang-tidy: Use memcpy instead of the insecure strcpy
Pierre Le Marre 53b3f446 2025-01-22T17:43:53 clang-tidy: Fix headers includes
Pierre Le Marre 0c940827 2025-01-22T16:39:35 clang-tidy: Macro arguments should be enclosed in parentheses
Pierre Le Marre b1e1aae6 2025-01-23T15:20:44 xkbcomp: Fix memory leak when extra content after keymap It triggers with e.g.: ``` xkb_keymap { xkb_keycodes { }; }; }; // erroneous ```
Pierre Le Marre 709027ec 2025-01-23T09:12:15 symbols: Fix inconsistent error handling Currently the following keymap triggers a critical error (invalid `vmods`) only for the second key statement, while it should handle both equally. ``` xkb_keymap { xkb_keycodes { <> = 9; }; xkb_types { }; xkb_compat { }; xkb_symbols { key <> { vmods = [], repeats = false }; key <> { repeats = false, vmods = [] }; }; }; ``` Fixed by parsing the whole symbols body and failing if any error was found.
Pierre Le Marre ec2915fe 2025-01-22T17:18:21 symbols: Fix a possible null pointer deference Introduce a new Expression type, `EXPR_EMPTY_LIST`, to avoid the ambiguity between action and keysym empty lists. Two alternatives were rejected to keep the semantics clear: - Using `EXPR_KEYSYM_LIST`: because we would end up accepting an empty keysym list while processing actions. - Using NULL: convey no info and is hazardous.
Pierre Le Marre 9b7466cf 2025-01-21T16:02:55 atom: Fix missing return value in atom_intern Ensure all control paths return a value.
Pierre Le Marre 425dc634 2025-01-21T15:40:33 Fix some implicit integers casts
Pierre Le Marre 9ef45dc5 2025-01-21T19:55:47 Fix incompatible pointer types with enums The enum casts can possibly lead to unaligned access. The warnings trigger in the Windows CI but not on Linux. One may use `-fshort-enums` with gcc in order to trigger the errors.
Pierre Le Marre b1aecd47 2025-01-21T17:51:56 actions: Fix SwitchScreen screen value range Currently we accept values of -255..255 while parsing the screen value of `SwitchScreen` actions`, but then we silently cast it against `int8_t`, i.e. in range -128..127. We actually do as xkbcomp, but this seems a bug because the target storage is a `char`. Let’s simply raise a parse error if the value does not fit in our type.
Ran Benita 26069b76 2025-01-21T10:48:28 xkbcomp/parser: silence a set but unused warning ``` libxkbcommon.so.0.7.0.p/parser.c:1632:9: warning: variable '_xkbcommon_nerrs' set but not used [-Wunused-but-set-variable] 1632 | int yynerrs = 0; ``` Signed-off-by: Ran Benita <ran@unusedvar.com>
Pierre Le Marre db5e6d30 2025-01-21T11:35:57 registry: Refactor to avoid hazardous casts Inline `rxkb_object_unref` for each type and remove the `destroy` field.
Pierre Le Marre c0762c49 2025-01-20T16:33:50 keymap: Fix buffer unnecessary written twice When dumping the keymap, we first try to write to the buffer and get the min size requirement. Then we reallocate if necessary. However, we should not write it again if we got enough space previously!
Pierre Le Marre 24fe4bac 2025-01-20T16:31:44 Fix undefined behaviours with NULL pointer Issues detected by the sanitizers: - fix indexing NULL pointer - fix zero offset to NULL pointer
Pierre Le Marre 8d0df44a 2025-01-15T19:11:58 text: Ensure mod mask can always be printed entirely
Pierre Le Marre b0d9a790 2025-01-15T12:03:10 vmods: Fix explicit vmods not dumped
Pierre Le Marre c7fdf506 2025-01-16T20:23:28 Use portable integer literal suffixes
Pierre Le Marre e3e44998 2025-01-16T20:23:47 Fix missing or incorrect integer literal suffixes The correct suffix is required in order to have the expected value in a portable way.
Jules Bertholet 3fdd822d 2025-01-16T02:21:29 state: Fix mods not being independently cleared (#584) The modifiers filters should ensure minimal interaction between them, but currently the Latch mod filters are overzealous and mess with the mods from other filters set to be cleared, resulting in some modifiers permanently set. Fixed by clearing mods properly with `OR` rather than direct setting of `state::clear_mods`. While we are at it, `state::set_mods` should be `OR`ed as well. This should not have any impact for now, but this is more future-proof. Fixes #583 Co-authored-by: Jules Bertholet <julesbertholet@quoi.xyz> Co-authored-by: Pierre Le Marre <dev@wismill.eu>
Pierre Le Marre dfa286b2 2025-01-15T13:56:36 compat: Fix Interp & LED merge modes
Pierre Le Marre d43bb955 2024-12-19T18:21:01 symbols: Fix key symbols/actions merge - Fixed field for defined keysyms/actions - Fixed regression introduced by fdf2c525977e7e8af4135d593110f5bc1454abd8
Pierre Le Marre 6c6dbf32 2025-01-07T11:19:30 state: Fix LatchGroup action with latchToLock disabled A `LatchGroup` action with the `latchToLock`` option disabled can apply its latch effect multiple times.
Pierre Le Marre 325ba10e 2025-01-07T16:27:50 state: Fix LEDs driven by the group state When the indicator field `whichGroupState` is set to `Base` or `Latched`, the group masks should be considered only as boolean values as per the XKB specification.
Pierre Le Marre 93b75c63 2024-12-22T17:49:24 x11: Keep level when the keysym is undefined but not the action When getting the keymap from X11, the following: ``` key <AD01> { actions=[SetGroup(2)] }; ``` is currently converted to: ``` key <AD01> { }; ``` This commit fixes dropping a defined action when the keysym is undefined
Pierre Le Marre b6acdc30 2025-01-10T20:31:04 xkbcli list: Fix duplicate variants
Pierre Le Marre bf03b4b5 2024-12-19T16:23:05 symbols: Parse empty key The following syntax does not parse in xkbcommon, but it does in xkbcomp: ``` xkb_symbols "x" { key <AD01> { }; }; ``` While the usefulness of such statement is debatable, the fact that it does parse in xkbcomp and that tools may generate such keymap entry make it relevant to handle.
Pierre Le Marre b9b4ab47 2024-12-09T09:21:01 keysyms: Add sharp S upper case mapping exception The case mapping `ssharp` ß ↔ `U1E9E` ẞ was added in 13b30f4f0dccc08dfea426d73570b913596ed602 but was broken: - For the lower case mapping it returned the keysym `0x10000df`, which is an invalid Unicode keysym. - For the upper case mapping it returned the upper Unicode code point rather than the corresponding keysym. It did accidentally enable the detection of alphabetic key type for the pair (ß, ẞ) though. However this detection was accidentally removed in 5c7c79970a2800b6248e829464676e1f09c5f43d (v1.7) with an attempt to fix the wrong keysym case mapping. Finally both the *lower* case mapping and the key type detection were fixed for good when we implemented the complete Unicode simple case mappings and corresponding tests in e83d08ddbc9851944c662c18e86d4eb0eff23e68. However, the *upper* case mapping `ssharp` → `U1E9E` remained disabled. Indeed, ẞ is a relatively recent addition to Unicode (2008) and had no official recommendation, until recently. So while the lower mapping ẞ→ß exists in Unicode, its converse upper mapping does not. Yet since 2017 the Council for German Orthography (Rat für deutsche Rechtschreibung) recommends[^1] ẞ as the capitalization of ß. Due to its stability policies, the Unicode Character Database (UCD) that we use to generate our keysym case mappings (via ICU) cannot update the simple case mapping of ß. Discussions are currently ongoing in the Unicode mailing list[^2] and CLDR[^3] about how to deal with the new recommended case mapping. However, the discussions are oriented on text-processing and compatibility mappings, while libxkbcommon is on a rather lower level. It seems that the slow adoption of ẞ is partly due to the difficulty to type it. Since ẞ is used only for ALL CAPS casing, the expectation is to type it using CapsLock. While our detection of alphabetic key types works well[^4] for the pair (ß,ẞ), the *internal capitalization* currently does not work and is fixed by this commit. Added the ß → ẞ upper mapping: - Added an exception in the generation script - Fixed tests - Added documentation of the exceptions in `xkbcommon.h` - Added/updated log entries [^1]: https://www.rechtschreibrat.com/regeln-und-woerterverzeichnis/ [^2]: https://corp.unicode.org/pipermail/unicode/2024-November/011162.html [^3]: https://unicode-org.atlassian.net/browse/CLDR-17624 [^4]: Except libxkbcommon 1.7, see the second paragraph.
Pierre Le Marre e0130e30 2024-11-18T20:08:56 state: Add vmod support for xkb_state_mod_mask_remove_consumed
Pierre Le Marre 5fbc0ec7 2024-10-14T16:05:52 state: Support querying whether virtual mods are consumed Previously it was not possible to query the status of virtual modifiers with the following functions: - `xkb_state_mod_index_is_consumed` - `xkb_state_mod_index_is_consumed2` Note that it may *overmatch* if some modifier mappings overlap. For example, the default “us” PC layout maps both “Alt” and “Meta” to the real modifier “Mod1”; thus “Mod1”, “Alt” and “Meta” modifiers will return the same result with these functions.
Pierre Le Marre 31a841ae 2024-10-14T16:05:35 state: support querying whether virtual modifiers are active Previously it was not possible to query the status of virtual modifiers with the following functions: - `xkb_state_mod_index_is_active` - `xkb_state_mod_indices_are_active` - `xkb_state_mod_name_is_active` - `xkb_state_mod_names_are_active` Note that it may *overmatch* if some modifier mappings overlap. For example, the default “us” PC layout maps both “Alt” and “Meta” to the real modifier “Mod1”; thus “Mod1”, “Alt” and “Meta” modifiers will return the same result with these functions.
Pierre Le Marre 086a286a 2024-09-23T16:20:17 mods: Always use constants from xkbcommon-names.h Respect the claim that real modifiers names are built-in: - Add `XKB_MOD_NAME_MOD[1-5]` constants. - Replace modifiers names with their corresponding constants.
Pierre Le Marre 43b26bd7 2024-11-29T08:51:41 keysyms: Update to Unicode 16.0
Jeffrey Cliff b1b9ff61 2024-11-23T10:07:24 compose/paths: fix `false` <-> `NULL` confusion, errors on C23 i don't have access to github but this patch enabled me to compile libxkbcommon with -std=gnu23 otherwise the following compilation error will result : ../src/compose/paths.c:70:16: error: incompatible types when returning type ‘_Bool’ but ‘char *’ was expected ( gcc (GCC) 15.0.0 20240509 (experimental) ) Signed-off-by: Ran Benita <ran@unusedvar.com>
Pierre Le Marre cd029431 2024-10-13T19:52:15 registry: Set libxml2 context options
Pierre Le Marre 5f1b06b7 2024-10-13T19:51:45 registry: Start using libxml2 contextual API Contextual functions are safer because they do not rely on a global state.
Sebastian Keller a47961b1 2024-10-12T16:43:46 registry: Restore default libxml2 error handler after parsing Leaving the custom error handler could have resulted in a crash after the context has been freed. Closes: https://github.com/xkbcommon/libxkbcommon/issues/529
Pierre Le Marre 60228356 2024-10-07T10:42:27 symbols: Add message ID for incompatible keysyms and actions counts
Pierre Le Marre fdf2c525 2024-10-08T19:43:30 actions: Add support for multiple actions per level This makes 1 keysym == 1 action holds also for multiple keysyms per level. The motivation of this new feature are: - Make multiple keysyms per level more intuitive. - Explore how to fix the issue with shortcuts in multi-layout settings (see the xkeyboard-config issue[^1]). The idea is to use e.g.: ```c key <LCTL> { symbols[1] = [ {Control_L, ISO_First_Group } ], actions[1] = [ {SetMods(modifiers=Control), SetGroup(group=-4) } ] }; ``` in order to switch temporarily to a reference layout in order to get the same shortcuts on every layout. When no action is specified, `interpret` statements are used to find an action corresponding for *each* keysym, as expected. For an interpretation matching Any keysym, we may get the same interpretation for multiple keysyms. This may result in unwanted duplicate actions. So set this interpretation only if no previous keysym was matched with this interpret at this level, else set the default interpretation. For now, at most one action of each following categories is allowed per level: - modifier actions: `SetMods`, `LatchMods`, `LockMods`; - group actions: `SetGroup`, `LatchGroup`, `LockGroup`. Some examples: - `SetMods` + `SetGroup`: ok - `SetMods` + `SetMods`: error - `SetMods` + `LockMods`: error - `SetMods` + `LockGroup`: ok [^1]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/416
Pierre Le Marre 772ac0c4 2024-09-23T11:02:35 keymap: Rename keysyms field in xkb_level The current field `u` (short for “union”) is not very descriptive. Next commit will add multiple actions per level, so let’s rename the keysym field to `s` (short for “symmbols”).
Pierre Le Marre 31c6d866 2024-10-08T18:39:00 symbols: Min. 2 keysyms in level list Do not allow `{ a }` when a single `a` suffices.
Pierre Le Marre 7c4c718b 2024-09-30T06:13:38 Allow only the first group in symbols sections when using RMLVO Currently `xkb_keymap_num_layouts` may return a greater number than the number of layouts configured using RMLVO, because we allow symbols sections to define various groups per key. This is unintuitive and kind of buggy: groups should be added via rules by setting an explicit `:n` modifier. Fix: when parsing a keymap using RMLVO resolution: - Get the expected layouts count from the resulting KcCGST. - Drop the groups after the first one in included symbols sections. This will ensure that a symbol section can only define one group per key. Notes: - Compiling a keymap string directly is unaffected. - RMLVO resolution may still produce more groups than the input layouts. Indeed, some legacy rules in xkeyboard-config rely on this to insert automatically a US layout before the given non-Latin one, resulting in two layouts while only one was given.
Pierre Le Marre 948f7a59 2024-10-09T08:34:27 symbols: Skip interprets only for groups with explicit actions Previously setting explicit actions for a group in symbols files made the parser skip compatibility interpretations for the corresponding *whole* key, so the other groups with *no* explicit actions could result broken on some levels. In the following example, `<RALT>` would have an action on group 2, because it is explicit, but none on group 1 because interpretation are also skipped there as a side effect: ```c key <RALT> { symbols[1]= [ ISO_Level3_Shift ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ``` Fixed by skipping interpretations *only* for groups with explicit actions. We still set `key->explicit |= EXPLICIT_INTERP` if at least one group has explicit actions. In such case, when dumping a keymap, we will write explicit actions for *all* groups, in order to ensure that X11 and previous versions of libxkbcommon can parse the keymap as intended. One side effect is that no interpretation will be run on this key anymore, so we may have to set some extra fields explicitly: repeat, virtualMods. Thus the previous example would be bumped as: ```c key <RALT> { repeat= No, symbols[1]= [ ISO_Level3_Shift ], actions[1]= [ SetMods(modifiers=LevelThree,clearLocks) ], symbols[2]= [ ISO_Level3_Shift ], actions[2]= [ SetMods(modifiers=LevelThree) ] }; ```
Pierre Le Marre 929a485f 2024-10-08T12:52:53 symbols: Fix too liberal parsing of keysyms lists Currently we are too liberal when parsing symbols lists: e.g. `[{a,{b}}]` is parsed as `[{a,b}]` but it should be rejected.
Pierre Le Marre 1d897502 2024-10-04T08:09:28 keysyms: Update using latest xorgproto xorgproto commit: d7ea44d5f04cc476dee83ef439a847172f7a6bd1 Relevant MR: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/91
Pierre Le Marre bf1ea088 2024-09-30T11:26:39 Fix typo in darray_enumerate_from
Pierre Le Marre 4ea9d431 2023-11-16T17:12:03 rules: Add support for :all qualifier Some layout options require to be applied to every group to maintain consistency (e.g. a group switcher). Currently this must be done manually for all layout indexes. This is error prone and prevents the increase of the maximum group count. This commit introduces the `:all` qualifier for KcCGST values. When a rule with this qualifier is matched, it will expands the qualified value (and its optional merge mode) for every layout, e.g. `+group(toggle):all` (respectively `|group(toggle)`) would expand to `+group(toggle):1+group(toggle):2` (respectively `|group(toggle):1|group(toggle):2`) if there are 2 layouts, etc. If there is no merge mode, it defaults to *override* `+`, e.g. `x:all` expands to `x:1+x:2+x:3` for 3 layouts. Note that only the qualified *value* is expanded, e.g. `x+y:all` expands to `x+y:1+y:2` for 2 layouts. `:all` can be used in combination with special layout indexes. Since this can lead to an unexpected behaviour, a warning will be raised.
Pierre Le Marre cdafba4f 2024-09-24T15:23:16 rules: Add support for index ranges There is a lot of repetition in the current rules files provided by xkeyboard-config, because the MLVO mappings need to match on the exact layout/variant index. This also prevents to increase the number of maximum groups, because it does not scale. We introduces the following new special layout/variant indexes: - “single”: matches a single layout; same as with no index. - “first”: matches the first layout/variant, no matter how many layouts are in the RMLVO configuration. It allows to merge `layout` and `layout[1]` patterns. - “later”: matches all but the first layout. This is an index range. - “any”: matches layout at any position. This is an index range. We also introduces the new `%i` expansion, which correspond to the index of the matched layout in a mapping with an index range. Example: layout[later] = symbols my_layout = +my_symbols:%i * = +%l[%i]:%i Let’s have a look at concrete examples from xkeyboard-config: ! model layout = symbols * * = pc+%l%(v) ! model layout[1] = symbols * * = pc+%l[1]%(v[1]) ! model layout[2] = symbols * * = +%l[2]%(v[2]) ! model layout[3] = symbols * * = +%l[3]%(v[3]) ! model layout[4] = symbols * * = +%l[4]%(v[4]) ! layout option = symbols * grp:toggle = +group(toggle) ! layout[1] option = symbols * grp:toggle = +group(toggle):1 ! layout[2] option = symbols * grp:toggle = +group(toggle):2 ! layout[3] option = symbols * grp:toggle = +group(toggle):3 ! layout[4] option = symbols * grp:toggle = +group(toggle):4 With this commit we can now simplify it into: ! model layout[first] = symbols * * = pc+%l[%i]%(v[%i]) ! model layout[later] = symbols * * = +%l[%i]%(v[%i]):%i ! layout[any] option = symbols * grp:toggle = +group(toggle):%i The latter rule will work even if we increase XKB_MAX_GROUPS, whereas the former would require to add the missing entries for the new groups. In order to maintain consistent rules, we now disallow layout and variant to have different indexes. For example, the following mapping are now invalid: - layout variant[1] - layout[1] variant[2] - layout[1] variant - layout[first] variant[1] - layout[first] variant - layout variant[any] - etc.
Pierre Le Marre 076c60df 2024-09-25T16:21:05 rules: Ensure same number of layouts and variants
Pierre Le Marre c67ec170 2024-09-25T14:59:23 include: Use constants for merge mode prefixes This will make their semantics explicit.
Pierre Le Marre a898bc81 2024-09-25T06:47:23 logging: Added new error messages ID for keymap and rules