Skip to content

XKB support#134

Closed
wismill wants to merge 22 commits intolegionus:masterfrom
wismill:xkb/v4
Closed

XKB support#134
wismill wants to merge 22 commits intolegionus:masterfrom
wismill:xkb/v4

Conversation

@wismill
Copy link
Copy Markdown
Contributor

@wismill wismill commented Jun 3, 2025

Fixes #72

TODO:

  • Moaar tests
  • Reduce XKB test data to strict minimum
  • Refactor commits (squash, proper messages)

@wismill
Copy link
Copy Markdown
Contributor Author

wismill commented Jun 3, 2025

⚠️ This is very much WIP ⚠️

legionus added 5 commits June 3, 2025 18:35
Signed-off-by: Alexey Gladkov <legion@kernel.org>
Xorg/Wayland uses its own keyboard configuration mechanism. Because of
this, the configuration of the text console and Xorg layouts may differ.
Not all combinations of Xorg layouts have a keymap in the kbd database.
It's inconvenient for users.

To solve this problem, it is possible to try convert the Xorg keymap
to the kernel keymap.

The XKB (X Keyboard Extension) database can be accessed with
libxkbcommon, which does not depend on the X11 libraries.

libxkbcommon is a keyboard keymap compiler and support library which
processes a reduced subset of keymaps as defined by the XKB
specification [1].

libxkbcommon does not distribute a keymap dataset itself, other than for
testing purposes. The most common dataset is xkeyboard-config, which is
used by all current distributions for their X11 XKB data [2].

There is a project that uses a similar approach to unify configurations.
This is console-setup [3].

I talked with Anton Zinoviev and he helped me figure out their idea of
switching multiple layouts with a single key combination:

  > how you solved the problem of switching more than two layouts with
  > one key combination ?

  The keys with ISO_Next_Group, for example the right Alt (keynumber
  100), are defined like this:

  keycode 100 = ShiftL_lock
  ShiftL keycode 100 = ShiftR_lock
  ShiftR keycode 100 = ShiftR_lock
  ShiftL ShiftR keycode 100 = ShiftL_lock

  So this key will work in the following way:

  no modifiers are active -> ShiftL is active
  ShiftL is active -> ShiftL and ShiftR are active
  ShiftL and ShiftR are active -> ShiftR is active
  ShiftR is active -> no modifiers are active

  The groups (the layouts) are placed in the following way:

  active modifiers  1 group    2 groups    3 groups    4 groups
  ----------------  -------    --------    --------    --------
  no modifier       group 1    group 1     group 1     group 1
  ShiftL            group 1    group 2     group 2     group 2
  ShiftR            group 1    group 2     group 3     group 4
  ShiftL+ShiftR     group 1    group 1     group 1     group 3

  In this way we have the following cycles:

  1 group: gr1->gr1->gr1->...
  2 groups: gr1->gr2->gr1->gr2->...
  3 groups: gr1->gr2->gr1->gr4->gr1->gr2->gr1->gr4->...
  4 groups: gr1->gr2->gr3->gr4->gr1->gr2->gr3->gr4->...

  --
  Anton Zinoviev

The difference with this implementation is that I am not trying to read
and parse the XKB base files. I analyze the resulting xkb keymap.

[1] https://xkbcommon.org/doc/current/index.html
[2] https://www.freedesktop.org/wiki/Software/XKeyboardConfig/
[3] https://salsa.debian.org/installer-team/console-setup.git

Signed-off-by: Alexey Gladkov <legion@kernel.org>
A binary search tree is created with all the unicodes that are used in
the generated keymap so that it can be checked later whether the unicode
symbol is used or not.

Signed-off-by: Alexey Gladkov <legion@kernel.org>
An external table allows it to be expanded without recompilation.

Signed-off-by: Alexey Gladkov <legion@kernel.org>
The approach to using compose differs between libxkbcommon and kernel.
Compose in the kernel has stricter restrictions.

1. Length of sequence.

xkb: The length of the compose sequence can be any (or very long).
kbd: The length of the sequence is 2.

2. Length of result.

xkb: Again, the result of the sequence can be anything.
kbd: The result of compose restricted by unsigned int.

3. How to use compose.

xkb: The libxkbcommon library loads the entire table for all locales
(more than 5000 combinations) and as characters are typed, it narrows
the number of variants until there is only one sequence left. The
library is not limited by the amount of memory by the number of stored
variants.

kbd: Compose sequences are loaded into the kernel (ioctl KDGKBDIACR) and
after that it is applied in the kernel without our participation. A table
in the kernel is limited to 256 records.

To reduce the number of combinations:

1. We must ignore all xkb compose sequences longer than 2.
2. We should ignore sequences that use unicodes that are not used in the
   generated keymap.

Such tricks allow you to reduce 5000+ to ~220 (for en,ru keymap).
Unfortunately, there is no guarantee yet that the amount of compose will
be within the limit and there is no way to control it yet.

Signed-off-by: Alexey Gladkov <legion@kernel.org>
wismill added 13 commits June 3, 2025 18:37
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
@wismill wismill force-pushed the xkb/v4 branch 2 times, most recently from fa6cfc4 to 1951339 Compare June 3, 2025 16:48
wismill added 2 commits June 3, 2025 18:49
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
wismill added 2 commits June 3, 2025 19:14
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
Signed-off-by: Pierre Le Marre <dev@wismill.eu>
@wismill
Copy link
Copy Markdown
Contributor Author

wismill commented Jun 3, 2025

@legionus CI is finally running. XKB test is expected to fail for now: locally the issue is that stderr output does mot match (I have a bunch of unable to get symbol of…), but I need to first design a test that compare kbd and xkb keymap by traversing them, because I just cannot fully test the keymap manually. I should have started with a much simpler layout too (say, us) 😅. Oh well…

The kbd compose sequences currently use control characters; I am not sure if this is expected (some special encoding?).

@legionus
Copy link
Copy Markdown
Owner

legionus commented Jun 4, 2025

I was thinking that the testing could involve ckbcomp in some way (keymaps that were generated by it). Generate a keymap with this utility and use it as a sample. I don't know how possible that would be.

./ckbcomp -layout us,ru -compact

@legionus
Copy link
Copy Markdown
Owner

This pull request is no longer relevant.

@legionus legionus closed this Mar 23, 2026
@wismill
Copy link
Copy Markdown
Contributor Author

wismill commented Mar 23, 2026

I hope some the work and discussion was relevant for your implementation though 😅

@legionus
Copy link
Copy Markdown
Owner

@wismill I closed the PR because I created an xkb branch where I made progress on the implementation. It works for me.

@wismill
Copy link
Copy Markdown
Contributor Author

wismill commented Mar 23, 2026

It is great the XKB support is progressing! I would have appreciated a short message when closing the MR, that’s all 😉

@legionus
Copy link
Copy Markdown
Owner

This PR has been abandoned. I no longer have any hope that it will lead to anything. I didn't think you cared about it.

@wismill
Copy link
Copy Markdown
Contributor Author

wismill commented Mar 23, 2026

I care of all my MR, even the dormant ones, otherwise I close them. IIRC, I stopped working on this one for more pressing matters, but also because it was too much efforts to write tests with the current build system. At that time, there was also issues with keymap round-trip parsing and misc bugs.

Anyway, I just expected a short message like:

This MR is superseded by the branch <xxx>. I {rewrote from scratch/reuse some bits/ideas/…}, thanks for your contribution.

instead of “this work is not relevant”, which feels harsh: was my work useless? does the feature development continues somehow?

There is no issue to close/reject MRs, just a finer way to do it 🙂


That said, if you need anything about libxkbcommon, just ping me or open an issue in the repository, I do my best to answer quickly.

Keep up the great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add xkb support

2 participants