use std::collections::HashSet;
use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState,
};
use smithay::backend::libinput::LibinputInputBackend;
use smithay::input::keyboard::{keysyms, FilterResult, Keysym, ModifiersState};
use smithay::input::pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent,
GestureSwipeUpdateEvent, MotionEvent, RelativeMotionEvent,
};
use smithay::utils::SERIAL_COUNTER;
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
use crate::config::{Action, Binds, Modifiers};
use crate::niri::State;
use crate::screenshot_ui::ScreenshotUi;
use crate::utils::{center, get_monotonic_time, spawn};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompositorMod {
Super,
Alt,
}
impl State {
pub fn process_input_event<I: InputBackend>(&mut self, event: InputEvent<I>) {
let _span = tracy_client::span!("process_input_event");
// A bit of a hack, but animation end runs some logic (i.e. workspace clean-up) and it
// doesn't always trigger due to damage, etc. So run it here right before it might prove
// important. Besides, animations affect the input, so it's best to have up-to-date values
// here.
self.niri.layout.advance_animations(get_monotonic_time());
// Power on monitors if they were off.
if should_activate_monitors(&event) {
self.niri.activate_monitors(&self.backend);
}
let comp_mod = self.backend.mod_key();
match event {
InputEvent::Keyboard { event, .. } => {
let serial = SERIAL_COUNTER.next_serial();
let time = Event::time_msec(&event);
let pressed = event.state() == KeyState::Pressed;
let Some(Some(action)) = self.niri.seat.get_keyboard().unwrap().input(
self,
event.key_code(),
event.state(),
serial,
time,
|this, mods, keysym| {
let bindings = &this.niri.config.borrow().binds;
let key_code = event.key_code();
let modified = keysym.modified_sym();
let raw = keysym.raw_syms().first().cloned();
should_intercept_key(
&mut this.niri.suppressed_keys,
bindings,
comp_mod,
key_code,
modified,
raw,
pressed,
*mods,
&this.niri.screenshot_ui,
)
},
) else {
return;
};
// Filter actions when the key is released or the session is locked.