Skip to content

wayland: xkb_keymap_mod_get_mask() optional at runtime, with a suite - #3

Merged
foxnne merged 2 commits into
fizzy-3.4from
wayland/xkb-mod-mask-optional
Oct 9, 2026
Merged

foxnne merged 2 commits into
fizzy-3.4from
wayland/xkb-mod-mask-optional

Conversation

@foxnne

@foxnne foxnne commented Oct 9, 2026 •

Copy link
Copy Markdown

Fixes fizzyedit/fizzy#289. Part of fizzyedit/fizzy#280 (step A4b). Builds on #1 (merged, fizzy-3.4 = fizzy-3.4.16-6). fizzyedit/sdl_zig#3 pins this branch and runs the suite in CI.

Two commits: the test first, then the fix, so the test commit alone shows the failure.

1. test: a fizzy suite for the Wayland driver on an older libxkbcommon

test/testautomation_fizzy_xkb.c, suite FizzyXkb, plus one line each in testfizzy.c and testautomation_fizzy.h:

  • xkb_waylandDriverLoads: when the Wayland driver is compiled in and WAYLAND_DISPLAY is set, restart the video subsystem with SDL_HINT_VIDEO_DRIVER=wayland (override priority), then check that it started and that SDL_GetCurrentVideoDriver() is wayland. Otherwise it skips. The runner initializes video twice, so the test quits it until it is down and restores it afterwards, hint included.
  • xkb_keymapModifierLevels: this test runs only with FIZZY_TEST_XKB_LAYOUT=de, and otherwise skips. It checks the SDL keymap the Wayland driver built from the compositor's German keymap. Each level of a key is entered under the SDL modifiers its xkb mask translates to, so a wrong mask drops or misfiles the level. It checks Y = z (the compositor's keymap is in use), Shift+2 = ", Shift+3 = § (shift mask), Caps+Q = Q (caps lock mask), and AltGr+Q = @, AltGr+E = €, AltGr+7 = { (level 3 mask, LevelThree on Mod5). It also checks that no modifier is held.

2. wayland: Make xkb_keymap_mod_get_mask() optional at runtime (patch 8)

  • SDL_waylandsym.h: xkb_keymap_mod_get_mask becomes SDL_WAYLAND_SYM_OPT (still only declared when the headers are ≥ 1.10).
  • SDL_waylandevents.c: the keymap handler uses it when the pointer loaded, and otherwise falls back to the existing xkb_keymap_mod_get_index path, which is now compiled in both cases. WAYLAND_xkb_* are function pointers in static builds too (SDL_waylanddyn.h declares them so in both modes, and static builds assign = fn), so unlike wl_display_create_queue_with_name and the libdecor optionals, which are called by their bare names, the check needs no #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC.

Are the fallback's masks the same? Yes, for the standard keymaps. xkeyboard-config's symbols/pc puts Alt and Meta on Mod1, NumLock on Mod2, Super on Mod4, LevelThree on Mod5 and LevelFive on Mod3, which is exactly what the fallback assumes (hence its Mod3/Mod5 comment). Shift, Control and Lock are real modifiers on both paths. They differ only for a keymap that maps one of those virtual modifiers to a different real modifier, or to more than one, as some altwin:/lv3:/lv5: options can. The 1.10 path follows the keymap there and the fallback doesn't. That is the behaviour every build against headers older than 1.10 has always had. CI checks shift, caps lock and level 3 on both paths with the German layout. Alt, Super, NumLock and LevelFive masks aren't covered by a level check.

Upstream: not yet proposed. Upstream main and release-3.4.x have the same code. The upstream PR text is drafted in the fizzy#280 hand-off.

Verified

CI is fizzyedit/sdl_zig's test-fizzy-xkb job: ubuntu:24.04 (libxkbcommon 1.6, weston 13) and ubuntu:26.04 (libxkbcommon 1.13, weston 14) containers, weston's X11 backend inside Xvfb -noreset, with setxkbmap -layout de. Weston's headless backend has no seat, so it can't send a keymap.

  • Test commit only (213751e), run https://github.com/fizzyedit/sdl_zig/actions/runs/37968707700: 24.04 fails both tests with Validate that the Wayland video driver started, got error: wayland not available. On 26.04 the driver loads. (The keymap test failed on both in that run, but only because the CI's layout hadn't been set yet: Xvfb reset its layout when setxkbmap disconnected. That's fixed with -noreset.)
  • With the fix (36dda37), run https://github.com/fizzyedit/sdl_zig/actions/runs/37971005996: both distros pass both tests (16/16 asserts in the keymap test on each), so the fallback (24.04) and the 1.10 path (26.04) produce the same levels. A1's jobs (test-fizzy-linux x11/wayland, test-fizzy-macos) still pass, with the new suite skipping there.
  • The patch cross-compiles for x86_64-linux-gnu from a Mac through sdl_zig. macOS zig build test-fizzy passes, with FizzyXkb skipping because Wayland isn't compiled in.

Not verified: the "no modifier held" check is vacuous in this setup. Weston never gave the test window keyboard focus under the X11 backend (Keyboard focus: no), so no modifiers event arrived. A real desktop on 24.04 is also untested. The fix hasn't been run in a fizzy build on 24.04, which is waiting for the tag and repin.

Before merge

fizzy-3.4 takes this by fast-forward, and then the tip needs a permanent tag before sdl_zig's pin can merge (docs/DEPENDENCIES.md, "Tag, then pin"). The tag is the maintainer's to name; I created none. docs/DEPENDENCIES.md in fizzy gets the patch 8 entry with the repin.

🤖 Generated with Claude Code

foxnne and others added 2 commits October 9, 2026 12:46
testautomation_fizzy_xkb.c checks that SDL's Wayland driver loads, and
builds its keymap's modifier levels right, wherever libxkbcommon is
older than the headers SDL was built against.

xkb_waylandDriverLoads restarts the video subsystem with the Wayland
driver whenever WAYLAND_DISPLAY is set and checks that it started. Built
against libxkbcommon 1.10 or newer, SDL required xkb_keymap_mod_get_mask()
(new in 1.10) at load time, so on Ubuntu 24.04 (libxkbcommon 1.6) the
driver reported itself unavailable.

xkb_keymapModifierLevels checks the masks the keymap handler computed,
through the SDL keymap they built: each level of a key is entered under
the SDL modifiers its xkb mask translates to, so a wrong shift, caps lock
or level 3 mask drops or misfiles the level. With FIZZY_TEST_XKB_LAYOUT=de
and a compositor keyboard on the German layout it checks Shift+2 = '"',
Caps+Q = 'Q', AltGr+Q = '@' and the like, and that no modifier is held.
Without the variable it is skipped.

fizzyedit/sdl_zig runs it under weston's X11 backend in Xvfb, on Ubuntu
24.04 and 26.04.

Part of fizzyedit/fizzy#280, for fizzyedit/fizzy#289.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built against libxkbcommon 1.10 or newer, the Wayland driver required
xkb_keymap_mod_get_mask() (new in 1.10) when it loaded libxkbcommon, so
where the system's libxkbcommon is older the whole driver reported itself
unavailable and SDL fell back to X11. libxkbcommon is loaded at runtime so
that one binary runs across distributions, but Ubuntu 24.04 ships 1.6 and
Debian 12 1.5. It only bites builds made against newer headers than the
machines they run on, as fizzyedit/sdl_zig's are (1.13); distribution
packages build against their own.

The symbol is now SDL_WAYLAND_SYM_OPT, and the keymap handler uses it when
it loaded, and otherwise falls back to the masks from
xkb_keymap_mod_get_index(), which was already the path for builds against
older headers. Both paths are compiled whenever the headers are 1.10 or
newer. The WAYLAND_xkb_* names are function pointers in static builds too,
so the pointer check needs no #ifdef.

The fallback is the same as the 1.10 path for the standard keymaps:
xkeyboard-config maps Alt to Mod1, Super to Mod4, NumLock to Mod2,
LevelThree to Mod5 and LevelFive to Mod3. It differs where a keymap maps a
virtual modifier elsewhere or to several real modifiers, and for
LevelFive when nothing maps it (1.10 gives 0, the fallback Mod3), as it
always has for builds against older headers.

Test: test/testautomation_fizzy_xkb.c (fizzyedit/sdl_zig's test-fizzy-xkb
job, Ubuntu 24.04 and 26.04). On 24.04 without this change the driver
doesn't load.

Upstream: not yet proposed; upstream main and release-3.4.x have the
same code.

Fixes fizzyedit/fizzy#289. Part of fizzyedit/fizzy#280.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne marked this pull request as ready for review October 9, 2026 18:48
@foxnne
foxnne merged commit 36dda37 into fizzy-3.4 Oct 9, 2026
foxnne added a commit to fizzyedit/fizzy that referenced this pull request Oct 9, 2026
…294)

Fixes #289. Part of #280 (steps A1, A2 and A4b landed on the forks).

Moves fizzy's `.sdl` pin to sdl_zig `fizzy-1.0.3+3.4.16-8` (SDL
`fizzy-3.4.16-8`). That brings two things:

**1. The forks carry tests now.** fizzyedit/SDL has fizzy's own suites
on SDL's test harness, one per patch, each failing without its patch.
fizzyedit/sdl_zig runs them with `zig build test-fizzy` in CI: Linux on
lavapipe under Xvfb and headless weston, and the hosted macOS runners,
which have a Metal device.
- fizzyedit/SDL#1 → `fizzy-3.4.16-6` (`4839ede`): the runner, plus patch
1's suite (transparent window claimed on Metal and Vulkan).
- fizzyedit/sdl_zig#1 → `fizzy-1.0.3+3.4.16-6` (`0f6a2a8`): the
`test-fizzy` step.
- fizzyedit/SDL#2 → `fizzy-3.4.16-8` (`a518aaf`), fizzyedit/sdl_zig#2 →
`fizzy-1.0.3+3.4.16-8` (`a02dda8`): patch 6's suite, Wayland frame
insets.
- **How:** it reads libwayland's request trace under headless weston, at
scale 1 and 2.
- **Checks:** geometry, input region, min/max sizes and published insets
while floating; zero insets when maximized or fullscreen; popup
anchoring.
  - **Result:** passes on the fork, and fails on upstream 3.4.16.
  - **Problems it found in patch 6:** five, listed in #280 (C2b).

**2. SDL patch 8: Wayland loads where libxkbcommon is older than 1.10**
(#289).
- **The bug:** built against 1.10+ headers (sdl_zig uses 1.13), SDL
required `xkb_keymap_mod_get_mask()`. On Ubuntu 24.04 (1.6) or Debian 12
(1.5) the whole Wayland driver reported itself unavailable, and fizzy
fell back to X11. Upstream `main` has the same problem.
- **The fix:** the symbol is now optional at runtime, and the masks fall
back to `xkb_keymap_mod_get_index()`, the path SDL already takes when
built against older headers. For standard keymaps both paths give the
same masks.
- **The proof:**
- [red](https://github.com/fizzyedit/sdl_zig/actions/runs/37968707700)
on `ubuntu:24.04` without the patch ("wayland not available");
- [green](https://github.com/fizzyedit/sdl_zig/actions/runs/37971005996)
on 24.04 and 26.04 with it, where a German keymap's Shift, Caps Lock and
AltGr levels come out right.
- **The PRs:** fizzyedit/SDL#3 → `fizzy-3.4.16-7` (`36dda37`);
fizzyedit/sdl_zig#3 → `fizzy-1.0.3+3.4.16-7` (`264af2a`).

`docs/DEPENDENCIES.md` records patch 8, the three suites, sdl_zig's step
and CI jobs, all six tags, and each patch's check at a rebase.

## Verified

On macOS (arm64), in a fresh workspace on `main`:

| Gate | Result |
|---|---|
| `zig build` | 43/43 steps |
| `zig build test` | 75/75 steps |
| `zig build test-integration` | 33/33 steps, 347/347 tests |
| `zig build check-web` | 16/16 steps |
| `zig build test-sdk-version` | 12/12 steps |
| `zig build -Dtarget=x86_64-linux-gnu` | 54/54 steps (builds the
patched Wayland file) |

Not verified: a fizzy binary running on a real Ubuntu 24.04 Wayland
desktop. The evidence is the fork suite in CI containers, built from the
same sdl_zig. The SDK fingerprint doesn't move, since plugins never link
SDL.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant