Skip to content

Commit

Permalink
v2
Browse files Browse the repository at this point in the history
  • Loading branch information
kchibisov committed Oct 27, 2023
1 parent a36a8ac commit 5c0cdae
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
69 changes: 49 additions & 20 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::hash_map::Entry;

use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
Expand Down Expand Up @@ -126,36 +128,63 @@ impl State {
InputEvent::Keyboard { event, .. } => {
let serial = SERIAL_COUNTER.next_serial();
let time = Event::time_msec(&event);
let pressed = event.state() == KeyState::Pressed;

let action = self.niri.seat.get_keyboard().unwrap().input(
let Some(Some(action)) = self.niri.seat.get_keyboard().unwrap().input(
self,
event.key_code(),
event.state(),
serial,
time,
|self_, mods, keysym| {
let config = self_.niri.config.borrow();
match action(&config, comp_mod, keysym, *mods) {
Some(action) => FilterResult::Intercept(action),
None => FilterResult::Forward,
|this, mods, keysym| {
let config = this.niri.config.borrow();
let key_code = event.key_code();
match (
action(&config, comp_mod, keysym, *mods),
this.niri.suppress_keys.entry(key_code),
) {
(action, Entry::Occupied(mut entry)) => {
let key = entry.get_mut();
if pressed {
*key += 1;
} else {
*key -= 1;
}

if *key == 0 {
entry.remove_entry();
}

FilterResult::Intercept(action)
}
// Only register suppresses on presses, since user can trigger release
// due to matching action from non-action hotkey by releasing some
// of the modifiers.
(Some(action), Entry::Vacant(entry)) if pressed => {
entry.insert(1);
FilterResult::Intercept(Some(action))
}
(_, Entry::Vacant(_)) => FilterResult::Forward,
}
},
);

// 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,
) else {
return;
};

// Filter actions when the key is released or the session is locked.
if !pressed
|| self.niri.is_locked()
&& !matches!(
action,
Action::Quit
| Action::ChangeVt(_)
| Action::Suspend
| Action::PowerOffMonitors
)
{
return;
}

match action {
Action::Quit => {
info!("quitting because quit bind was pressed");
Expand Down
4 changes: 4 additions & 0 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ pub struct Niri {
pub presentation_state: PresentationState,

pub seat: Seat<State>,
/// Suppress keys based on the `scancode -> num_pressed` mapping. When the value amount
/// of time to suppress gets to `0` the key is removed.
pub suppress_keys: HashMap<u32, u32>,

pub default_cursor: Cursor,
pub cursor_image: CursorImageStatus,
Expand Down Expand Up @@ -629,6 +632,7 @@ impl Niri {
primary_selection_state,
data_control_state,
popups: PopupManager::default(),
suppress_keys: HashMap::new(),
presentation_state,

seat,
Expand Down

0 comments on commit 5c0cdae

Please sign in to comment.