use smithay::backend::input::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, }; use smithay::input::keyboard::{keysyms, FilterResult}; use smithay::input::pointer::{AxisFrame, ButtonEvent, MotionEvent}; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::utils::SERIAL_COUNTER; use crate::niri::Niri; enum InputAction { Quit, ChangeVt(i32), } impl Niri { pub fn process_input_event(&mut self, event: InputEvent) { trace!("process_input_event"); match event { InputEvent::Keyboard { event, .. } => { let serial = SERIAL_COUNTER.next_serial(); let time = Event::time_msec(&event); let action = self.seat.get_keyboard().unwrap().input( self, event.key_code(), event.state(), serial, time, |_, _, keysym| match keysym.modified_sym() { keysyms::KEY_Escape => FilterResult::Intercept(InputAction::Quit), keysym @ keysyms::KEY_XF86Switch_VT_1..=keysyms::KEY_XF86Switch_VT_12 => { let vt = (keysym - keysyms::KEY_XF86Switch_VT_1 + 1) as i32; FilterResult::Intercept(InputAction::ChangeVt(vt)) } _ => FilterResult::Forward, }, ); if let Some(action) = action { match action { InputAction::Quit => { info!("quitting because Esc was pressed"); self.stop_signal.stop() } InputAction::ChangeVt(vt) => todo!(), } } } InputEvent::PointerMotion { .. } => {} InputEvent::PointerMotionAbsolute { event, .. } => { let output = self.space.outputs().next().unwrap(); let output_geo = self.space.output_geometry(output).unwrap(); let pos = event.position_transformed(output_geo.size) + output_geo.loc.to_f64(); let serial = SERIAL_COUNTER.next_serial(); let pointer = self.seat.get_pointer().unwrap(); let under = self.surface_under_pointer(&pointer); pointer.motion( self, under, &MotionEvent { location: pos, serial, time: event.time_msec(), }, ); } InputEvent::PointerButton { event, .. } => { let pointer = self.seat.get_pointer().unwrap(); let keyboard = self.seat.get_keyboard().unwrap(); let serial = SERIAL_COUNTER.next_serial(); let button = event.button_code(); let button_state = event.state(); if ButtonState::Pressed == button_state && !pointer.is_grabbed() { if let Some((window, _loc)) = self .space .element_under(pointer.current_location()) .map(|(w, l)| (w.clone(), l)) { self.space.raise_element(&window, true); keyboard.set_focus( self, Some(window.toplevel().wl_surface().clone()), serial, ); self.space.elements().for_each(|window| { window.toplevel().send_pending_configure(); }); } else { self.space.elements().for_each(|window| { window.set_activated(false); window.toplevel().send_pending_configure(); }); keyboard.set_focus(self, Option::::None, serial); } }; pointer.button( self, &ButtonEvent { button, state: button_state, serial, time: event.time_msec(), }, ); } InputEvent::PointerAxis { event, .. } => { let source = event.source(); // FIXME: this crashes on keyboard scroll. let horizontal_amount = event .amount(Axis::Horizontal) .unwrap_or_else(|| event.amount_discrete(Axis::Horizontal).unwrap() * 3.0); let vertical_amount = event .amount(Axis::Vertical) .unwrap_or_else(|| event.amount_discrete(Axis::Vertical).unwrap() * 3.0); let horizontal_amount_discrete = event.amount_discrete(Axis::Horizontal); let vertical_amount_discrete = event.amount_discrete(Axis::Vertical); let mut frame = AxisFrame::new(event.time_msec()).source(source); if horizontal_amount != 0.0 { frame = frame.value(Axis::Horizontal, horizontal_amount); if let Some(discrete) = horizontal_amount_discrete { frame = frame.discrete(Axis::Horizontal, discrete as i32); } } else if source == AxisSource::Finger { frame = frame.stop(Axis::Horizontal); } if vertical_amount != 0.0 { frame = frame.value(Axis::Vertical, vertical_amount); if let Some(discrete) = vertical_amount_discrete { frame = frame.discrete(Axis::Vertical, discrete as i32); } } else if source == AxisSource::Finger { frame = frame.stop(Axis::Vertical); } self.seat.get_pointer().unwrap().axis(self, frame); } _ => {} } } }