From 7896d88c8c86ba0fec0053ce848e50584947609e Mon Sep 17 00:00:00 2001 From: Ottatop Date: Mon, 24 Jun 2024 09:56:00 -0500 Subject: [PATCH] Support pointer gestures --- src/handlers.rs | 6 +- src/input.rs | 198 +++++++++++++++++++++++++++++++++++++++--------- src/state.rs | 3 + 3 files changed, 170 insertions(+), 37 deletions(-) diff --git a/src/handlers.rs b/src/handlers.rs index 76083ea..1a3d398 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -17,8 +17,8 @@ use smithay::{ }, delegate_compositor, delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_fractional_scale, delegate_keyboard_shortcuts_inhibit, delegate_layer_shell, - delegate_output, delegate_pointer_constraints, delegate_presentation, - delegate_primary_selection, delegate_relative_pointer, delegate_seat, + delegate_output, delegate_pointer_constraints, delegate_pointer_gestures, + delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_viewporter, delegate_xdg_activation, delegate_xwayland_keyboard_grab, delegate_xwayland_shell, desktop::{ @@ -1036,6 +1036,8 @@ impl XdgActivationHandler for State { } delegate_xdg_activation!(State); +delegate_pointer_gestures!(State); + impl Pinnacle { fn position_popup(&self, popup: &PopupSurface) { trace!("State::position_popup"); diff --git a/src/input.rs b/src/input.rs index 83d323c..000db39 100644 --- a/src/input.rs +++ b/src/input.rs @@ -21,15 +21,21 @@ use pinnacle_api_defs::pinnacle::input::v0alpha1::{ use smithay::{ backend::{ input::{ - AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, - KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent, + AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, GestureBeginEvent, + GestureEndEvent, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, + PointerAxisEvent, PointerButtonEvent, PointerMotionEvent, }, renderer::utils::with_renderer_surface_state, }, desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType}, input::{ keyboard::{keysyms, FilterResult, ModifiersState}, - pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent}, + pointer::{ + AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, + GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, + GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent, + RelativeMotionEvent, + }, }, reexports::input::{self, Led}, utils::{Logical, Point, Rectangle, SERIAL_COUNTER}, @@ -295,17 +301,32 @@ impl Pinnacle { impl State { pub fn process_input_event(&mut self, event: InputEvent) { - match event { - // TODO: rest of input events + self.pinnacle + .idle_notifier_state + .notify_activity(&self.pinnacle.seat); + match event { // InputEvent::DeviceAdded { device } => todo!(), // InputEvent::DeviceRemoved { device } => todo!(), - InputEvent::Keyboard { event } => self.keyboard::(event), - InputEvent::PointerMotion { event } => self.pointer_motion::(event), - InputEvent::PointerMotionAbsolute { event } => self.pointer_motion_absolute::(event), - InputEvent::PointerButton { event } => self.pointer_button::(event), - InputEvent::PointerAxis { event } => self.pointer_axis::(event), + InputEvent::Keyboard { event } => self.on_keyboard::(event), + InputEvent::PointerMotion { event } => self.on_pointer_motion::(event), + InputEvent::PointerMotionAbsolute { event } => { + self.on_pointer_motion_absolute::(event) + } + InputEvent::PointerButton { event } => self.on_pointer_button::(event), + InputEvent::PointerAxis { event } => self.on_pointer_axis::(event), + + InputEvent::GestureSwipeBegin { event } => self.on_gesture_swipe_begin::(event), + InputEvent::GestureSwipeUpdate { event } => self.on_gesture_swipe_update::(event), + InputEvent::GestureSwipeEnd { event } => self.on_gesture_swipe_end::(event), + InputEvent::GesturePinchBegin { event } => self.on_gesture_pinch_begin::(event), + InputEvent::GesturePinchUpdate { event } => self.on_gesture_pinch_update::(event), + InputEvent::GesturePinchEnd { event } => self.on_gesture_pinch_end::(event), + InputEvent::GestureHoldBegin { event } => self.on_gesture_hold_begin::(event), + InputEvent::GestureHoldEnd { event } => self.on_gesture_hold_end::(event), + + // TODO: rest of input events _ => (), } } @@ -404,11 +425,7 @@ impl State { } } - fn keyboard(&mut self, event: I::KeyboardKeyEvent) { - self.pinnacle - .idle_notifier_state - .notify_activity(&self.pinnacle.seat); - + fn on_keyboard(&mut self, event: I::KeyboardKeyEvent) { let serial = SERIAL_COUNTER.next_serial(); let time = event.time_msec(); let press_state = event.state(); @@ -602,11 +619,7 @@ impl State { } } - fn pointer_button(&mut self, event: I::PointerButtonEvent) { - self.pinnacle - .idle_notifier_state - .notify_activity(&self.pinnacle.seat); - + fn on_pointer_button(&mut self, event: I::PointerButtonEvent) { let Some(pointer) = self.pinnacle.seat.get_pointer() else { return; }; @@ -680,11 +693,7 @@ impl State { pointer.frame(self); } - fn pointer_axis(&mut self, event: I::PointerAxisEvent) { - self.pinnacle - .idle_notifier_state - .notify_activity(&self.pinnacle.seat); - + fn on_pointer_axis(&mut self, event: I::PointerAxisEvent) { let source = event.source(); let horizontal_amount = event @@ -732,11 +741,10 @@ impl State { /// /// This *should* only be generated on the winit backend. /// Unless there's a case where it's generated on udev that I'm unaware of. - fn pointer_motion_absolute(&mut self, event: I::PointerMotionAbsoluteEvent) { - self.pinnacle - .idle_notifier_state - .notify_activity(&self.pinnacle.seat); - + fn on_pointer_motion_absolute( + &mut self, + event: I::PointerMotionAbsoluteEvent, + ) { let Some(pointer) = self.pinnacle.seat.get_pointer() else { error!("Pointer motion absolute received with no pointer on seat"); return; @@ -784,11 +792,7 @@ impl State { } } - fn pointer_motion(&mut self, event: I::PointerMotionEvent) { - self.pinnacle - .idle_notifier_state - .notify_activity(&self.pinnacle.seat); - + fn on_pointer_motion(&mut self, event: I::PointerMotionEvent) { let Some(pointer) = self.pinnacle.seat.get_pointer() else { error!("Pointer motion received with no pointer on seat"); return; @@ -971,6 +975,130 @@ impl State { self.schedule_render(&output); } } + + fn on_gesture_swipe_begin(&mut self, event: I::GestureSwipeBeginEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_swipe_begin( + self, + &GestureSwipeBeginEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + fingers: event.fingers(), + }, + ); + } + + fn on_gesture_swipe_update(&mut self, event: I::GestureSwipeUpdateEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + use smithay::backend::input::GestureSwipeUpdateEvent as _; + + pointer.gesture_swipe_update( + self, + &GestureSwipeUpdateEvent { + time: event.time_msec(), + delta: event.delta(), + }, + ); + } + + fn on_gesture_swipe_end(&mut self, event: I::GestureSwipeEndEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_swipe_end( + self, + &GestureSwipeEndEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + cancelled: event.cancelled(), + }, + ); + } + + fn on_gesture_pinch_begin(&mut self, event: I::GesturePinchBeginEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_pinch_begin( + self, + &GesturePinchBeginEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + fingers: event.fingers(), + }, + ); + } + + fn on_gesture_pinch_update(&mut self, event: I::GesturePinchUpdateEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + use smithay::backend::input::GesturePinchUpdateEvent as _; + + pointer.gesture_pinch_update( + self, + &GesturePinchUpdateEvent { + time: event.time_msec(), + delta: event.delta(), + scale: event.scale(), + rotation: event.rotation(), + }, + ); + } + + fn on_gesture_pinch_end(&mut self, event: I::GesturePinchEndEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_pinch_end( + self, + &GesturePinchEndEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + cancelled: event.cancelled(), + }, + ); + } + + fn on_gesture_hold_begin(&mut self, event: I::GestureHoldBeginEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_hold_begin( + self, + &GestureHoldBeginEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + fingers: event.fingers(), + }, + ); + } + + fn on_gesture_hold_end(&mut self, event: I::GestureHoldEndEvent) { + let Some(pointer) = self.pinnacle.seat.get_pointer() else { + return; + }; + + pointer.gesture_hold_end( + self, + &GestureHoldEndEvent { + serial: SERIAL_COUNTER.next_serial(), + time: event.time_msec(), + cancelled: event.cancelled(), + }, + ); + } } /// Clamp the given point within the given rects. diff --git a/src/state.rs b/src/state.rs index 994e168..20d83d3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -45,6 +45,7 @@ use smithay::{ keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState, output::OutputManagerState, pointer_constraints::PointerConstraintsState, + pointer_gestures::PointerGesturesState, relative_pointer::RelativePointerManagerState, security_context::SecurityContextState, selection::{ @@ -129,6 +130,7 @@ pub struct Pinnacle { pub xdg_activation_state: XdgActivationState, pub xdg_decoration_state: XdgDecorationState, pub kde_decoration_state: KdeDecorationState, + pub pointer_gestures_state: PointerGesturesState, pub lock_state: LockState, @@ -362,6 +364,7 @@ impl Pinnacle { &display_handle, org_kde_kwin_server_decoration_manager::Mode::Client, ), + pointer_gestures_state: PointerGesturesState::new::(&display_handle), lock_state: LockState::default(),