feat: layout-independent keybinds#3801
Draft
ronharel02 wants to merge 7 commits intoniri-wm:mainfrom
Draft
Conversation
Add config fields for layout-independent binds at both the `binds {}` and individual bind levels, plus a separate `binds.xkb` reference keymap section.
Validate the merged binds configuration after includes are applied so that layout-independent binds require a reference XKB config, and that config describes a single reference layout unless an explicit keymap file is used.
Introduce runtime-specific bind types so input handling no longer depends directly on config-layer bind structures. This keeps bind presentation on the original config data, while letting the runtime and MRU-generated bindings work with owned compiled triggers that can later represent more than plain keysyms.
Compile layout-independent binds against the configured reference keymap and match them by physical key at runtime. This wires bind compilation into startup, validation, and config reload, and rejects binds that cannot be resolved uniquely or that collide after physical key resolution. When both a physical-key bind and a keysym bind match the same event, the compiled physical-key bind takes precedence.
Document the new layout-independent bind mode, including how `binds.xkb` defines the reference keymap used for physical-key matching. Also add commented guidance to the default config so users can discover the feature and see the minimal setup it requires.
Treat `layout-independent` and `binds.xkb` as applying only to binds in the same `binds { }` block.
Move `Xkb` into individual `Bind` entries and validate per-block during decoding.
Update `compile_binds` to use each bind's xkb, cache multiple keymaps, and report per-bind errors on resolution failures.
Also consolidate modifier display and XKB-name parsing through a shared modifier-name table.
`Bind` no longer stores a separate `layout_independent` flag.
Instead, layout-independent matching is represented entirely by `Bind.xkb`: if it is present, the bind is resolved against that reference keymap, and if it is absent, the bind remains a normal keysym bind.
The `layout-independent` setting is now treated purely as `binds {}` block parsing state.
During decoding, each bind computes its effective override from the bind-local property or the block default, validates that the trigger is a keysym when enabled, and copies the block `xkb` onto the bind when needed.
This makes the resolved bind representation simpler and more semantic.
Runtime code no longer has to interpret a tri-state `Option<bool>` alongside `xkb`, and bind compilation can infer layout-independent behavior directly from whether an `xkb` is attached.
Let layout-independent binds compile to multiple physical keys when the reference keymap maps the requested keysym to more than one key. Keep duplicate detection after expansion, so ambiguous binds are allowed only when their expanded key set does not collide with another bind.
d956e8a to
5288c78
Compare
Contributor
|
Wouldn't this be covered by #3366? |
Author
I wasn’t aware of #3366 when I opened this, thanks for pointing it out. The main thing this PR adds beyond it is symbolic layout-independent binds for keys that are not simple first-level symbols in the default layout. With #3366, those cases still seem to require either changing bind resolution globally or writing raw binds, while this PR keeps normal keysym binds unchanged and lets specific binds opt into an explicit reference xkb map, including symbols that require modifiers like With that being said, #3366 is much simpler, so I see why it would be favorable. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds explicit layout-independent keybinds that resolve symbolic binds against a reference
binds.xkbkeymap and then match them by physical key at runtime. The feature keeps normalkeysymbinds unchanged, while allowing punctuation and non-latin layout cases likeMod+/to continue working across layout switches.Layout-independent resolution is configured locally within each
binds {}block. A block can declare a default withlayout-independent true/false, a reference keymap withxkb { ... }, and individual binds in that same block can opt in or out explicitly usinglayout-independent=true/false. The symbolic key must resolve to at least one physical key in the reference keymap; missing or colliding resolutions are treated as configuration errors.Several existing issues point to the same underlying problem: keybind behavior changes unexpectedly across keyboard layouts, especially for non-latin layouts, punctuation, and keys whose logical meaning depends on the active XKB layout - e.g. #2818, #1519, #1913, #283, #1225, and #2390.
I did not find an issue that proposes this exact solution/ configuration model directly, but this seemed like a good direction for addressing that broader class of problems while maintaining the default bind behavior.
This also ended up being a larger PR then I intended for it to be, sorry.