aboutsummaryrefslogtreecommitdiff
path: root/src/input.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-03-22 20:47:40 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-03-22 20:47:40 +0400
commitb06e51da60505bba42ef310d510f38440b897f9b (patch)
treea7440c6ea6f59dd2fbdf2e2771a562640c949a05 /src/input.rs
parent6c08ba307aef03938e009601ac81bc140c38a1dd (diff)
downloadniri-b06e51da60505bba42ef310d510f38440b897f9b.tar.gz
niri-b06e51da60505bba42ef310d510f38440b897f9b.tar.bz2
niri-b06e51da60505bba42ef310d510f38440b897f9b.zip
Implement bind cooldown-ms
Diffstat (limited to 'src/input.rs')
-rw-r--r--src/input.rs53
1 files changed, 48 insertions, 5 deletions
diff --git a/src/input.rs b/src/input.rs
index aa08d580..b4e44974 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,7 +1,9 @@
use std::any::Any;
+use std::collections::hash_map::Entry;
use std::collections::HashSet;
use std::time::Duration;
+use calloop::timer::{TimeoutAction, Timer};
use input::event::gesture::GestureEventCoordinates as _;
use niri_config::{Action, Bind, Binds, Key, Modifiers, Trigger};
use niri_ipc::LayoutSwitchTarget;
@@ -289,7 +291,40 @@ impl State {
return;
}
- self.do_action(bind.action);
+ self.handle_bind(bind);
+ }
+
+ pub fn handle_bind(&mut self, bind: Bind) {
+ let Some(cooldown) = bind.cooldown else {
+ self.do_action(bind.action);
+ return;
+ };
+
+ // Check this first so that it doesn't trigger the cooldown.
+ if self.niri.is_locked() && !allowed_when_locked(&bind.action) {
+ return;
+ }
+
+ match self.niri.bind_cooldown_timers.entry(bind.key) {
+ // The bind is on cooldown.
+ Entry::Occupied(_) => (),
+ Entry::Vacant(entry) => {
+ let timer = Timer::from_duration(cooldown);
+ let token = self
+ .niri
+ .event_loop
+ .insert_source(timer, move |_, _, state| {
+ if state.niri.bind_cooldown_timers.remove(&bind.key).is_none() {
+ error!("bind cooldown timer entry disappeared");
+ }
+ TimeoutAction::Drop
+ })
+ .unwrap();
+ entry.insert(token);
+
+ self.do_action(bind.action);
+ }
+ }
}
pub fn do_action(&mut self, action: Action) {
@@ -1100,12 +1135,12 @@ impl State {
let ticks = self.niri.horizontal_wheel_tracker.accumulate(v120);
if let Some(right) = bind_right {
for _ in 0..ticks {
- self.do_action(right.action.clone());
+ self.handle_bind(right.clone());
}
}
if let Some(left) = bind_left {
for _ in ticks..0 {
- self.do_action(left.action.clone());
+ self.handle_bind(left.clone());
}
}
return;
@@ -1125,12 +1160,12 @@ impl State {
let ticks = self.niri.vertical_wheel_tracker.accumulate(v120);
if let Some(down) = bind_down {
for _ in 0..ticks {
- self.do_action(down.action.clone());
+ self.handle_bind(down.clone());
}
}
if let Some(up) = bind_up {
for _ in ticks..0 {
- self.do_action(up.action.clone());
+ self.handle_bind(up.clone());
}
}
return;
@@ -1725,6 +1760,7 @@ fn should_intercept_key(
modifiers: Modifiers::empty(),
},
action,
+ cooldown: None,
});
}
}
@@ -1772,6 +1808,7 @@ fn find_bind(
modifiers: Modifiers::empty(),
},
action,
+ cooldown: None,
});
}
@@ -1991,6 +2028,7 @@ mod tests {
modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL,
},
action: Action::CloseWindow,
+ cooldown: None,
}]);
let comp_mod = CompositorMod::Super;
@@ -2122,6 +2160,7 @@ mod tests {
modifiers: Modifiers::COMPOSITOR,
},
action: Action::CloseWindow,
+ cooldown: None,
},
Bind {
key: Key {
@@ -2129,6 +2168,7 @@ mod tests {
modifiers: Modifiers::SUPER,
},
action: Action::FocusColumnLeft,
+ cooldown: None,
},
Bind {
key: Key {
@@ -2136,6 +2176,7 @@ mod tests {
modifiers: Modifiers::empty(),
},
action: Action::FocusWindowDown,
+ cooldown: None,
},
Bind {
key: Key {
@@ -2143,6 +2184,7 @@ mod tests {
modifiers: Modifiers::COMPOSITOR | Modifiers::SUPER,
},
action: Action::FocusWindowUp,
+ cooldown: None,
},
Bind {
key: Key {
@@ -2150,6 +2192,7 @@ mod tests {
modifiers: Modifiers::SUPER | Modifiers::ALT,
},
action: Action::FocusColumnRight,
+ cooldown: None,
},
]);