From b6cab38528fe9baf8ecad27ca60605ff9c933623 Mon Sep 17 00:00:00 2001 From: Skygrango Date: Sun, 24 May 2026 01:47:57 +0800 Subject: [PATCH] wayland: implement pointer_warp_v1 --- src/state.rs | 2 ++ src/wayland/handlers/mod.rs | 1 + src/wayland/handlers/pointer_warp.rs | 44 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 src/wayland/handlers/pointer_warp.rs diff --git a/src/state.rs b/src/state.rs index 5b84492f..18de36ba 100644 --- a/src/state.rs +++ b/src/state.rs @@ -86,6 +86,7 @@ use smithay::{ output::OutputManagerState, pointer_constraints::PointerConstraintsState, pointer_gestures::PointerGesturesState, + pointer_warp::PointerWarpManager, presentation::PresentationState, seat::WaylandFocus, security_context::{SecurityContext, SecurityContextState}, @@ -671,6 +672,7 @@ impl State { XWaylandKeyboardGrabState::new::(dh); let xwayland_shell_state = XWaylandShellState::new::(dh); PointerConstraintsState::new::(dh); + PointerWarpManager::new::(dh); PointerGesturesState::new::(dh); TabletManagerState::new::(dh); SecurityContextState::new::(dh, client_has_no_security_context); diff --git a/src/wayland/handlers/mod.rs b/src/wayland/handlers/mod.rs index 8f6547cf..34d063d0 100644 --- a/src/wayland/handlers/mod.rs +++ b/src/wayland/handlers/mod.rs @@ -25,6 +25,7 @@ pub mod output_configuration; pub mod output_power; pub mod overlap_notify; pub mod pointer_constraints; +pub mod pointer_warp; pub mod primary_selection; pub mod seat; pub mod security_context; diff --git a/src/wayland/handlers/pointer_warp.rs b/src/wayland/handlers/pointer_warp.rs new file mode 100644 index 00000000..971ab583 --- /dev/null +++ b/src/wayland/handlers/pointer_warp.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::State; +use smithay::{ + input::pointer::PointerHandle, + reexports::wayland_server::protocol::{wl_pointer::WlPointer, wl_surface::WlSurface}, + utils::{Logical, Point, Serial}, + wayland::pointer_warp::PointerWarpHandler, +}; + +impl PointerWarpHandler for State { + fn warp_pointer( + &mut self, + surface: WlSurface, + pointer: WlPointer, + pos: Point, + serial: Serial, + ) { + let Some(resource_handle) = PointerHandle::::from_resource(&pointer) else { + return; + }; + + let shell = self.common.shell.read(); + + let pointer_handle = shell.seats.iter().find_map(|seat| { + if let Some(pointer_handle) = seat.get_pointer() + && resource_handle == pointer_handle + && pointer_handle.last_enter() == Some(serial) + && let Some(keyboard) = seat.get_keyboard() + && let Some(keyboard_focus) = keyboard.current_focus() + && keyboard_focus.has_surface(&shell, &surface) + { + return Some(pointer_handle); + } + None + }); + + drop(shell); + + if let Some(pointer_handle) = pointer_handle { + self.apply_cursor_hint(&surface, &pointer_handle, pos); + } + } +}