diff options
| -rw-r--r-- | niri-config/src/lib.rs | 52 | ||||
| -rw-r--r-- | src/backend/mod.rs | 15 | ||||
| -rw-r--r-- | src/input/mod.rs | 134 | ||||
| -rw-r--r-- | src/niri.rs | 25 | ||||
| -rw-r--r-- | src/ui/hotkey_overlay.rs | 71 |
5 files changed, 167 insertions, 130 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 394a2b36..99628649 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -100,6 +100,10 @@ pub struct Input { pub focus_follows_mouse: Option<FocusFollowsMouse>, #[knuffel(child)] pub workspace_auto_back_and_forth: bool, + #[knuffel(child, unwrap(argument, str))] + pub mod_key: Option<ModKey>, + #[knuffel(child, unwrap(argument, str))] + pub mod_key_nested: Option<ModKey>, } #[derive(knuffel::Decode, Debug, PartialEq, Eq)] @@ -368,6 +372,29 @@ pub struct FocusFollowsMouse { #[derive(Debug, Clone, Copy, PartialEq)] pub struct Percent(pub f64); +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum ModKey { + Ctrl, + Shift, + Alt, + Super, + IsoLevel3Shift, + IsoLevel5Shift, +} + +impl ModKey { + pub fn to_modifiers(&self) -> Modifiers { + match self { + ModKey::Ctrl => Modifiers::CTRL, + ModKey::Shift => Modifiers::SHIFT, + ModKey::Alt => Modifiers::ALT, + ModKey::Super => Modifiers::SUPER, + ModKey::IsoLevel3Shift => Modifiers::ISO_LEVEL3_SHIFT, + ModKey::IsoLevel5Shift => Modifiers::ISO_LEVEL5_SHIFT, + } + } +} + #[derive(Debug, Default, Clone, PartialEq)] pub struct Outputs(pub Vec<Output>); @@ -3427,6 +3454,22 @@ where } } +impl FromStr for ModKey { + type Err = miette::Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match &*s.to_ascii_lowercase() { + "ctrl" | "control" => Ok(Self::Ctrl), + "shift" => Ok(Self::Shift), + "alt" => Ok(Self::Alt), + "super" | "win" => Ok(Self::Super), + "iso_level3_shift" | "mod5" => Ok(Self::IsoLevel3Shift), + "iso_level5_shift" | "mod3" => Ok(Self::IsoLevel5Shift), + _ => Err(miette!("invalid Mod key: {s}")), + } + } +} + impl FromStr for Key { type Err = miette::Error; @@ -3664,6 +3707,9 @@ mod tests { warp-mouse-to-focus focus-follows-mouse workspace-auto-back-and-forth + + mod-key "Mod5" + mod-key-nested "Super" } output "eDP-1" { @@ -3984,6 +4030,12 @@ mod tests { }, ), workspace_auto_back_and_forth: true, + mod_key: Some( + IsoLevel3Shift, + ), + mod_key_nested: Some( + Super, + ), }, outputs: Outputs( [ diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e23947c5..2aa97bc0 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -2,12 +2,12 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; +use niri_config::{Config, ModKey}; use smithay::backend::allocator::dmabuf::Dmabuf; use smithay::backend::renderer::gles::GlesRenderer; use smithay::output::Output; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; -use crate::input::CompositorMod; use crate::niri::Niri; use crate::utils::id::IdCounter; @@ -94,11 +94,16 @@ impl Backend { } } - pub fn mod_key(&self) -> CompositorMod { + pub fn mod_key(&self, config: &Config) -> ModKey { match self { - Backend::Tty(_) => CompositorMod::Super, - Backend::Winit(_) => CompositorMod::Alt, - Backend::Headless(_) => CompositorMod::Super, + Backend::Winit(_) => config.input.mod_key_nested.unwrap_or({ + if let Some(ModKey::Alt) = config.input.mod_key { + ModKey::Super + } else { + ModKey::Alt + } + }), + Backend::Tty(_) | Backend::Headless(_) => config.input.mod_key.unwrap_or(ModKey::Super), } } diff --git a/src/input/mod.rs b/src/input/mod.rs index c9677ba2..8fb5acb6 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -6,7 +6,7 @@ use std::time::Duration; use calloop::timer::{TimeoutAction, Timer}; use input::event::gesture::GestureEventCoordinates as _; -use niri_config::{Action, Bind, Binds, Key, Modifiers, SwitchBinds, Trigger}; +use niri_config::{Action, Bind, Binds, Key, ModKey, Modifiers, SwitchBinds, Trigger}; use niri_ipc::LayoutSwitchTarget; use smithay::backend::input::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, @@ -60,12 +60,6 @@ use backend_ext::{NiriInputBackend as InputBackend, NiriInputDevice as _}; pub const DOUBLE_CLICK_TIME: Duration = Duration::from_millis(400); -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum CompositorMod { - Super, - Alt, -} - #[derive(Debug, Clone, Copy, PartialEq)] pub struct TabletData { pub aspect_ratio: f64, @@ -336,7 +330,7 @@ impl State { } fn on_keyboard<I: InputBackend>(&mut self, event: I::KeyboardKeyEvent) { - let comp_mod = self.backend.mod_key(); + let mod_key = self.backend.mod_key(&self.niri.config.borrow()); let serial = SERIAL_COUNTER.next_serial(); let time = Event::time_msec(&event); @@ -399,7 +393,7 @@ impl State { should_intercept_key( &mut this.niri.suppressed_keys, bindings, - comp_mod, + mod_key, key_code, modified, raw, @@ -2118,6 +2112,8 @@ impl State { let button_state = event.state(); + let mod_key = self.backend.mod_key(&self.niri.config.borrow()); + // Ignore release events for mouse clicks that triggered a bind. if self.niri.suppressed_buttons.remove(&button_code) { return; @@ -2128,8 +2124,6 @@ impl State { let modifiers = modifiers_from_state(mods); if self.niri.mods_with_mouse_binds.contains(&modifiers) { - let comp_mod = self.backend.mod_key(); - if let Some(bind) = match button { Some(MouseButton::Left) => Some(Trigger::MouseLeft), Some(MouseButton::Right) => Some(Trigger::MouseRight), @@ -2141,7 +2135,7 @@ impl State { .and_then(|trigger| { let config = self.niri.config.borrow(); let bindings = &config.binds; - find_configured_bind(bindings, comp_mod, trigger, mods) + find_configured_bind(bindings, mod_key, trigger, mods) }) { self.niri.suppressed_buttons.insert(button_code); self.handle_bind(bind.clone()); @@ -2154,10 +2148,7 @@ impl State { self.niri.tablet_cursor_location = None; if button == Some(MouseButton::Middle) && !pointer.is_grabbed() { - let mod_down = match self.backend.mod_key() { - CompositorMod::Super => mods.logo, - CompositorMod::Alt => mods.alt, - }; + let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers()); if mod_down { if let Some(output) = self.niri.output_under_cursor() { self.niri.layout.activate_output(&output); @@ -2189,10 +2180,7 @@ impl State { // Check if we need to start an interactive move. if button == Some(MouseButton::Left) && !pointer.is_grabbed() { - let mod_down = match self.backend.mod_key() { - CompositorMod::Super => mods.logo, - CompositorMod::Alt => mods.alt, - }; + let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers()); if mod_down { let location = pointer.current_location(); let (output, pos_within_output) = self.niri.output_under(location).unwrap(); @@ -2220,10 +2208,7 @@ impl State { } // Check if we need to start an interactive resize. else if button == Some(MouseButton::Right) && !pointer.is_grabbed() { - let mod_down = match self.backend.mod_key() { - CompositorMod::Super => mods.logo, - CompositorMod::Alt => mods.alt, - }; + let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers()); if mod_down { let location = pointer.current_location(); let (output, pos_within_output) = self.niri.output_under(location).unwrap(); @@ -2353,6 +2338,8 @@ impl State { let source = event.source(); + let mod_key = self.backend.mod_key(&self.niri.config.borrow()); + // We received an event for the regular pointer, so show it now. This is also needed for // update_pointer_contents() below to return the real contents, necessary for the pointer // axis event to reach the window. @@ -2369,17 +2356,15 @@ impl State { let mods = self.niri.seat.get_keyboard().unwrap().modifier_state(); let modifiers = modifiers_from_state(mods); if self.niri.mods_with_wheel_binds.contains(&modifiers) { - let comp_mod = self.backend.mod_key(); - let horizontal = horizontal_amount_v120.unwrap_or(0.); let ticks = self.niri.horizontal_wheel_tracker.accumulate(horizontal); if ticks != 0 { let config = self.niri.config.borrow(); let bindings = &config.binds; let bind_left = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollLeft, mods); + find_configured_bind(bindings, mod_key, Trigger::WheelScrollLeft, mods); let bind_right = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollRight, mods); + find_configured_bind(bindings, mod_key, Trigger::WheelScrollRight, mods); drop(config); if let Some(right) = bind_right { @@ -2400,9 +2385,9 @@ impl State { let config = self.niri.config.borrow(); let bindings = &config.binds; let bind_up = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollUp, mods); + find_configured_bind(bindings, mod_key, Trigger::WheelScrollUp, mods); let bind_down = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollDown, mods); + find_configured_bind(bindings, mod_key, Trigger::WheelScrollDown, mods); drop(config); if let Some(down) = bind_down { @@ -2432,8 +2417,6 @@ impl State { let mods = self.niri.seat.get_keyboard().unwrap().modifier_state(); let modifiers = modifiers_from_state(mods); if self.niri.mods_with_finger_scroll_binds.contains(&modifiers) { - let comp_mod = self.backend.mod_key(); - let horizontal = horizontal_amount.unwrap_or(0.); let ticks = self .niri @@ -2443,13 +2426,9 @@ impl State { let config = self.niri.config.borrow(); let bindings = &config.binds; let bind_left = - find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollLeft, mods); - let bind_right = find_configured_bind( - bindings, - comp_mod, - Trigger::TouchpadScrollRight, - mods, - ); + find_configured_bind(bindings, mod_key, Trigger::TouchpadScrollLeft, mods); + let bind_right = + find_configured_bind(bindings, mod_key, Trigger::TouchpadScrollRight, mods); drop(config); if let Some(right) = bind_right { @@ -2473,9 +2452,9 @@ impl State { let config = self.niri.config.borrow(); let bindings = &config.binds; let bind_up = - find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollUp, mods); + find_configured_bind(bindings, mod_key, Trigger::TouchpadScrollUp, mods); let bind_down = - find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollDown, mods); + find_configured_bind(bindings, mod_key, Trigger::TouchpadScrollDown, mods); drop(config); if let Some(down) = bind_down { @@ -2987,16 +2966,15 @@ impl State { let under = self.niri.contents_under(touch_location); + let mod_key = self.backend.mod_key(&self.niri.config.borrow()); + if !handle.is_grabbed() { if let Some((window, _)) = under.window { self.niri.layout.activate_window(&window); // Check if we need to start an interactive move. let mods = self.niri.seat.get_keyboard().unwrap().modifier_state(); - let mod_down = match self.backend.mod_key() { - CompositorMod::Super => mods.logo, - CompositorMod::Alt => mods.alt, - }; + let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers()); if mod_down { let (output, pos_within_output) = self.niri.output_under(touch_location).unwrap(); @@ -3129,7 +3107,7 @@ impl State { fn should_intercept_key( suppressed_keys: &mut HashSet<Keycode>, bindings: &Binds, - comp_mod: CompositorMod, + mod_key: ModKey, key_code: Keycode, modified: Keysym, raw: Option<Keysym>, @@ -3148,7 +3126,7 @@ fn should_intercept_key( let mut final_bind = find_bind( bindings, - comp_mod, + mod_key, modified, raw, mods, @@ -3212,7 +3190,7 @@ fn should_intercept_key( fn find_bind( bindings: &Binds, - comp_mod: CompositorMod, + mod_key: ModKey, modified: Keysym, raw: Option<Keysym>, mods: ModifiersState, @@ -3253,22 +3231,19 @@ fn find_bind( } let trigger = Trigger::Keysym(raw?); - find_configured_bind(bindings, comp_mod, trigger, mods) + find_configured_bind(bindings, mod_key, trigger, mods) } fn find_configured_bind( bindings: &Binds, - comp_mod: CompositorMod, + mod_key: ModKey, trigger: Trigger, mods: ModifiersState, ) -> Option<Bind> { // Handle configured binds. let mut modifiers = modifiers_from_state(mods); - let (mod_down, comp_mod) = match comp_mod { - CompositorMod::Super => (mods.logo, Modifiers::SUPER), - CompositorMod::Alt => (mods.alt, Modifiers::ALT), - }; + let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers()); if mod_down { modifiers |= Modifiers::COMPOSITOR; } @@ -3280,8 +3255,8 @@ fn find_configured_bind( let mut bind_modifiers = bind.key.modifiers; if bind_modifiers.contains(Modifiers::COMPOSITOR) { - bind_modifiers |= comp_mod; - } else if bind_modifiers.contains(comp_mod) { + bind_modifiers |= mod_key.to_modifiers(); + } else if bind_modifiers.contains(mod_key.to_modifiers()) { bind_modifiers |= Modifiers::COMPOSITOR; } @@ -3661,16 +3636,7 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input:: } } -pub fn mods_with_binds( - comp_mod: CompositorMod, - binds: &Binds, - triggers: &[Trigger], -) -> HashSet<Modifiers> { - let comp_mod = match comp_mod { - CompositorMod::Super => Modifiers::SUPER, - CompositorMod::Alt => Modifiers::ALT, - }; - +pub fn mods_with_binds(mod_key: ModKey, binds: &Binds, triggers: &[Trigger]) -> HashSet<Modifiers> { let mut rv = HashSet::new(); for bind in &binds.0 { if !triggers.iter().any(|trigger| bind.key.trigger == *trigger) { @@ -3680,7 +3646,7 @@ pub fn mods_with_binds( let mut mods = bind.key.modifiers; if mods.contains(Modifiers::COMPOSITOR) { mods.remove(Modifiers::COMPOSITOR); - mods.insert(comp_mod); + mods.insert(mod_key.to_modifiers()); } rv.insert(mods); @@ -3689,9 +3655,9 @@ pub fn mods_with_binds( rv } -pub fn mods_with_mouse_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<Modifiers> { +pub fn mods_with_mouse_binds(mod_key: ModKey, binds: &Binds) -> HashSet<Modifiers> { mods_with_binds( - comp_mod, + mod_key, binds, &[ Trigger::MouseLeft, @@ -3703,9 +3669,9 @@ pub fn mods_with_mouse_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet< ) } -pub fn mods_with_wheel_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<Modifiers> { +pub fn mods_with_wheel_binds(mod_key: ModKey, binds: &Binds) -> HashSet<Modifiers> { mods_with_binds( - comp_mod, + mod_key, binds, &[ Trigger::WheelScrollUp, @@ -3716,9 +3682,9 @@ pub fn mods_with_wheel_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet< ) } -pub fn mods_with_finger_scroll_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<Modifiers> { +pub fn mods_with_finger_scroll_binds(mod_key: ModKey, binds: &Binds) -> HashSet<Modifiers> { mods_with_binds( - comp_mod, + mod_key, binds, &[ Trigger::TouchpadScrollUp, @@ -3752,7 +3718,7 @@ mod tests { hotkey_overlay_title: None, }]); - let comp_mod = CompositorMod::Super; + let comp_mod = ModKey::Super; let mut suppressed_keys = HashSet::new(); let screenshot_ui = ScreenshotUi::new(Clock::default(), Default::default()); @@ -3990,7 +3956,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::q), ModifiersState { logo: true, @@ -4003,7 +3969,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::q), ModifiersState::default(), ), @@ -4013,7 +3979,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::h), ModifiersState { logo: true, @@ -4026,7 +3992,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::h), ModifiersState::default(), ), @@ -4036,7 +4002,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::j), ModifiersState { logo: true, @@ -4048,7 +4014,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::j), ModifiersState::default(), ) @@ -4059,7 +4025,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::k), ModifiersState { logo: true, @@ -4072,7 +4038,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::k), ModifiersState::default(), ), @@ -4082,7 +4048,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::l), ModifiersState { logo: true, @@ -4096,7 +4062,7 @@ mod tests { assert_eq!( find_configured_bind( &bindings, - CompositorMod::Super, + ModKey::Super, Trigger::Keysym(Keysym::l), ModifiersState { logo: true, diff --git a/src/niri.rs b/src/niri.rs index e85ec938..ac8b90a3 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -1247,14 +1247,15 @@ impl State { preserved_output_config = Some(mem::take(&mut old_config.outputs)); } - if config.binds != old_config.binds { - self.niri.hotkey_overlay.on_hotkey_config_updated(); - self.niri.mods_with_mouse_binds = - mods_with_mouse_binds(self.backend.mod_key(), &config.binds); - self.niri.mods_with_wheel_binds = - mods_with_wheel_binds(self.backend.mod_key(), &config.binds); + let new_mod_key = self.backend.mod_key(&config); + if new_mod_key != self.backend.mod_key(&old_config) || config.binds != old_config.binds { + self.niri + .hotkey_overlay + .on_hotkey_config_updated(new_mod_key); + self.niri.mods_with_mouse_binds = mods_with_mouse_binds(new_mod_key, &config.binds); + self.niri.mods_with_wheel_binds = mods_with_wheel_binds(new_mod_key, &config.binds); self.niri.mods_with_finger_scroll_binds = - mods_with_finger_scroll_binds(self.backend.mod_key(), &config.binds); + mods_with_finger_scroll_binds(new_mod_key, &config.binds); } if config.window_rules != old_config.window_rules { @@ -2135,16 +2136,16 @@ impl Niri { let cursor_manager = CursorManager::new(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size); - let mods_with_mouse_binds = mods_with_mouse_binds(backend.mod_key(), &config_.binds); - let mods_with_wheel_binds = mods_with_wheel_binds(backend.mod_key(), &config_.binds); - let mods_with_finger_scroll_binds = - mods_with_finger_scroll_binds(backend.mod_key(), &config_.binds); + let mod_key = backend.mod_key(&config.borrow()); + let mods_with_mouse_binds = mods_with_mouse_binds(mod_key, &config_.binds); + let mods_with_wheel_binds = mods_with_wheel_binds(mod_key, &config_.binds); + let mods_with_finger_scroll_binds = mods_with_finger_scroll_binds(mod_key, &config_.binds); let screenshot_ui = ScreenshotUi::new(animation_clock.clone(), config.clone()); let config_error_notification = ConfigErrorNotification::new(animation_clock.clone(), config.clone()); - let mut hotkey_overlay = HotkeyOverlay::new(config.clone(), backend.mod_key()); + let mut hotkey_overlay = HotkeyOverlay::new(config.clone(), mod_key); if !config_.hotkey_overlay.skip_at_startup { hotkey_overlay.show(); } diff --git a/src/ui/hotkey_overlay.rs b/src/ui/hotkey_overlay.rs index 29e96e2a..518488e2 100644 --- a/src/ui/hotkey_overlay.rs +++ b/src/ui/hotkey_overlay.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use std::iter::zip; use std::rc::Rc; -use niri_config::{Action, Bind, Config, Key, Modifiers, Trigger}; +use niri_config::{Action, Bind, Config, Key, ModKey, Modifiers, Trigger}; use pangocairo::cairo::{self, ImageSurface}; use pangocairo::pango::{AttrColor, AttrInt, AttrList, AttrString, FontDescription, Weight}; use smithay::backend::renderer::element::Kind; @@ -14,7 +14,6 @@ use smithay::output::{Output, WeakOutput}; use smithay::reexports::gbm::Format as Fourcc; use smithay::utils::{Scale, Transform}; -use crate::input::CompositorMod; use crate::render_helpers::primary_gpu_texture::PrimaryGpuTextureRenderElement; use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::texture::{TextureBuffer, TextureRenderElement}; @@ -30,7 +29,7 @@ const TITLE: &str = "Important Hotkeys"; pub struct HotkeyOverlay { is_open: bool, config: Rc<RefCell<Config>>, - comp_mod: CompositorMod, + mod_key: ModKey, buffers: RefCell<HashMap<WeakOutput, RenderedOverlay>>, } @@ -39,11 +38,11 @@ pub struct RenderedOverlay { } impl HotkeyOverlay { - pub fn new(config: Rc<RefCell<Config>>, comp_mod: CompositorMod) -> Self { + pub fn new(config: Rc<RefCell<Config>>, mod_key: ModKey) -> Self { Self { is_open: false, config, - comp_mod, + mod_key, buffers: RefCell::new(HashMap::new()), } } @@ -70,7 +69,8 @@ impl HotkeyOverlay { self.is_open } - pub fn on_hotkey_config_updated(&mut self) { + pub fn on_hotkey_config_updated(&mut self, mod_key: ModKey) { + self.mod_key = mod_key; self.buffers.borrow_mut().clear(); } @@ -101,7 +101,7 @@ impl HotkeyOverlay { let rendered = buffers.entry(weak).or_insert_with(|| { let renderer = renderer.as_gles_renderer(); - render(renderer, &self.config.borrow(), self.comp_mod, scale) + render(renderer, &self.config.borrow(), self.mod_key, scale) .unwrap_or_else(|_| RenderedOverlay { buffer: None }) }); let buffer = rendered.buffer.as_ref()?; @@ -125,11 +125,7 @@ impl HotkeyOverlay { } } -fn format_bind( - binds: &[Bind], - comp_mod: CompositorMod, - action: &Action, -) -> Option<(String, String)> { +fn format_bind(binds: &[Bind], mod_key: ModKey, action: &Action) -> Option<(String, String)> { let mut bind_with_non_null = None; let mut bind_with_custom_title = None; let mut found_null_title = false; @@ -162,7 +158,7 @@ fn format_bind( title = Some(custom.clone()); } - key_name(comp_mod, &bind.key) + key_name(mod_key, &bind.key) } else { String::from("(not bound)") }; @@ -174,7 +170,7 @@ fn format_bind( fn render( renderer: &mut GlesRenderer, config: &Config, - comp_mod: CompositorMod, + mod_key: ModKey, scale: f64, ) -> anyhow::Result<RenderedOverlay> { let _span = tracy_client::span!("hotkey_overlay::render"); @@ -290,7 +286,7 @@ fn render( let strings = actions .into_iter() - .filter_map(|action| format_bind(binds, comp_mod, action)) + .filter_map(|action| format_bind(binds, mod_key, action)) .collect::<Vec<_>>(); let mut font = FontDescription::from_string(FONT); @@ -448,38 +444,55 @@ fn action_name(action: &Action) -> String { } } -fn key_name(comp_mod: CompositorMod, key: &Key) -> String { +fn key_name(mod_key: ModKey, key: &Key) -> String { let mut name = String::new(); let has_comp_mod = key.modifiers.contains(Modifiers::COMPOSITOR); // Compositor mod goes first. if has_comp_mod { - if comp_mod == CompositorMod::Super { - name.push_str("Super + "); - } else if comp_mod == CompositorMod::Alt { - name.push_str("Alt + "); + match mod_key { + ModKey::Super => { + name.push_str("Super + "); + } + ModKey::Alt => { + name.push_str("Alt + "); + } + ModKey::Shift => { + name.push_str("Shift + "); + } + ModKey::Ctrl => { + name.push_str("Ctrl + "); + } + ModKey::IsoLevel3Shift => { + name.push_str("ISO_Level3_Shift + "); + } + ModKey::IsoLevel5Shift => { + name.push_str("ISO_Level5_Shift + "); + } } } - if key.modifiers.contains(Modifiers::SUPER) - && !(has_comp_mod && comp_mod == CompositorMod::Super) - { + if key.modifiers.contains(Modifiers::SUPER) && !(has_comp_mod && mod_key == ModKey::Super) { name.push_str("Super + "); } - if key.modifiers.contains(Modifiers::CTRL) { + if key.modifiers.contains(Modifiers::CTRL) && !(has_comp_mod && mod_key == ModKey::Ctrl) { name.push_str("Ctrl + "); } - if key.modifiers.contains(Modifiers::SHIFT) { + if key.modifiers.contains(Modifiers::SHIFT) && !(has_comp_mod && mod_key == ModKey::Shift) { name.push_str("Shift + "); } - if key.modifiers.contains(Modifiers::ALT) && !(has_comp_mod && comp_mod == CompositorMod::Alt) { + if key.modifiers.contains(Modifiers::ALT) && !(has_comp_mod && mod_key == ModKey::Alt) { name.push_str("Alt + "); } - if key.modifiers.contains(Modifiers::ISO_LEVEL3_SHIFT) { + if key.modifiers.contains(Modifiers::ISO_LEVEL3_SHIFT) + && !(has_comp_mod && mod_key == ModKey::IsoLevel3Shift) + { name.push_str("ISO_Level3_Shift + "); } - if key.modifiers.contains(Modifiers::ISO_LEVEL5_SHIFT) { + if key.modifiers.contains(Modifiers::ISO_LEVEL5_SHIFT) + && !(has_comp_mod && mod_key == ModKey::IsoLevel5Shift) + { name.push_str("ISO_Level5_Shift + "); } @@ -538,7 +551,7 @@ mod tests { #[track_caller] fn check(config: &str, action: Action) -> String { let config = Config::parse("test.kdl", config).unwrap(); - if let Some((key, title)) = format_bind(&config.binds.0, CompositorMod::Super, &action) { + if let Some((key, title)) = format_bind(&config.binds.0, ModKey::Super, &action) { format!("{key}: {title}") } else { String::from("None") |
