aboutsummaryrefslogtreecommitdiff
path: root/src/input.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-03-23 19:20:44 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-03-23 19:20:44 +0400
commitafaaf36f27caf73b6c6b394e8f96ae362c454e61 (patch)
tree7b2a6fbdeea25ac390b05b64e0264d9a05004050 /src/input.rs
parentf1b36b0dce16d8fb8054facbc7abfecaf27eaed7 (diff)
downloadniri-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.rs148
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::*;