From 79fd309d6cf84163ff1c5c44f222e6a58dfa2872 Mon Sep 17 00:00:00 2001 From: Christian Meissl Date: Fri, 18 Oct 2024 16:00:40 +0200 Subject: support binding actions to switches (#747) * support spawn action on switch events this adds a new config section named `switch-events` that allows to bind `spawn` action to certain switch toggles. * Expand docs --------- Co-authored-by: Ivan Molodetskikh --- src/input/mod.rs | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'src/input') diff --git a/src/input/mod.rs b/src/input/mod.rs index 92475d8e..3bccb714 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -6,14 +6,15 @@ 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_config::{Action, Bind, Binds, Key, Modifiers, SwitchBinds, Trigger}; use niri_ipc::LayoutSwitchTarget; use smithay::backend::input::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, Keycode, MouseButton, PointerAxisEvent, - PointerButtonEvent, PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent, - TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent, + PointerButtonEvent, PointerMotionEvent, ProximityState, Switch, SwitchState, SwitchToggleEvent, + TabletToolButtonEvent, TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, + TabletToolTipState, TouchEvent, }; use smithay::backend::libinput::LibinputInputBackend; use smithay::input::keyboard::{keysyms, FilterResult, Keysym, ModifiersState}; @@ -127,7 +128,7 @@ impl State { TouchUp { event } => self.on_touch_up::(event), TouchCancel { event } => self.on_touch_cancel::(event), TouchFrame { event } => self.on_touch_frame::(event), - SwitchToggle { .. } => (), + SwitchToggle { event } => self.on_switch_toggle::(event), Special(_) => (), } @@ -2360,6 +2361,21 @@ impl State { }; handle.cancel(self); } + + fn on_switch_toggle(&mut self, evt: I::SwitchToggleEvent) { + let Some(switch) = evt.switch() else { + return; + }; + + let action = { + let bindings = &self.niri.config.borrow().switch_events; + find_configured_switch_action(bindings, switch, evt.state()) + }; + + if let Some(action) = action { + self.do_action(action, true); + } + } } /// Check whether the key should be intercepted and mark intercepted @@ -2511,6 +2527,23 @@ fn find_configured_bind( None } +fn find_configured_switch_action( + bindings: &SwitchBinds, + switch: Switch, + state: SwitchState, +) -> Option { + let switch_action = match (switch, state) { + (Switch::Lid, SwitchState::Off) => &bindings.lid_open, + (Switch::Lid, SwitchState::On) => &bindings.lid_close, + (Switch::TabletMode, SwitchState::Off) => &bindings.tablet_mode_off, + (Switch::TabletMode, SwitchState::On) => &bindings.tablet_mode_on, + _ => unreachable!(), + }; + switch_action + .as_ref() + .map(|switch_action| Action::Spawn(switch_action.spawn.clone())) +} + fn modifiers_from_state(mods: ModifiersState) -> Modifiers { let mut modifiers = Modifiers::empty(); if mods.ctrl { -- cgit