Skip to content

fix: respect XKB keyboard remaps - #15

Merged
no1msd merged 1 commit into
no1msd:mainfrom
raviboth:fix/caps-remap-keycode
Sep 9, 2026
Merged

no1msd merged 1 commit into
no1msd:mainfrom
raviboth:fix/caps-remap-keycode

Conversation

@raviboth

@raviboth raviboth commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix XKB keyboard remaps in terminal panes. Caps Lock remapped to Backspace now deletes text, and Caps/Escape swaps work in both directions.

Translate supported editing, function, and modifier keyvals to the native keycodes expected by the embedded Ghostty API. Preserve GDK's actual Caps Lock state, including when another key enables the lock. Modifier meanings that Ghostty cannot represent no longer fall back to sending the original editing key. Ordinary letter keys retain their physical identity for keyboard layouts and shortcuts.

Add unit coverage and GUI regressions that send physical key events through XKB and GTK on isolated X servers. Enable CI for pull requests and install the keyboard-test utilities in CI.

Validation

  • Build and 162 unit tests passed locally.
  • All 24 existing end-to-end tests passed.
  • Python suite: 13 passed; the optional live Codex test was skipped.
  • The original PR fails three new GUI regressions; the completed fix passes all four, including Colemak typing and Ctrl shortcuts.
  • Manually verified Caps-to-Backspace and both directions of Caps/Escape swapping on Hyprland/Wayland.

Closes #3.

@raviboth

raviboth commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

This also resolves the reported case in #3 (filed for caps:swapescape). Same root cause: the raw hardware keycode is forwarded to libghostty instead of one reflecting the post-XKB keyval, so the embedded Ghostty resolves the physical key and ignores the remap.

This patch is essentially fix (a) proposed in #3 — for a small set of named editing/navigation keys, translate keyval to the canonical evdev+8 keycode and pass that to ghostty_input_key_s. Escape is in the table, so the caps-to-esc direction that #3 reports (physical CapsLock should produce Escape) now works. The reverse half of swapescape (physical Esc producing Caps_Lock) is a modifier and out of scope here.

The broader fix (b) in #3 — build an xkb_keymap from the GDK display and hand it to libghostty so Ghostty's own resolution honors the full session layout — is more correct but more invasive. Happy to take that route instead if you'd prefer it.

Note this is orthogonal to #6: that PR fixes the printable-text / IME path (text_ptr, consumed mods) and never touches .keycode, so it does not address keycode-driven remaps. Both edit handleKeyEvent, so whichever lands first I am glad to rebase on.

Two confirmed reporters now via XKB-level remaps (this and #3), so it is not a one-off config.

@no1msd no1msd changed the title fix: respect xkb keysym remaps for editing keys fix: respect XKB keyboard remaps Sep 9, 2026
@no1msd
no1msd force-pushed the fix/caps-remap-keycode branch from 9c39f76 to 0c12154 Compare September 9, 2026 15:50
@no1msd
no1msd merged commit 0c12154 into no1msd:main Sep 9, 2026
1 check passed
@no1msd

no1msd commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Thanks for the patch, Ravi! I completed the modifier-state and reverse-swap handling and added regression coverage. The fix passed CI and manual Hyprland/Wayland testing.

Squashed and fast-forwarded to main as 0c12154, preserving your authorship.

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.

Terminal key events ignore XKB-level remaps (e.g. caps:swapescape) — raw hardware keycode is sent to libghostty

2 participants