diff options
| author | srdusr <[email protected]> | 2024-11-30 23:03:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-11-30 23:03:00 +0200 |
| commit | 583063c3094ca0cf9f6cceba92d710b238547f6b (patch) | |
| tree | a1ff8f181027892f4a45846b67898beb136a9312 /crates/core/src/event.rs | |
| parent | 87f5c04b2593dc49409644e69e7962b73d26b9d8 (diff) | |
| download | srdwm-583063c3094ca0cf9f6cceba92d710b238547f6b.tar.gz srdwm-583063c3094ca0cf9f6cceba92d710b238547f6b.zip | |
Accumulate core-crate additions: capture requests, focus/workspace fixes, test coverage
Bundles several related changes to crates/core built up over this
session rather than committed incrementally:
- WindowManager::request_capture_workspace/drain_capture_requests (new
manager/capture.rs) - backend-agnostic queuing for an off-screen
workspace render, see the wayland-side commit for why this exists.
- focus_window now switches workspace as a side effect when the target
isn't on the current one, matching Hyprland's focuswindow convention
(manager/focus.rs).
- Assorted window/rules/theme field additions and their test coverage.
Left less granular than the repo's usual one-purpose-per-commit
convention deliberately: these accumulated across a long session
without being committed as they landed, and are too entangled
line-by-line to safely split apart now without risking mis-attributing
changes to the wrong commit message.
Diffstat (limited to 'crates/core/src/event.rs')
| -rw-r--r-- | crates/core/src/event.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/crates/core/src/event.rs b/crates/core/src/event.rs index ad96f73..0bfadc0 100644 --- a/crates/core/src/event.rs +++ b/crates/core/src/event.rs @@ -40,7 +40,31 @@ pub enum MouseButton { /// A key combination, e.g. "Mod4+Shift+Return", used both as the canonical /// string form for Lua keybindings and as the lookup key at dispatch time. +/// +/// Lowercases a single ASCII letter's name before building the string -- +/// `Shift+r` and `Shift+R` are genuinely different X11 keysyms (`XK_r`/ +/// `XK_R`), not case variants of one shared symbol, so a real Shift+<letter> +/// keypress's `modified_sym()` (see `input.rs::handle_keyboard_key_event`) +/// reports the uppercase name even though `Shift` is *also* tracked as its +/// own bit in `modifiers` - meaning without this, "Super+Shift+r" (how +/// every config writes it, lowercase) could never match a real Shift+R +/// keypress's actual combo string ("Shift+Mod4+R"). `canonicalize_key_ +/// combo`'s own case-fixing (for named keys like "Space") explicitly +/// leaves plain letters alone, so it doesn't catch this either - this is +/// the one place both the config-registration path (`canonicalize_key_ +/// combo` calls this) and the real-dispatch path converge, so normalizing +/// here is the single fix for both. Confirmed live: a real keypress +/// reached srdwm fine (a sibling Alt+Tab binding in the same config +/// fired), but every `Shift+<letter>` binding - including the reload key +/// this was found chasing - silently never did. pub fn key_combo_string(modifiers: Modifiers, key_name: &str) -> String { + let lowercased; + let key_name = if key_name.chars().count() == 1 && key_name.chars().next().is_some_and(|c| c.is_ascii_alphabetic()) { + lowercased = key_name.to_ascii_lowercase(); + lowercased.as_str() + } else { + key_name + }; format!("{modifiers}{key_name}") } @@ -185,6 +209,30 @@ mod tests { } #[test] + fn a_real_shifted_letter_keypress_matches_the_lowercase_written_binding() { + // `Shift+r` and `Shift+R` are different X11 keysyms (`XK_r`/`XK_R`), + // not case variants of one shared symbol - a real Shift+<letter> + // keypress's dispatch-time key name is the *uppercase* one, even + // though Shift is also tracked as its own bit in `modifiers`. Every + // config writes bindings lowercase ("Super+Shift+r"), so the two + // sides have to agree despite that: this is what silently broke + // every `Shift+<letter>` binding (found chasing a dead reload key) + // until `key_combo_string` started normalizing single letters. + let config_side = canonicalize_key_combo("Mod4+Shift+r"); + let dispatch_side = key_combo_string(Modifiers::SHIFT | Modifiers::SUPER, "R"); + assert_eq!(config_side, dispatch_side); + assert_eq!(config_side, "Shift+Mod4+r"); + } + + #[test] + fn named_keys_are_unaffected_by_the_letter_lowercasing() { + // Multi-character key names ("Space", "Return", ...) don't change + // identity with Shift the way a single letter's keysym does, so + // they must not be touched by the same normalization. + assert_eq!(key_combo_string(Modifiers::SHIFT, "Space"), "Shift+Space"); + } + + #[test] fn lowercase_named_key_still_reaches_the_capitalized_dispatch_form() { // `srd.bind("Super+space", ...)` (lowercase, as a real config had // it) must resolve to the exact same string a live Space keypress |