Skip to content

[Next] keybindings: Skip per-window keygrab regrab when combos don't change - #890

Open
KAMI911 wants to merge 1 commit into
linuxmint:masterfrom
KAMI911:fix/skip-unneeded-per-window-keygrab-regrab
Open

KAMI911 wants to merge 1 commit into
linuxmint:masterfrom
KAMI911:fix/skip-unneeded-per-window-keygrab-regrab

Conversation

@KAMI911

@KAMI911 KAMI911 commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #886 (every keyboard layout switch freezes the compositor for up to ~1s).

Implementation

  • Added per_window_combos_will_change(): a read-only probe that resolves each META_KEY_BINDING_PER_WINDOW binding's combo under the incoming layout (after reload_modmap(), before reload_combos() overwrites anything) and compares it against the binding's current resolved combo via a new resolved_key_combo_equal() helper, without mutating any binding state.
  • Split ungrab_key_bindings()/grab_key_bindings() (previously root window + full per-window loop) into the cheap root-only operation plus new ungrab_per_window_key_bindings()/grab_per_window_key_bindings(). reload_keybindings() now only calls the per-window variants when the probe finds a real difference. The META_PREF_KEYBINDINGS preference-change path (user edits a shortcut) keeps calling both unconditionally, since that's rare and not the perf-sensitive path.
  • The always-cheap root-window grab/ungrab is unchanged and still runs unconditionally on every reload, so non-per-window bindings (and non-Latin-layout per-window bindings) are unaffected.

Test plan

  • Reproduce X11: every keyboard layout switch freezes the compositor for up to ~1 s (reload_keybindings regrabs per-window keybindings on every window) #886's measurement script (pingsw.py) with ~100+ open windows on an X11 session with 2+ keyboard layouts; confirm the post-switch Cinnamon D-Bus freeze drops to near-baseline when per-window bindings use layout-independent keys (arrows/F-keys/Space)
  • Switch to a non-Latin layout (e.g. ru) with a per-window binding whose keysym needs the secondary US layout fallback, and confirm the per-window regrab still happens and the binding still works after the switch
  • Verify editing a keybinding in Cinnamon Settings (META_PREF_KEYBINDINGS path) still correctly re-grabs both root and per-window bindings

reload_keybindings() unconditionally ungrabbed and regrabbed every
per-window keybinding (Alt+F4, Super+arrows, etc.) on every window on
every keyboard layout group switch. Each grab/ungrab is a synchronous
XIGrabKeycode/XIUngrabKeycode round trip, so this blocks Cinnamon's
main loop (the X11 compositor) for O(windows x per-window bindings)
round trips per switch -- measured at 290ms-960ms with 32-149 open
windows.

Per-window bindings here typically use F-keys, arrows and Space, whose
keycodes are identical in every layout, so the regrab does no useful
work in the common case; it's only needed when a resolved combo's
keycodes or modifier mask actually differ under the new layout (e.g.
for non-Latin layouts, which use a secondary US layout).

Add per_window_combos_will_change(), a read-only probe that resolves
each per-window binding's combo under the incoming layout and compares
it against its current resolved combo, without mutating any state.
reload_keybindings() and the META_PREF_KEYBINDINGS preference-change
path now only pay for the per-window ungrab/grab loop when this probe
finds an actual difference. The always-cheap root-window grab/ungrab
(ungrab_key_bindings()/grab_key_bindings()) is unchanged and still
runs unconditionally on every reload.

Fixes linuxmint#886

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mtwebster mtwebster changed the title keybindings: Skip per-window keygrab regrab when combos don't change [Next] keybindings: Skip per-window keygrab regrab when combos don't change Nov 12, 2026
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.

X11: every keyboard layout switch freezes the compositor for up to ~1 s (reload_keybindings regrabs per-window keybindings on every window)

1 participant