diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-23 19:20:44 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-23 19:20:44 +0400 |
| commit | afaaf36f27caf73b6c6b394e8f96ae362c454e61 (patch) | |
| tree | 7b2a6fbdeea25ac390b05b64e0264d9a05004050 /src/input.rs | |
| parent | f1b36b0dce16d8fb8054facbc7abfecaf27eaed7 (diff) | |
| download | niri-afaaf36f27caf73b6c6b394e8f96ae362c454e61.tar.gz niri-afaaf36f27caf73b6c6b394e8f96ae362c454e61.tar.bz2 niri-afaaf36f27caf73b6c6b394e8f96ae362c454e61.zip | |
Avoid scroll bind lookup until it is triggered
Diffstat (limited to 'src/input.rs')
| -rw-r--r-- | src/input.rs | 148 |
1 files changed, 92 insertions, 56 deletions
diff --git a/src/input.rs b/src/input.rs index f01d66a5..850fb76a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1118,26 +1118,24 @@ impl State { // Handle wheel scroll bindings. if source == AxisSource::Wheel { - let comp_mod = self.backend.mod_key(); + // If we have a scroll bind with current modifiers, then accumulate and don't pass to + // Wayland. If there's no bind, reset the accumulator. 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); + let bind_right = + find_configured_bind(bindings, comp_mod, Trigger::WheelScrollRight, mods); + drop(config); - // Winit sends scroll events where both directions are set at once, so we can't early - // return after handling just one. - let mut handled = false; - - if let Some(v120) = horizontal_amount_v120 { - let config = self.niri.config.borrow(); - let bindings = &config.binds; - let bind_left = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollLeft, mods); - let bind_right = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollRight, mods); - drop(config); - - // If we have a bind with current modifiers along the scroll direction, then - // accumulate and don't pass to Wayland. If there's no bind, reset the accumulator. - if bind_left.is_some() || bind_right.is_some() { - let ticks = self.niri.horizontal_wheel_tracker.accumulate(v120); if let Some(right) = bind_right { for _ in 0..ticks { self.handle_bind(right.clone()); @@ -1148,24 +1146,19 @@ impl State { self.handle_bind(left.clone()); } } - - handled = true; - } else { - self.niri.horizontal_wheel_tracker.reset(); } - } - if let Some(v120) = vertical_amount_v120 { - let config = self.niri.config.borrow(); - let bindings = &config.binds; - let bind_up = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollUp, mods); - let bind_down = - find_configured_bind(bindings, comp_mod, Trigger::WheelScrollDown, mods); - drop(config); - - if bind_up.is_some() || bind_down.is_some() { - let ticks = self.niri.vertical_wheel_tracker.accumulate(v120); + let vertical = vertical_amount_v120.unwrap_or(0.); + let ticks = self.niri.vertical_wheel_tracker.accumulate(vertical); + if ticks != 0 { + let config = self.niri.config.borrow(); + let bindings = &config.binds; + let bind_up = + find_configured_bind(bindings, comp_mod, Trigger::WheelScrollUp, mods); + let bind_down = + find_configured_bind(bindings, comp_mod, Trigger::WheelScrollDown, mods); + drop(config); + if let Some(down) = bind_down { for _ in 0..ticks { self.handle_bind(down.clone()); @@ -1176,15 +1169,12 @@ impl State { self.handle_bind(up.clone()); } } - - handled = true; - } else { - self.niri.vertical_wheel_tracker.reset(); } - } - if handled { return; + } else { + self.niri.horizontal_wheel_tracker.reset(); + self.niri.vertical_wheel_tracker.reset(); } } @@ -1836,22 +1826,7 @@ fn find_configured_bind( mods: ModifiersState, ) -> Option<Bind> { // Handle configured binds. - let mut modifiers = Modifiers::empty(); - if mods.ctrl { - modifiers |= Modifiers::CTRL; - } - if mods.shift { - modifiers |= Modifiers::SHIFT; - } - if mods.alt { - modifiers |= Modifiers::ALT; - } - if mods.logo { - modifiers |= Modifiers::SUPER; - } - if mods.iso_level3_shift { - modifiers |= Modifiers::ISO_LEVEL3_SHIFT; - } + let mut modifiers = modifiers_from_state(mods); let (mod_down, comp_mod) = match comp_mod { CompositorMod::Super => (mods.logo, Modifiers::SUPER), @@ -1881,6 +1856,26 @@ fn find_configured_bind( None } +fn modifiers_from_state(mods: ModifiersState) -> Modifiers { + let mut modifiers = Modifiers::empty(); + if mods.ctrl { + modifiers |= Modifiers::CTRL; + } + if mods.shift { + modifiers |= Modifiers::SHIFT; + } + if mods.alt { + modifiers |= Modifiers::ALT; + } + if mods.logo { + modifiers |= Modifiers::SUPER; + } + if mods.iso_level3_shift { + modifiers |= Modifiers::ISO_LEVEL3_SHIFT; + } + modifiers +} + fn should_activate_monitors<I: InputBackend>(event: &InputEvent<I>) -> bool { match event { InputEvent::Keyboard { event } if event.state() == KeyState::Pressed => true, @@ -2031,6 +2026,47 @@ 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, + }; + + let mut rv = HashSet::new(); + for bind in &binds.0 { + if !triggers.iter().any(|trigger| bind.key.trigger == *trigger) { + continue; + } + + let mut mods = bind.key.modifiers; + if mods.contains(Modifiers::COMPOSITOR) { + mods.remove(Modifiers::COMPOSITOR); + mods.insert(comp_mod); + } + + rv.insert(mods); + } + + rv +} + +pub fn mods_with_wheel_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<Modifiers> { + mods_with_binds( + comp_mod, + binds, + &[ + Trigger::WheelScrollUp, + Trigger::WheelScrollDown, + Trigger::WheelScrollLeft, + Trigger::WheelScrollRight, + ], + ) +} + #[cfg(test)] mod tests { use super::*; |
