From 44849fa871285cb8a99a50fbcf09e1c59ef56218 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 27 Oct 2023 16:50:02 +0400 Subject: [PATCH] Don't send key on release from niri actions Some clients run logic on `Release`, thus don't send the key originally used for running `niri` actions. Fixes #28. --- src/config.rs | 2 - src/input.rs | 412 ++++++++++++++++++++++++-------------------------- 2 files changed, 200 insertions(+), 214 deletions(-) diff --git a/src/config.rs b/src/config.rs index 1570b7373..10309f537 100644 --- a/src/config.rs +++ b/src/config.rs @@ -229,8 +229,6 @@ bitflags! { #[derive(knuffel::Decode, Debug, Clone, PartialEq)] pub enum Action { - #[knuffel(skip)] - None, Quit, #[knuffel(skip)] ChangeVt(i32), diff --git a/src/input.rs b/src/input.rs index 157edb595..08c4d3446 100644 --- a/src/input.rs +++ b/src/input.rs @@ -24,21 +24,12 @@ pub enum CompositorMod { Alt, } -impl From for FilterResult { - fn from(value: Action) -> Self { - match value { - Action::None => FilterResult::Forward, - action => FilterResult::Intercept(action), - } - } -} - fn action( config: &Config, comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState, -) -> Action { +) -> Option { use keysyms::*; // Handle hardcoded binds. @@ -46,9 +37,9 @@ fn action( match keysym.modified_sym().raw() { modified @ KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12 => { let vt = (modified - KEY_XF86Switch_VT_1 + 1) as i32; - return Action::ChangeVt(vt); + return Some(Action::ChangeVt(vt)); } - KEY_XF86PowerOff => return Action::Suspend, + KEY_XF86PowerOff => return Some(Action::Suspend), _ => (), } @@ -78,7 +69,7 @@ fn action( } let Some(&raw) = keysym.raw_syms().first() else { - return Action::None; + return None; }; for bind in &config.binds.0 { if bind.key.keysym != raw { @@ -86,11 +77,11 @@ fn action( } if bind.key.modifiers | comp_mod == modifiers { - return bind.actions.first().cloned().unwrap_or(Action::None); + return bind.actions.first().cloned(); } } - Action::None + None } fn should_activate_monitors(event: &InputEvent) -> bool { @@ -136,232 +127,229 @@ impl State { let serial = SERIAL_COUNTER.next_serial(); let time = Event::time_msec(&event); - let mut action = self.niri.seat.get_keyboard().unwrap().input( + let action = self.niri.seat.get_keyboard().unwrap().input( self, event.key_code(), event.state(), serial, time, |self_, mods, keysym| { - if event.state() == KeyState::Pressed { - let config = self_.niri.config.borrow(); - action(&config, comp_mod, keysym, *mods).into() - } else { - FilterResult::Forward + let config = self_.niri.config.borrow(); + match action(&config, comp_mod, keysym, *mods) { + Some(action) => FilterResult::Intercept(action), + None => FilterResult::Forward, } }, ); - // Filter actions when the session is locked. - if self.niri.is_locked() { - match action { - Some( - Action::Quit - | Action::ChangeVt(_) - | Action::Suspend - | Action::PowerOffMonitors, - ) => (), - _ => action = None, - } - } + // Filter actions when the session is locked or we released the previous + // action hotkey. + let action = match action { + _ if event.state() == KeyState::Released => return, + Some( + Action::Quit + | Action::ChangeVt(_) + | Action::Suspend + | Action::PowerOffMonitors, + ) if self.niri.is_locked() => return, + Some(action) => action, + _ => return, + }; - if let Some(action) = action { - match action { - Action::None => unreachable!(), - Action::Quit => { - info!("quitting because quit bind was pressed"); - self.niri.stop_signal.stop() - } - Action::ChangeVt(vt) => { - self.backend.change_vt(vt); - } - Action::Suspend => { - self.backend.suspend(); - } - Action::PowerOffMonitors => { - self.niri.deactivate_monitors(&self.backend); - } - Action::ToggleDebugTint => { - self.backend.toggle_debug_tint(); - } - Action::Spawn(command) => { - if let Some((command, args)) = command.split_first() { - spawn(command, args); - } + match action { + Action::Quit => { + info!("quitting because quit bind was pressed"); + self.niri.stop_signal.stop() + } + Action::ChangeVt(vt) => { + self.backend.change_vt(vt); + } + Action::Suspend => { + self.backend.suspend(); + } + Action::PowerOffMonitors => { + self.niri.deactivate_monitors(&self.backend); + } + Action::ToggleDebugTint => { + self.backend.toggle_debug_tint(); + } + Action::Spawn(command) => { + if let Some((command, args)) = command.split_first() { + spawn(command, args); } - Action::Screenshot => { - let active = self.niri.layout.active_output().cloned(); - if let Some(active) = active { - if let Some(renderer) = self.backend.renderer() { - if let Err(err) = self.niri.screenshot(renderer, &active) { - warn!("error taking screenshot: {err:?}"); - } + } + Action::Screenshot => { + let active = self.niri.layout.active_output().cloned(); + if let Some(active) = active { + if let Some(renderer) = self.backend.renderer() { + if let Err(err) = self.niri.screenshot(renderer, &active) { + warn!("error taking screenshot: {err:?}"); } } } - Action::ScreenshotWindow => { - let active = self.niri.layout.active_window(); - if let Some((window, output)) = active { - if let Some(renderer) = self.backend.renderer() { - if let Err(err) = - self.niri.screenshot_window(renderer, &output, &window) - { - warn!("error taking screenshot: {err:?}"); - } + } + Action::ScreenshotWindow => { + let active = self.niri.layout.active_window(); + if let Some((window, output)) = active { + if let Some(renderer) = self.backend.renderer() { + if let Err(err) = + self.niri.screenshot_window(renderer, &output, &window) + { + warn!("error taking screenshot: {err:?}"); } } } - Action::CloseWindow => { - if let Some(window) = self.niri.layout.focus() { - window.toplevel().send_close(); - } - } - Action::FullscreenWindow => { - let focus = self.niri.layout.focus().cloned(); - if let Some(window) = focus { - self.niri.layout.toggle_fullscreen(&window); - } - } - Action::MoveColumnLeft => { - self.niri.layout.move_left(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveColumnRight => { - self.niri.layout.move_right(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWindowDown => { - self.niri.layout.move_down(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWindowUp => { - self.niri.layout.move_up(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::FocusColumnLeft => { - self.niri.layout.focus_left(); - } - Action::FocusColumnRight => { - self.niri.layout.focus_right(); - } - Action::FocusWindowDown => { - self.niri.layout.focus_down(); - } - Action::FocusWindowUp => { - self.niri.layout.focus_up(); - } - Action::MoveWindowToWorkspaceDown => { - self.niri.layout.move_to_workspace_down(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWindowToWorkspaceUp => { - self.niri.layout.move_to_workspace_up(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWindowToWorkspace(idx) => { - self.niri.layout.move_to_workspace(idx); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::FocusWorkspaceDown => { - self.niri.layout.switch_workspace_down(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::FocusWorkspaceUp => { - self.niri.layout.switch_workspace_up(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::FocusWorkspace(idx) => { - self.niri.layout.switch_workspace(idx); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWorkspaceDown => { - self.niri.layout.move_workspace_down(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::MoveWorkspaceUp => { - self.niri.layout.move_workspace_up(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::ConsumeWindowIntoColumn => { - self.niri.layout.consume_into_column(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::ExpelWindowFromColumn => { - self.niri.layout.expel_from_column(); - // FIXME: granular - self.niri.queue_redraw_all(); - } - Action::SwitchPresetColumnWidth => { - self.niri.layout.toggle_width(); - } - Action::MaximizeColumn => { - self.niri.layout.toggle_full_width(); + } + Action::CloseWindow => { + if let Some(window) = self.niri.layout.focus() { + window.toplevel().send_close(); } - Action::FocusMonitorLeft => { - if let Some(output) = self.niri.output_left() { - self.niri.layout.focus_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::FullscreenWindow => { + let focus = self.niri.layout.focus().cloned(); + if let Some(window) = focus { + self.niri.layout.toggle_fullscreen(&window); } - Action::FocusMonitorRight => { - if let Some(output) = self.niri.output_right() { - self.niri.layout.focus_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::MoveColumnLeft => { + self.niri.layout.move_left(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveColumnRight => { + self.niri.layout.move_right(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWindowDown => { + self.niri.layout.move_down(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWindowUp => { + self.niri.layout.move_up(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::FocusColumnLeft => { + self.niri.layout.focus_left(); + } + Action::FocusColumnRight => { + self.niri.layout.focus_right(); + } + Action::FocusWindowDown => { + self.niri.layout.focus_down(); + } + Action::FocusWindowUp => { + self.niri.layout.focus_up(); + } + Action::MoveWindowToWorkspaceDown => { + self.niri.layout.move_to_workspace_down(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWindowToWorkspaceUp => { + self.niri.layout.move_to_workspace_up(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWindowToWorkspace(idx) => { + self.niri.layout.move_to_workspace(idx); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::FocusWorkspaceDown => { + self.niri.layout.switch_workspace_down(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::FocusWorkspaceUp => { + self.niri.layout.switch_workspace_up(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::FocusWorkspace(idx) => { + self.niri.layout.switch_workspace(idx); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWorkspaceDown => { + self.niri.layout.move_workspace_down(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::MoveWorkspaceUp => { + self.niri.layout.move_workspace_up(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::ConsumeWindowIntoColumn => { + self.niri.layout.consume_into_column(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::ExpelWindowFromColumn => { + self.niri.layout.expel_from_column(); + // FIXME: granular + self.niri.queue_redraw_all(); + } + Action::SwitchPresetColumnWidth => { + self.niri.layout.toggle_width(); + } + Action::MaximizeColumn => { + self.niri.layout.toggle_full_width(); + } + Action::FocusMonitorLeft => { + if let Some(output) = self.niri.output_left() { + self.niri.layout.focus_output(&output); + self.move_cursor_to_output(&output); } - Action::FocusMonitorDown => { - if let Some(output) = self.niri.output_down() { - self.niri.layout.focus_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::FocusMonitorRight => { + if let Some(output) = self.niri.output_right() { + self.niri.layout.focus_output(&output); + self.move_cursor_to_output(&output); } - Action::FocusMonitorUp => { - if let Some(output) = self.niri.output_up() { - self.niri.layout.focus_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::FocusMonitorDown => { + if let Some(output) = self.niri.output_down() { + self.niri.layout.focus_output(&output); + self.move_cursor_to_output(&output); } - Action::MoveWindowToMonitorLeft => { - if let Some(output) = self.niri.output_left() { - self.niri.layout.move_to_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::FocusMonitorUp => { + if let Some(output) = self.niri.output_up() { + self.niri.layout.focus_output(&output); + self.move_cursor_to_output(&output); } - Action::MoveWindowToMonitorRight => { - if let Some(output) = self.niri.output_right() { - self.niri.layout.move_to_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::MoveWindowToMonitorLeft => { + if let Some(output) = self.niri.output_left() { + self.niri.layout.move_to_output(&output); + self.move_cursor_to_output(&output); } - Action::MoveWindowToMonitorDown => { - if let Some(output) = self.niri.output_down() { - self.niri.layout.move_to_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::MoveWindowToMonitorRight => { + if let Some(output) = self.niri.output_right() { + self.niri.layout.move_to_output(&output); + self.move_cursor_to_output(&output); } - Action::MoveWindowToMonitorUp => { - if let Some(output) = self.niri.output_up() { - self.niri.layout.move_to_output(&output); - self.move_cursor_to_output(&output); - } + } + Action::MoveWindowToMonitorDown => { + if let Some(output) = self.niri.output_down() { + self.niri.layout.move_to_output(&output); + self.move_cursor_to_output(&output); } - Action::SetColumnWidth(change) => { - self.niri.layout.set_column_width(change); + } + Action::MoveWindowToMonitorUp => { + if let Some(output) = self.niri.output_up() { + self.niri.layout.move_to_output(&output); + self.move_cursor_to_output(&output); } } + Action::SetColumnWidth(change) => { + self.niri.layout.set_column_width(change); + } } } InputEvent::PointerMotion { event, .. } => {