input: Make functions return the whole bind

This commit is contained in:
Ivan Molodetskikh
2024-03-22 20:27:58 +04:00
parent 4b2fdd0776
commit 6c08ba307a
3 changed files with 96 additions and 63 deletions
+1 -1
View File
@@ -716,7 +716,7 @@ impl PartialEq for Match {
#[derive(Debug, Default, PartialEq)] #[derive(Debug, Default, PartialEq)]
pub struct Binds(pub Vec<Bind>); pub struct Binds(pub Vec<Bind>);
#[derive(Debug, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Bind { pub struct Bind {
pub key: Key, pub key: Key,
pub action: Action, pub action: Action,
+93 -60
View File
@@ -3,7 +3,7 @@ use std::collections::HashSet;
use std::time::Duration; use std::time::Duration;
use input::event::gesture::GestureEventCoordinates as _; use input::event::gesture::GestureEventCoordinates as _;
use niri_config::{Action, Binds, Modifiers, Trigger}; use niri_config::{Action, Bind, Binds, Key, Modifiers, Trigger};
use niri_ipc::LayoutSwitchTarget; use niri_ipc::LayoutSwitchTarget;
use smithay::backend::input::{ use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
@@ -248,7 +248,7 @@ impl State {
let time = Event::time_msec(&event); let time = Event::time_msec(&event);
let pressed = event.state() == KeyState::Pressed; let pressed = event.state() == KeyState::Pressed;
let Some(Some(action)) = self.niri.seat.get_keyboard().unwrap().input( let Some(Some(bind)) = self.niri.seat.get_keyboard().unwrap().input(
self, self,
event.key_code(), event.key_code(),
event.state(), event.state(),
@@ -289,7 +289,7 @@ impl State {
return; return;
} }
self.do_action(action); self.do_action(bind.action);
} }
pub fn do_action(&mut self, action: Action) { pub fn do_action(&mut self, action: Action) {
@@ -1089,22 +1089,23 @@ impl State {
if let Some(v120) = horizontal_amount_v120 { if let Some(v120) = horizontal_amount_v120 {
let config = self.niri.config.borrow(); let config = self.niri.config.borrow();
let bindings = &config.binds; let bindings = &config.binds;
let action_left = bound_action(bindings, comp_mod, Trigger::WheelLeft, mods); let bind_left = find_configured_bind(bindings, comp_mod, Trigger::WheelLeft, mods);
let action_right = bound_action(bindings, comp_mod, Trigger::WheelRight, mods); let bind_right =
find_configured_bind(bindings, comp_mod, Trigger::WheelRight, mods);
drop(config); drop(config);
// If we have a bind with current modifiers along the scroll direction, then // 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. // accumulate and don't pass to Wayland. If there's no bind, reset the accumulator.
if action_left.is_some() || action_right.is_some() { if bind_left.is_some() || bind_right.is_some() {
let ticks = self.niri.horizontal_wheel_tracker.accumulate(v120); let ticks = self.niri.horizontal_wheel_tracker.accumulate(v120);
if let Some(right) = action_right { if let Some(right) = bind_right {
for _ in 0..ticks { for _ in 0..ticks {
self.do_action(right.clone()); self.do_action(right.action.clone());
} }
} }
if let Some(left) = action_left { if let Some(left) = bind_left {
for _ in ticks..0 { for _ in ticks..0 {
self.do_action(left.clone()); self.do_action(left.action.clone());
} }
} }
return; return;
@@ -1116,20 +1117,20 @@ impl State {
if let Some(v120) = vertical_amount_v120 { if let Some(v120) = vertical_amount_v120 {
let config = self.niri.config.borrow(); let config = self.niri.config.borrow();
let bindings = &config.binds; let bindings = &config.binds;
let action_up = bound_action(bindings, comp_mod, Trigger::WheelUp, mods); let bind_up = find_configured_bind(bindings, comp_mod, Trigger::WheelUp, mods);
let action_down = bound_action(bindings, comp_mod, Trigger::WheelDown, mods); let bind_down = find_configured_bind(bindings, comp_mod, Trigger::WheelDown, mods);
drop(config); drop(config);
if action_up.is_some() || action_down.is_some() { if bind_up.is_some() || bind_down.is_some() {
let ticks = self.niri.vertical_wheel_tracker.accumulate(v120); let ticks = self.niri.vertical_wheel_tracker.accumulate(v120);
if let Some(down) = action_down { if let Some(down) = bind_down {
for _ in 0..ticks { for _ in 0..ticks {
self.do_action(down.clone()); self.do_action(down.action.clone());
} }
} }
if let Some(up) = action_up { if let Some(up) = bind_up {
for _ in ticks..0 { for _ in ticks..0 {
self.do_action(up.clone()); self.do_action(up.action.clone());
} }
} }
return; return;
@@ -1687,7 +1688,7 @@ fn should_intercept_key(
mods: ModifiersState, mods: ModifiersState,
screenshot_ui: &ScreenshotUi, screenshot_ui: &ScreenshotUi,
disable_power_key_handling: bool, disable_power_key_handling: bool,
) -> FilterResult<Option<Action>> { ) -> FilterResult<Option<Bind>> {
// Actions are only triggered on presses, release of the key // Actions are only triggered on presses, release of the key
// shouldn't try to intercept anything unless we have marked // shouldn't try to intercept anything unless we have marked
// the key to suppress. // the key to suppress.
@@ -1695,7 +1696,7 @@ fn should_intercept_key(
return FilterResult::Forward; return FilterResult::Forward;
} }
let mut final_action = action( let mut final_bind = find_bind(
bindings, bindings,
comp_mod, comp_mod,
modified, modified,
@@ -1709,21 +1710,30 @@ fn should_intercept_key(
if screenshot_ui.is_open() { if screenshot_ui.is_open() {
let mut use_screenshot_ui_action = true; let mut use_screenshot_ui_action = true;
if let Some(action) = &final_action { if let Some(bind) = &final_bind {
if allowed_during_screenshot(action) { if allowed_during_screenshot(&bind.action) {
use_screenshot_ui_action = false; use_screenshot_ui_action = false;
} }
} }
if use_screenshot_ui_action { if use_screenshot_ui_action {
final_action = screenshot_ui.action(raw, mods); if let Some(raw) = raw {
final_bind = screenshot_ui.action(raw, mods).map(|action| Bind {
key: Key {
trigger: Trigger::Keysym(raw),
// Not entirely correct but it doesn't matter in how we currently use it.
modifiers: Modifiers::empty(),
},
action,
});
}
} }
} }
match (final_action, pressed) { match (final_bind, pressed) {
(Some(action), true) => { (Some(bind), true) => {
suppressed_keys.insert(key_code); suppressed_keys.insert(key_code);
FilterResult::Intercept(Some(action)) FilterResult::Intercept(Some(bind))
} }
(_, false) => { (_, false) => {
suppressed_keys.remove(&key_code); suppressed_keys.remove(&key_code);
@@ -1733,37 +1743,48 @@ fn should_intercept_key(
} }
} }
fn action( fn find_bind(
bindings: &Binds, bindings: &Binds,
comp_mod: CompositorMod, comp_mod: CompositorMod,
modified: Keysym, modified: Keysym,
raw: Option<Keysym>, raw: Option<Keysym>,
mods: ModifiersState, mods: ModifiersState,
disable_power_key_handling: bool, disable_power_key_handling: bool,
) -> Option<Action> { ) -> Option<Bind> {
use keysyms::*; use keysyms::*;
// Handle hardcoded binds. // Handle hardcoded binds.
#[allow(non_upper_case_globals)] // wat #[allow(non_upper_case_globals)] // wat
match modified.raw() { let hardcoded_action = match modified.raw() {
modified @ KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12 => { modified @ KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12 => {
let vt = (modified - KEY_XF86Switch_VT_1 + 1) as i32; let vt = (modified - KEY_XF86Switch_VT_1 + 1) as i32;
return Some(Action::ChangeVt(vt)); Some(Action::ChangeVt(vt))
} }
KEY_XF86PowerOff if !disable_power_key_handling => return Some(Action::Suspend), KEY_XF86PowerOff if !disable_power_key_handling => Some(Action::Suspend),
_ => (), _ => None,
};
if let Some(action) = hardcoded_action {
return Some(Bind {
key: Key {
// Not entirely correct but it doesn't matter in how we currently use it.
trigger: Trigger::Keysym(modified),
modifiers: Modifiers::empty(),
},
action,
});
} }
let trigger = Trigger::Keysym(raw?); let trigger = Trigger::Keysym(raw?);
bound_action(bindings, comp_mod, trigger, mods) find_configured_bind(bindings, comp_mod, trigger, mods)
} }
fn bound_action( fn find_configured_bind(
bindings: &Binds, bindings: &Binds,
comp_mod: CompositorMod, comp_mod: CompositorMod,
trigger: Trigger, trigger: Trigger,
mods: ModifiersState, mods: ModifiersState,
) -> Option<Action> { ) -> Option<Bind> {
// Handle configured binds. // Handle configured binds.
let mut modifiers = Modifiers::empty(); let mut modifiers = Modifiers::empty();
if mods.ctrl { if mods.ctrl {
@@ -1800,7 +1821,7 @@ fn bound_action(
} }
if bind_modifiers == modifiers { if bind_modifiers == modifiers {
return Some(bind.action.clone()); return Some(bind.clone());
} }
} }
@@ -1959,8 +1980,6 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input::
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use niri_config::{Bind, Key};
use super::*; use super::*;
#[test] #[test]
@@ -2026,7 +2045,10 @@ mod tests {
let filter = close_key_event(&mut suppressed_keys, mods, true); let filter = close_key_event(&mut suppressed_keys, mods, true);
assert!(matches!( assert!(matches!(
filter, filter,
FilterResult::Intercept(Some(Action::CloseWindow)) FilterResult::Intercept(Some(Bind {
action: Action::CloseWindow,
..
}))
)); ));
assert!(suppressed_keys.contains(&close_key_code)); assert!(suppressed_keys.contains(&close_key_code));
@@ -2057,7 +2079,10 @@ mod tests {
let filter = close_key_event(&mut suppressed_keys, mods, true); let filter = close_key_event(&mut suppressed_keys, mods, true);
assert!(matches!( assert!(matches!(
filter, filter,
FilterResult::Intercept(Some(Action::CloseWindow)) FilterResult::Intercept(Some(Bind {
action: Action::CloseWindow,
..
}))
)); ));
let filter = none_key_event(&mut suppressed_keys, mods, true); let filter = none_key_event(&mut suppressed_keys, mods, true);
@@ -2074,7 +2099,10 @@ mod tests {
let filter = close_key_event(&mut suppressed_keys, mods, true); let filter = close_key_event(&mut suppressed_keys, mods, true);
assert!(matches!( assert!(matches!(
filter, filter,
FilterResult::Intercept(Some(Action::CloseWindow)) FilterResult::Intercept(Some(Bind {
action: Action::CloseWindow,
..
}))
)); ));
mods = Default::default(); mods = Default::default();
@@ -2126,7 +2154,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::q), Trigger::Keysym(Keysym::q),
@@ -2134,11 +2162,12 @@ mod tests {
logo: true, logo: true,
..Default::default() ..Default::default()
} }
), )
Some(Action::CloseWindow) .as_ref(),
Some(&bindings.0[0])
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::q), Trigger::Keysym(Keysym::q),
@@ -2148,7 +2177,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::h), Trigger::Keysym(Keysym::h),
@@ -2156,11 +2185,12 @@ mod tests {
logo: true, logo: true,
..Default::default() ..Default::default()
} }
), )
Some(Action::FocusColumnLeft) .as_ref(),
Some(&bindings.0[1])
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::h), Trigger::Keysym(Keysym::h),
@@ -2170,7 +2200,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::j), Trigger::Keysym(Keysym::j),
@@ -2182,17 +2212,18 @@ mod tests {
None, None,
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::j), Trigger::Keysym(Keysym::j),
ModifiersState::default(), ModifiersState::default(),
), )
Some(Action::FocusWindowDown) .as_ref(),
Some(&bindings.0[2])
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::k), Trigger::Keysym(Keysym::k),
@@ -2200,11 +2231,12 @@ mod tests {
logo: true, logo: true,
..Default::default() ..Default::default()
} }
), )
Some(Action::FocusWindowUp) .as_ref(),
Some(&bindings.0[3])
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::k), Trigger::Keysym(Keysym::k),
@@ -2214,7 +2246,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::l), Trigger::Keysym(Keysym::l),
@@ -2223,11 +2255,12 @@ mod tests {
alt: true, alt: true,
..Default::default() ..Default::default()
} }
), )
Some(Action::FocusColumnRight) .as_ref(),
Some(&bindings.0[4])
); );
assert_eq!( assert_eq!(
bound_action( find_configured_bind(
&bindings, &bindings,
CompositorMod::Super, CompositorMod::Super,
Trigger::Keysym(Keysym::l), Trigger::Keysym(Keysym::l),
+2 -2
View File
@@ -316,12 +316,12 @@ impl ScreenshotUi {
Ok((rect.size, copy.to_vec())) Ok((rect.size, copy.to_vec()))
} }
pub fn action(&self, raw: Option<Keysym>, mods: ModifiersState) -> Option<Action> { pub fn action(&self, raw: Keysym, mods: ModifiersState) -> Option<Action> {
if !matches!(self, Self::Open { .. }) { if !matches!(self, Self::Open { .. }) {
return None; return None;
} }
action(raw?, mods) action(raw, mods)
} }
pub fn selection_output(&self) -> Option<&Output> { pub fn selection_output(&self) -> Option<&Output> {