mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
input: Make functions return the whole bind
This commit is contained in:
@@ -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
@@ -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),
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
Reference in New Issue
Block a user