diff --git a/src/wayland/handlers/image_copy_capture/mod.rs b/src/wayland/handlers/image_copy_capture/mod.rs index 733e05ef..3f08b2dd 100644 --- a/src/wayland/handlers/image_copy_capture/mod.rs +++ b/src/wayland/handlers/image_copy_capture/mod.rs @@ -14,6 +14,7 @@ use smithay::{ }, }, desktop::space::SpaceElement, + input::{Seat, pointer::PointerHandle}, output::Output, reexports::wayland_server::protocol::{wl_pointer::WlPointer, wl_shm::Format as ShmFormat}, utils::{Buffer as BufferCoords, Point, Size, Transform}, @@ -30,7 +31,7 @@ use smithay::{ }; use crate::{ - shell::CosmicSurface, + shell::{CosmicSurface, Shell}, state::{BackendData, State}, utils::prelude::{ OutputExt, PointExt, PointGlobalExt, PointLocalExt, RectExt, RectLocalExt, SeatExt, @@ -44,6 +45,14 @@ pub use self::render::*; use self::user_data::*; pub use self::user_data::{FrameHolder, ImageCopySessions, SessionData, SessionHolder}; +fn seat_for_wl_pointer<'a>(shell: &'a Shell, pointer: &WlPointer) -> Option<&'a Seat> { + let pointer_handle = PointerHandle::::from_resource(pointer)?; + shell + .seats + .iter() + .find(|seat| seat.get_pointer().is_some_and(|p| p == pointer_handle)) +} + impl ImageCopyCaptureHandler for State { fn image_copy_capture_state(&mut self) -> &mut ImageCopyCaptureState { &mut self.common.image_copy_capture_state @@ -73,15 +82,12 @@ impl ImageCopyCaptureHandler for State { fn cursor_capture_constraints( &mut self, _source: &ImageCaptureSource, - _pointer: &WlPointer, + pointer: &WlPointer, ) -> Option { - let size = if let Some((geometry, _)) = self - .common - .shell - .read() - .seats - .last_active() - .cursor_geometry((0.0, 0.0), self.common.clock.now()) + let shell = self.common.shell.read(); + let seat = seat_for_wl_pointer(&shell, pointer)?; + let size = if let Some((geometry, _)) = + seat.cursor_geometry((0.0, 0.0), self.common.clock.now()) { geometry.size } else { @@ -149,20 +155,23 @@ impl ImageCopyCaptureHandler for State { fn new_cursor_session(&mut self, session: CursorSession) { let (pointer_loc, pointer_size, hotspot) = { - let seat = self.common.shell.read().seats.last_active().clone(); + let shell = self.common.shell.read(); + if let Some(seat) = seat_for_wl_pointer(&shell, &session.pointer()) { + let pointer = seat.get_pointer().unwrap(); + let pointer_loc = pointer.current_location().to_i32_round().as_global(); - let pointer = seat.get_pointer().unwrap(); - let pointer_loc = pointer.current_location().to_i32_round().as_global(); + let (pointer_size, hotspot) = if let Some((geometry, hotspot)) = + seat.cursor_geometry((0.0, 0.0), self.common.clock.now()) + { + (geometry.size, hotspot) + } else { + (Size::from((64, 64)), Point::from((0, 0))) + }; - let (pointer_size, hotspot) = if let Some((geometry, hotspot)) = - seat.cursor_geometry((0.0, 0.0), self.common.clock.now()) - { - (geometry.size, hotspot) + (pointer_loc, pointer_size, hotspot) } else { - (Size::from((64, 64)), Point::from((0, 0))) - }; - - (pointer_loc, pointer_size, hotspot) + (Point::new(0, 0), Size::from((64, 64)), Point::from((0, 0))) + } }; session.user_data().insert_if_missing_threadsafe(|| { @@ -299,8 +308,11 @@ impl ImageCopyCaptureHandler for State { return; } - let seat = self.common.shell.read().seats.last_active().clone(); - render_cursor_to_buffer(self, session, frame, &seat); + let shell = self.common.shell.read(); + if let Some(seat) = seat_for_wl_pointer(&shell, &session.pointer()).cloned() { + drop(shell); + render_cursor_to_buffer(self, session, frame, &seat); + } } fn frame_aborted(&mut self, frame: FrameRef) {