Branch :
| Author | Commit | Date | CI | Message |
|---|---|---|---|---|
| 4e1fd49a | 2025-05-17 07:53:10 | scripts: Enable generating new range message codes | ||
| c3744cd3 | 2025-05-16 14:10:37 | test: Fix Compose log | ||
| 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 | ||
| 9b4fd82b | 2025-05-13 11:46:46 | test: Skip checked arithmetic if not available | ||
| 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. | ||
| 9da1a2eb | 2025-05-16 10:33:43 | doc: Add license in generated doc | ||
| d018638d | 2025-05-16 09:35:39 | doc: Improve CSS | ||
| 61a1e646 | 2025-05-15 17:24:50 | doc: Reformat release notes and include them in the HTML doc | ||
| bd552642 | 2025-05-15 17:20:44 | doc: Use custom alias to fix HTML tags unsupported by Doxygen Previous solution with `sed` is both overkilled and unreliable. Prefer a hack using Doxygen’s buit-ins, although we are not sure these are much more stable… 😓 | ||
| b5f7c843 | 2025-05-14 21:34:23 | doc: Add script to fix HTML tags unsupported by Doxygen | ||
| 06fbe1b2 | 2025-05-14 20:08:39 | doc: Promote xkbcli tools | ||
| cedc54d0 | 2025-05-13 15:58:52 | doc: Modifier declaration and binding Detailed explanation of: - modifier declaration - real/virtual modifier maps - modifier key binding - modifier encoding - modifier portability | ||
| 48a6faa7 | 2025-05-14 15:13:50 | tools: Remove internal interactive-evdev This *internal* tool is no longer necessary, as its single special feature, `--print-modmaps`, is now available in the *public* `compile-keymap` tool. | ||
| ae80b244 | 2025-05-14 15:08:37 | tools: Add --modmaps option to compile-keymap - Remove the `ENABLE_PRIVATE_APIS` guards on modmaps printing functions, since we use no private symbols. - Copy the `--print-modmaps` options from `interactive-evdev` into `compile-keymap` and rename it to `--modmaps`. This enables a feature similar to `xmodmap -pm`. | ||
| fb73f9f5 | 2025-05-14 15:02:24 | tools: Refactor modmaps printing functions Simplify and make them print valid YAML. | ||
| 2e07790e | 2025-05-14 14:55:55 | tools: Remove modmaps fields in interactive entries They are already printed before entering the interactive mode. | ||
| b421c2cf | 2025-05-14 10:12:15 | tools: Refactor compile-keymap - Use explicit input and output format - Perform more tests | ||
| 3eaf8ad2 | 2025-05-14 18:39:11 | doc: Add FAQ section for legacy X tools replacement | ||
| 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 | ||
| af5eacea | 2025-05-12 19:38:04 | test: Fix uninitialized variable Warning from MSVC. | ||
| 72ed9104 | 2025-05-12 19:29:24 | test: Use standard C rather than POSIX API Windows does not use the same functions signatures and generates a lot of warnings. | ||
| 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 | ||
| b49a4409 | 2025-05-12 18:20:12 | tools: Minor refactor of how-to-type | ||
| 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 | ||
| 7cf3d49b | 2025-05-11 18:21:07 | doc: Improve actions - Improve parameters doc of supported actions - Document some legacy actions | ||
| 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. | ||
| 9191ccc9 | 2025-05-09 15:39:53 | test: Added further case to xkb_state_update_latched_locked Test group lock wrap. | ||
| 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. | ||
| 9fab3948 | 2025-05-09 00:05:31 | doc: Deprecate legacy modifiers names The following modifiers names in `xkbcommon/xkbcommon-names.h` are now deprecated: - `XKB_MOD_NAME_ALT`: use `XKB_VMOD_NAME_ALT` instead. - `XKB_MOD_NAME_LOGO`: use `XKB_VMOD_NAME_SUPER` instead. - `XKB_MOD_NAME_NUM`: use `XKB_VMOD_NAME_NUM` instead. | ||
| 1b402b06 | 2025-04-06 18:45:05 | doc: Introduce the “deprecated” changelog fragment type | ||
| 51c8c5b5 | 2025-05-09 00:04:42 | doc: Common modifiers & LEDs names | ||
| 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> | ||
| e00a5e83 | 2025-05-07 16:10:04 | Add tests for pure virtual modifiers | ||
| 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. | ||
| dd642359 | 2025-05-07 00:06:10 | Bump version to 1.9.2 | ||
| 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. | ||
| ac42ce29 | 2025-05-06 21:29:46 | test: Check xkeyboard-config xkbcommon → xkbcomp chaining | ||
| 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. | ||
| 7df431ac | 2025-05-02 19:44:15 | Bump version to 1.9.1 | ||
| cd512b8f | 2025-05-02 19:21:09 | x11: Fix capitalization transformation | ||
| 9ffe3cfc | 2025-04-29 12:48:10 | doc: Create a FAQ page - Initialize with multiple recurrent questions. - Document how to get the vmod → rmod mapping. Rational: Some applications may need it to interface with legacy code. | ||
| 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 | ||
| 4d605b70 | 2025-04-29 11:18:36 | tests: Ensure random generator use an explicit seed This enable debugging with the exact same seed. | ||
| 963c062c | 2025-04-29 11:02:16 | tests: Refactor utils Some parts relied on undefined behavior and it had duplicated tests. | ||
| 0bfd097c | 2025-04-28 08:37:31 | test: Fix main() function prototype Fix compilation error when building for Windows with clang-cl: ../subprojects/libxkbcommon-xkbcommon-1.9.0/test/keysym-unicode.c:11:1: error: return type defaults to 'int' [-Wimplicit-int] ../subprojects/libxkbcommon-xkbcommon-1.9.0/test/keysym-unicode.c:11:1: warning: function declaration isn't a prototype [-Wstrict-prototypes] | ||
| 8af09d59 | 2025-04-28 07:01:42 | doc: Fix usual vmods mapping typo `LevelThree` and `LevelFive` are mapped respectively to `Mod5` and `Mod3`. This is counter-intuitive but set so for ages and probably hard- coded in some places. | ||
| 33bc8c13 | 2025-04-27 11:51:58 | doc/keymap-format-text-v1: fix inaccurate statement in Keysym glossary entry Signed-off-by: Ran Benita <ran@unusedvar.com> | ||
| ee1a98c5 | 2025-04-15 20:45:27 | Bump version to 1.9.0 Signed-off-by: Ran Benita <ran@unusedvar.com> | ||
| 95c5c859 | 2025-03-25 05:50:02 | xkbcomp: Quote erroneous field in logging | ||
| d66a65c2 | 2025-03-20 17:34:07 | xkbcomp: Consistent keycodes logging | ||
| 38322758 | 2025-04-12 13:06:05 | doc: Include and merge modes | ||
| 21a341f2 | 2025-03-24 09:21:40 | test: Enable 3rd party compilers | ||
| 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. | ||
| 00585c5c | 2025-04-15 18:41:03 | doc: Keymap format + misc | ||
| 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 | ||
| a629aa84 | 2025-03-25 05:49:04 | xkbcomp: Fix merge mode for defaults in compat | ||
| af5296cf | 2025-03-19 13:11:35 | xkbcomp: Fix virtual mods merge modes | ||
| 06c024e0 | 2025-03-19 13:11:35 | xkbcomp: Fix merge modes Fix various issues with merge mode handling: - Invalid initialization - Invalid merge mode inherited from keymap - Do not leak local merge mode | ||
| 0f6ea465 | 2025-03-19 14:12:05 | ci: Enable merge modes tests | ||
| 636b8b97 | 2025-03-19 14:11:52 | test: Add merge mode tests for all the sections The merge modes tests C file is now only generated locally, because it is too large. The generator Python script requires Jinja2, so the test is optional and depends on Jinja22 availability. The test aim to be exhaustive with various combinations of a base and an update: - plain base + plain update, for every mode - plain base + include (for every mode) update (every mode) - single include (base +| update) | ||
| 216352db | 2025-04-10 14:58:25 | test: Improve xkeyboard-config script - Enable setting the XKB root directory. By far the most important change. - Enable to pass registry XML files relative to the target rules directory (with or without the `.XML` extension). - Enable to set the rules set to use. - Better JSON/YAML escaping. - Better error logging. | ||
| a1e595e7 | 2025-04-11 11:13:25 | rules: Fix merging KcCGST values in layout order When using layout index ranges (e.g. special indexes “any” or “later”), the rules still match following the order in the rules file, so layout indexes may match without following their natural order. So the resulting KcCGST value should not be merged with the output until reaching the end of the rule set. Because the rule set may also involve options, it may match multiple times for the *same* layout index. So these multiple matches should not be merged together either, until reaching the end of the rule set. When reaching the end of the rule set, for each KcCGST component the pending values are then merged: for each layout, for each KcCGST value in the corresponding sequence, merge with the output. --- Example: ! model = symbols * = pc ! layout[any] option = symbols C 1 = +c1:%i C 2 = +c2:%i B 3 = skip B 4 = +b:%i The result of RMLVO {layout: "A,B,C", options: "4,3,2,1"} is: symbols = pc+b:2+c1:3+c2:3 - `skip` was dropped because it has no explicit merge mode; - although every rule was matched in order, the resulting order of the symbols follows the order of the layouts, so `+b` appears before `+c1` and `+c2`. - the relative order of the options for layout C follows the order within the rule set, not the order of RMLVO. Before this commit, the result would have been: symbols = pc+c1:3+c2:3+b:2 | ||
| 8d380f1b | 2025-04-11 13:41:37 | rules: Improve bench | ||
| dc50603c | 2025-03-27 14:34:02 | build: Force UTF-8 source files encoding on Windows Some of our test files (e.g. keysym strings) use UTF-8 encoded strings that require proper handling by the compiler. Let’s favor readability using modern compiler settings instead of escape sequences. | ||
| 66f71890 | 2025-03-31 08:01:29 | symbols: Enable writing keysyms list as UTF-8 strings Each Unicode code point of the string will be translated to their respective keysym, if possible. An empty string denotes `NoSymbol`. When such conversion is not possible, this will raise a syntax error. This introduces the following syntax: ```c // Empty string = `NoSymbol` key <1> {[""]}; // NoSymbol // Single code point = single keysym key <2> {["é"]}; // eacute // String = translate each code point to their respective keysym key <3> {["sßξك🎺"]}; // {s, ssharp, Greek_xi, Arabic_kaf, U1F3BA} // Mix string and keysyms key <4> {[{"ξ", Greek_kappa, "β"}]}; // { Greek_xi, Greek_kappa, Greek_beta} ``` It can also be used wherever a keysym is required, e.g. in `interpret` and `modifier_map` statements. In these cases a single keysym is expected, so the string should contain *exactly one* Unicode code point. |