srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/core/src/event.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2024-11-30 23:03:00 +0200
committersrdusr <[email protected]>2024-11-30 23:03:00 +0200
commit583063c3094ca0cf9f6cceba92d710b238547f6b (patch)
treea1ff8f181027892f4a45846b67898beb136a9312 /crates/core/src/event.rs
parent87f5c04b2593dc49409644e69e7962b73d26b9d8 (diff)
downloadsrdwm-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.rs48
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