|
bdf069f9
|
2025-10-20T17:24:58
|
|
Bump version to 1.12.2
|
|
22799562
|
2025-10-20T13:07:58
|
|
compose: No fallback if no missing locale detection
Do not use `newlocale()` if it accepts missing locales. It happens with
muslc, while glibc works as expected.
It fixes the incorrect behavior of the fallback introduced in
135b3204a15838205c97e793cd41faa742d429e2.
|
|
3c0eb068
|
2025-10-17T14:50:07
|
|
Bump version to 1.12.1
|
|
939bf0e1
|
2025-10-17T11:57:53
|
|
xkbcomp: Never drop X11 canonical key types
There are 4 mandatory *canonical key types* in the XKB protocol:
- `ONE_LEVEL`
- `TWO_LEVEL`
- `ALPHABETIC`
- `KEYPAD`
They are always present in the keymap generated from xkeyboard-config.
But since 31900860c65b88e4d10ad7dd00377e2815cca0f6 we drop unused key
types by default, which may happen for the types hereinabove with e.g.
4+ level layouts like `es`.
In theory these types are automatically filled by libX11 if missing,
but there are some bugs in the X11 ecosystem that prevents the keymap
to be properly uploaded in the X server, leading to errors when
retrieving it with libxkbcommon-x11. See:
https://gitlab.archlinux.org/archlinux/packaging/packages/libxkbcommon/-/issues/3
The following fixes were filed to fix the issues:
- https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/292
- https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2082
- https://github.com/xkbcommon/libxkbcommon/pull/871
However it’s not clear when new versions of libX11 and xserver will be
released. So this commit is a hack to ensure that we do not drop the
XKB canonical key types, as an effort to reduce breakage.
WARNING: contrary to `xkbcomp`, we do not supply these types if they
are missing, because a keymap that uses them (explicitly `type="…"` or
implicitly with automatic types) without providing them is considered
buggy. The only exception is if no key type is provided, a default one-
level type `ONE_LEVEL` is provided and assigned to all keys.
|
|
f4e247e5
|
2025-10-10T10:10:10
|
|
Bump version to 1.12.0
|
|
584e0690
|
2025-10-08T11:55:22
|
|
keysyms: Update using latest xorgproto
xorgproto commit: 81931cc0fd4761b42603f7da7d4f50fc282cecc6
Relevant MR: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/103
|
|
31900860
|
2025-09-30T13:05:43
|
|
keymap: Make serialization of unused items optional
When compiling a keymap from text, some items may be unnecessary in the
final keymap, i.e. they do not affect the keymap behavior:
- unused key types;
- unused keysym interpretations.
Deactivate the serialization of these items *by default* and add a new
flag to enable it for debugging.
|
|
345f0c67
|
2025-09-24T20:28:00
|
|
keymap: Make pretty-printing optional
This greatly improves the keymap serialization: 1.22× speedup and
about 5% less allocations. The resulting keymap is also a bit faster
to parse.
Another improvement is that it eases keysym names migrations (removal
and additions) by using only keysym numeric values. This requires some
care, i.e. `NoSymbol` must be serialized with its name and not its
value 0x0, because xkbcomp and libxkbcommon < 1.12 would interpret the
numeric value as `XKB_KEY_0`.
|
|
9131711a
|
2025-08-21T13:09:04
|
|
keymap: Add xkb_keymap_get_as_string2()
Enable to configure the keymap serialization.
|
|
1eb34399
|
2025-08-20T22:52:17
|
|
xkbcomp: Enable using the whole keycode range
In 502e9e5bff3781cba09f3b33ec030522b549f4e5 we restricted the supported
keycode range in order to avoid memory exhaustion and inefficient storage
in sparse arrays. This solution enabled keycodes up to 0xfff, which
seemed good enough at the time.
However there are huge keycodes in use in the wild, e.g. in WebOS.
So let’s enable the whole keycode range by using 2 methods of storage:
- “Low” keycodes (≤ 0xfff): stored contiguously as before at indexes
[0..num_keys_low); fast O(1) access.
- “High” keycodes (> 0xfff): stored noncontiguously at indexes
[num_keys_low..num_keys); slow access via binary search.
|
|
44fad8a0
|
2025-09-14T10:29:41
|
|
keysyms: Update to Unicode 17.0
See: https://www.unicode.org/versions/Unicode17.0.0/
|
|
135b3204
|
2025-08-16T12: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`
|
|
0f9cefb1
|
2025-07-15T12:35:34
|
|
Bump version to 1.11.0
|
|
3ffb7e73
|
2025-07-16T19:43:27
|
|
doc: Add text format sections to release notes
|
|
39726cac
|
2025-08-06T20: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()`.
|
|
1e0c5790
|
2025-07-23T12:09:32
|
|
keysyms: Fix XF86MediaSelectAuxiliary typo
|
|
e9fd95a5
|
2025-07-23T10:01:45
|
|
keysyms: Update using latest xorgproto
xorgproto commit: 7fc33fe6d9cf0abc9b62ee976e5cb7ddcd050d1f
Relevant MR: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/merge_requests/93
|
|
93818226
|
2025-07-15T11:34:06
|
|
Add xkb_rmlvo_builder_ref()
|
|
b21a58d0
|
2025-07-01T14: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.
|
|
58373807
|
2025-06-27T18: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.
|
|
3d00222e
|
2025-06-21T18:26:34
|
|
keymap: Add option `unlockOnPress` for LatchMods()
It mirrors the feature of `SetMods()`, so that `StickyKeys` can be
implemented.
|
|
d192b3b6
|
2025-06-19T21: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-21T19: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-21T13: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-14T09: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-17T16: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-17T21: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.
|
|
ee50e0c9
|
2025-06-12T20: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
|
|
d9d82355
|
2025-06-12T09: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
|
|
0106b357
|
2025-06-17T12: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.
|
|
fab9d25b
|
2025-06-17T11: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` |
|
|
ef6a550f
|
2025-06-16T15:48:25
|
|
Add xkb_keymap_new_from_rmlvo()
Use the new RMLVO builder API to compile keymaps.
|
|
da5caabb
|
2025-06-16T15: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.
|
|
f7a61da7
|
2025-06-10T17:33:24
|
|
doc: Update new layout count ranges
|
|
44c8deb2
|
2025-05-07T10: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.
|
|
58397e94
|
2025-05-06T18:05:30
|
|
Deprecate xkb_keymap_new_from_names()
- Deprecate `xkb_keymap_new_from_names()` in favor of
`xkb_keymap_new_from_names2()`
- Add new changelog fragment type `deprecated`.
- Change documentation to use the new function.
|
|
1a10f858
|
2025-05-06T18:05:06
|
|
Add xkb_keymap_new_from_names2
This is just `xkb_keymap_new_from_names()` with an explicit keymap
format.
|
|
39b4b670
|
2025-06-06T18: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.
|
|
7888474d
|
2025-05-16T14:06:18
|
|
Bump version to 1.10.0
|
|
7a2aa9c9
|
2024-12-20T22: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-16T13: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.
|
|
b4c89600
|
2025-05-09T15: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.
|
|
551cca2a
|
2024-12-03T10: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>
|
|
7cd1180b
|
2025-05-06T11: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-09T00: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.
|
|
a3f1a9d3
|
2025-02-04T20: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>
|
|
dddffd51
|
2025-05-05T13: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-07T00:06:10
|
|
Bump version to 1.9.2
|
|
d5b779e1
|
2025-05-06T21:07:28
|
|
keymap: Fix empty compat interpretation map serialization
X11’s `xkbcomp` requires at least one compat interpretation entry.
|
|
87f9ac76
|
2025-05-06T21: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-06T14: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
|
|
7df431ac
|
2025-05-02T19:44:15
|
|
Bump version to 1.9.1
|
|
cd512b8f
|
2025-05-02T19:21:09
|
|
x11: Fix capitalization transformation
|
|
ee1a98c5
|
2025-04-15T20:45:27
|
|
Bump version to 1.9.0
Signed-off-by: Ran Benita <ran@unusedvar.com>
|
|
38322758
|
2025-04-12T13:06:05
|
|
doc: Include and merge modes
|
|
9b0b8c68
|
2025-04-15T19: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-13T09: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.
|
|
ead3ce77
|
2025-03-28T21:44:27
|
|
scanner: Enable LRM and RLM marks for BiDi text
Enable displaying bidirectional text in XKB files using:
- U+200E LEFT-TO-RIGHT MARK
- U+200F RIGHT-TO-LEFT MARK
We now parse these marks as white space. As such, they are dropped;
note that a later serialization may not display correctly without
the marks, although it will parse.
References:
- https://www.w3.org/International/articles/inline-bidi-markup/uba-basics
- https://www.w3.org/International/questions/qa-bidi-unicode-controls
- https://www.unicode.org/reports/tr31/#Whitespace
- https://www.unicode.org/reports/tr55/
|
|
bc3e464b
|
2025-04-09T12:35:05
|
|
keysyms: Fix Unicode handling
- `xkb_utf32_to_keysym`: Allow [Unicode noncharacters]. There is no
requirement to drop them and this would be the only function of our
API doing so.
From the Unicode Standard 16.0, section 23.7 “Noncharacters”:
> Applications are free to use any of these noncharacter code points
> internally. They have no standard interpretation when exchanged
> outside the context of internal use. However, they are not illegal
> in interchange, nor does their presence cause Unicode text to be
> ill-formed.
> If a noncharacter is received in open interchange, an application is
> not required to interpret it in any way. It is good practice,
> however, to recognize it as a noncharacter and to take appropriate
> action, such as replacing it with `U+FFFD` REPLACEMENT CHARACTER,
> to indicate the problem in the text.
The key part is:
> an application is not required to interpret it in any way
Since we handle the reverse conversion with `xkb_keysym_to_utf32` just
fine, I do not see a good motivation to keep this asymmetry. This is
the only function with a special case for these code points.
- `xkb_keysym_from_name`:
- Unicode format `UNNNN`: allow control characters C0 and C1 and use
`xkb_utf32_to_keysym` for the conversion when `NNNN < 0x100`, for
backward compatibility.
- Numeric hexadecimal format `0xNNNN`: *unchanged*. Contrary to the
Unicode format, it does not normalize any keysym values in order to
enable roundtrip with `xkb_keysym_get_name`.
Also added tests to ensure various properties and consistency.
Note about *surrogates*: they are valid valid *code points* but invalid
Unicode *scalar values*, i.e. they cannot be encoded in any Unicode
encoding form (UTF-8, UTF-16, UTF-32). So their corresponding Unicode
keysyms are valid, but:
- cannot be used as input of `xkb_keysym_to_utf32` nor `xkb_keysym_to_utf8`
- cannot result as output of `xkb_utf32_to_keysym`.
Otherwise they are valid e.g. in the Unicode keysym notation.
[Unicode noncharacters]: https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Noncharacters
|
|
36442baa
|
2025-04-03T15:01:46
|
|
xkbcomp: Support multiple actions in interpret
Before this commit we supported multiple actions per level, but not in
*interpret* statements. Let’s fix this asymmetry, so we can equivalently
assign all actions sets either implicitly or explicitly.
|
|
3d79f459
|
2025-03-29T11:46:34
|
|
xkbcomp: Add Unicode code point escape sequence \u{NNNN}
Unicode code point escape sequences `\u{NNNN}` are replaced with the
UTF-8 encoding of their corresponding code point `U+NNNN`, if legal.
Supported Unicode code points are in the range `1‥0x10ffff`.
Note that we will reject the `U+0000` NULL code point, as we reject it
in the octal escape sequence `\0`.
This is intended mainly for the upcoming feature to write keysyms as
UTF-8 encoded strings. It can be used for various reasons:
- avoid encoding issues;
- avoid issue with font rendering (e.g. Asian scripts);
- make white space or zero-width characters more readable.
|
|
7d91a753
|
2025-03-29T12:24:39
|
|
xkbcomp: Enable xkbcomp-style octal escape sequences
Xorg xkbcomp only parses octal sequences with `\0`, while xkbcommon
does not force the `0` prefix of the numeric part. However, we only
parsed up to to 3 digits, which does not allow to parse e.g. `\0377`
while `\377` parses fine.
Fixed by parsing up to 4 octal digits, while checking the result fits
into a byte.
|
|
aa8b572e
|
2025-03-29T12:04:26
|
|
keymap serialization: Ensure escaping relevant chars
Previously we would write characters without any escaping in some
cases (e.g.: names of indicators, types and groups). E.g. the string
"new\nline"
would be serialized as:
"new
line"
which would raise a syntax error if parsed.
Fixed by escaping any string that was not escaped after parsing (e.g.
the section names are safe already).
|
|
44480f7c
|
2025-04-01T08:28:02
|
|
xkbcomp: Enable lists of keysyms and actions {} and {a}
Motivations:
- Follow the principle of least astonishment;
- Ensure consistency;
- Enhance the use of custom defaults;
- Facilitate the tests.
There is some ambiguity because we use `{}` to denote both an empty list of
keysyms and an empty list of actions. But as soon as we get a keysym or an
action, we know whether it is a `MultiKeySymList` or a `MultiActionList`.
So we just count the `{}` at the *beginning* using `NoSymbolOrActionList`,
then replace it by the relevant count of `NoSymbol` or `NoAction()` once the
ambiguity is solved. If not, this is a list of empties of *some* type: we
drop those empties and delegate the type resolution using `ExprEmptyList()`.
|
|
e09cbe66
|
2025-04-02T10:46:06
|
|
symbols: Fix handling of empty keys
Before this commit, the following symbols:
```c
xkb_symbols {
virtual_modifiers M1, M2;
key <A> {};
key <B> { [] };
key.vmods = M1;
key <C> {};
key <D> { vmods = M2 };
};
```
would be equivalent to:
```c
xkb_symbols {
virtual_modifiers M1,M2;
key <B> { [ NoSymbol ] };
};
```
`<B>` entry could be skipped but is harmless. However, `<C>` and `<D>`
are missing, which would lead to the mapping resolution of `M1` and
`M2` failing.
After this commit, it is equivalent to:
```c
virtual_modifiers M1,M2;
key <C> { vmods = M1 };
key <D> { vmods = M2 };
```
Empty keys are skipped entirely, but any explicit field:
- is taken into account: previously they would be skipped if there
were no group;
- forces the key to be printed at serialization.
|
|
2e0245f8
|
2025-04-02T10:45:44
|
|
xkbcomp: Enable more empty lists
- Empty `interpret`
- Empty key `type`
- Empty `indicator`
Motivations:
- Follow the principle of least astonishment;
- Ensure consistency;
- Enhance the use of custom defaults;
- Facilitate the tests.
|
|
6881fb32
|
2025-04-01T08:28:02
|
|
xkbcomp: Drop trailing NoSymbol and NoAction()
This brings us closer to what `xkbcomp` outputs. One should use
the explicit `VoidSymbol` instead of `NoSymbol`, in order to avoid
dropping empty levels.
This may affect keys that rely on an *implicit* key type. Example:
- Input:
```c
key <> { [a, A, NoSymbol] };
```
- Compilation with xkbcommon \< 1.9.0:
```c
key <> {
type= "FOUR_LEVEL_SEMIALPHABETIC",
[a, A, NoSymbol, NoSymbol]
};
```
- Compilation with xkbcommon ≥ 1.9.0:
```c
key <> {
type= "ALPHABETIC",
[a, A]
};
```
|
|
343c49cc
|
2025-03-30T09:54:02
|
|
doc: Optional components
|
|
23598fa1
|
2025-03-25T22:52:06
|
|
Enable merge mode “replace” in include statements
Previously only the merge modes “override” and “augment” were available
in include statements, using the prefix ‘+’ and ‘|’ respectively. While
on one hand `replace` include statement can be used in keymap files, on
the other hand *rules* files have no way to express the *replace* mode.
This commit enables the merge mode “replace” using the prefix `^`. This
prefix was chosen due to its similarity with the `XOR` bit operator,
which convey *mutual exclusion*.
Other candidates:
- `!` conveys some kind of higher precedence, akin to CSS `!important`.
But it conflicts with the section header `!`, which is a token in the
current parser. It would require special handling, not worth it. It
also convey the meaning of negation, which is confusing.
- `&` has the advantage of not corresponding to a token in the rules
parser. `^` seems however to stand out more and it is less likely to
trigger erroneous comparison with `|` and `&` bit operators.
|
|
6fc6e64b
|
2025-03-26T10:35:22
|
|
rules: Added extended wild cards <none>, <some> and <any>
Added the following wild cards to the rules file syntax, in addition
to the current `*` legacy wild card:
- `<none>`: Match *empty* value.
- `<some>`: Match *non-empty* value.
- `<any>`: Match *any* (optionally empty) value. Its behavior does not
depend on the context, contrary to the legacy wild card `*`.
This will enable writing much simpler rules, see [!764] for an example
of tricky rules in the `xkeyboard-config` project, that would benefit
from the new wild cards.
[!764]: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/764
The verbose wild cards are preferred to single characters:
- More intuitive: self-explanatory.
- Does not steal syntax from other token.
- Extensible syntax, should we need it.
A previous proposal used the characters (`!`, `+`, `?`) for their
similarity with the corresponding syntax of regular expressions
(negative assertion & quantifiers), in line with `*`. But `!` is not
that intuitive after all and conflict with its role as section header.
Furthermore, `+` is also used as a merge mode. Finally, nothing beats
whole short words for readability.
|
|
500b260b
|
2025-03-28T09:38:58
|
|
xkbcomp: Fix parser failure on floating-point numbers
Before this commit we used `strtold`, which depends on the locale. But
the XKB syntax is fixed and uses a period as decimal separator. So ensure
the syntax is correct without relying on `strtold` and truncate the
result, as the parser does not use floating-point numbers.
|
|
d7e112fe
|
2025-03-29T19:44:13
|
|
registry: Added support for libxml2 2.14+
`libxml2-2.14+` now disallows parsing trailing `NULL` bytes, so don’t.
This is backward-compatible with previous versions of the library.
|
|
cc95f217
|
2025-03-25T11:15:45
|
|
xkbcomp: Fix whichGroupState serialization
This indicator field was previously looked up in the wrong table,
resulting the erroneous serialization `(null)`.
|
|
8e92f25e
|
2025-03-13T21:26:59
|
|
rules: Added xkb_components_names_from_rules()
This is mainly for debugging purposes and to enable displaying KcCGST
values from RMLVO resolution in `xkbcli compile-keymap --kccgst`.
|
|
b3465081
|
2025-03-12T00:20:39
|
|
Bump version to 1.8.1 and update changelog
|
|
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>
|
|
76740e0c
|
2025-01-30T14:21:00
|
|
Bump version to 1.8.0 and update changelog
|
|
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.
|
|
27ac30b2
|
2025-01-27T17:13:44
|
|
symbols: Normalize levels by dropping NoSymbol & NoAction
|
|
b0d9a790
|
2025-01-15T12:03:10
|
|
vmods: Fix explicit vmods not dumped
|
|
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>
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
e0130e30
|
2024-11-18T20:08:56
|
|
state: Add vmod support for xkb_state_mod_mask_remove_consumed
|
|
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.
|
|
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.
|
|
2ba9daf1
|
2024-09-23T16:20:37
|
|
mods: Add more built-in names
Added support for the following virtual modifiers:
- `Alt`
- `Meta`
- `NumLock`
- `Super`
- `Hyper`
- `LevelThree`
- `LevelFive`
- `ScrollLock`
|
|
43b26bd7
|
2024-11-29T08:51:41
|
|
keysyms: Update to Unicode 16.0
|
|
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
|
|
b1da948a
|
2024-10-08T19:43:18
|
|
symbols: Add doc for multiple actions
|
|
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.
|
|
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) ]
};
```
|
|
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
|
|
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.
|
|
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.
|
|
7697c712
|
2024-09-16T16:09:11
|
|
rules: Resolve relative include statements using XKB paths
Contrary to keymap files, the `! include` statement in rules does not
lookup include paths added to `xkb_context`. So it is not possible e.g.
to import another file in the same folder without using an absolute path.
- Added path utils: `is_absolute(path)`.
- Added XKB paths lookup to enable e.g. `! include evdev` to work.
- Added test.
|
|
44df6eee
|
2024-09-23T07:27:48
|
|
Add new warnings for deprecated keysyms
Add 2 new warnings:
- Deprecated keysym name (typo, historical alias, etc.);
- Deprecated keysym (all names and forms).
Guard deprecated keysym tests with verbosity level ≥2, so they are
run only when actually needed.
|
|
e4269202
|
2024-09-20T10:41:00
|
|
keysyms: Fix off-by-one XKB_KEYSYM_NAME_MAX_SIZE
The constant did not account for the terminating `NULL` byte and this was
sadly not caught by the tests.
Fixed the invalid value, the corresponding script and the tests.
|