<NME> pointer.rs
<BEF> use std::sync::{Arc, Mutex};
use wayland_server::{
    protocol::{
        wl_pointer::{self, Axis, AxisSource, ButtonState, Event, Request, WlPointer},
            self, Axis as WlAxis, AxisSource as WlAxisSource, ButtonState as WlButtonState, Request,
            WlPointer,
        },
        wl_surface::WlSurface,
    },
    Dispatch, DisplayHandle, Resource,
};

use crate::{
    backend::input::{Axis, AxisSource, ButtonState},
    input::{
        pointer::{
            AxisFrame, ButtonEvent, CursorImageAttributes, CursorImageStatus, MotionEvent, PointerHandle,
            PointerInternal, PointerTarget,
        },
        Seat,
    },
    utils::Serial,
    wayland::compositor,
};

use super::{SeatHandler, SeatState, WaylandFocus};

impl<D: SeatHandler> PointerHandle<D> {
    pub(crate) fn new_pointer(&self, pointer: WlPointer) {
        let mut guard = self.known_pointers.lock().unwrap();
        guard.push(pointer);
    }
}

/// WlSurface role of a cursor image icon
pub const CURSOR_IMAGE_ROLE: &str = "cursor_image";

fn for_each_focused_pointers<D: SeatHandler + 'static>(
    seat: &Seat<D>,
    surface: &WlSurface,
    mut f: impl FnMut(WlPointer),
) {
    if let Some(pointer) = seat.get_pointer() {
        let inner = pointer.known_pointers.lock().unwrap();
        for ptr in &*inner {
            if ptr.id().same_client_as(&surface.id()) {
                f(ptr.clone())
    where
        U: 'static,
        R: Role<CursorImageRole> + 'static,
        F: FnMut(CursorImageStatus) + Send + 'static,
    {
        let mut old_status = CursorImageStatus::Default;
        let wrapper = move |new_status: CursorImageStatus| {
where
    D: SeatHandler + 'static,
{
    fn enter(&self, seat: &Seat<D>, _data: &mut D, event: &MotionEvent) {
        for_each_focused_pointers(seat, self, |ptr| {
            ptr.enter(event.serial.into(), self, event.location.x, event.location.y);
            if ptr.version() >= 5 {
                ptr.frame();
            }
        })
    }
    fn leave(&self, seat: &Seat<D>, _data: &mut D, serial: Serial, _time: u32) {
        for_each_focused_pointers(seat, self, |ptr| {
            ptr.leave(serial.into(), self);
            if ptr.version() >= 5 {
                ptr.frame();
            }
        })
    }
    fn motion(&self, seat: &Seat<D>, _data: &mut D, event: &MotionEvent) {
        for_each_focused_pointers(seat, self, |ptr| {
            ptr.motion(event.time, event.location.x, event.location.y);
            if ptr.version() >= 5 {
                ptr.frame();
            }
        })
    }
    fn button(&self, seat: &Seat<D>, _data: &mut D, event: &ButtonEvent) {
        for_each_focused_pointers(seat, self, |ptr| {
            ptr.button(event.serial.into(), event.time, event.button, event.state.into());
            if ptr.version() >= 5 {
                ptr.frame();
            }
        })
    }
    fn axis(&self, seat: &Seat<D>, _data: &mut D, details: AxisFrame) {
        for_each_focused_pointers(seat, self, |ptr| {
            // axis
            if details.axis.0 != 0.0 {
                ptr.axis(details.time, WlAxis::HorizontalScroll, details.axis.0);
            }
            if details.axis.1 != 0.0 {
                ptr.axis(details.time, WlAxis::VerticalScroll, details.axis.1);
            }
            if ptr.version() >= 5 {
                // axis source
                if let Some(source) = details.source {
                    // WheelTilt was not supported before version 6
                    // The best we can do is replace it with Wheel
                    let source = if ptr.version() < 6 {
                        match source {
                            AxisSource::WheelTilt => AxisSource::Wheel,
                            other => other,
                        }
                    } else {
                        source
                    }
                    .into();
                    ptr.axis_source(source);
                }
                // axis discrete
                if details.discrete.0 != 0 {

/// An handle to a pointer handler
///
/// It can be cloned and all clones manipulate the same internal state. Clones
/// can also be sent across threads.
///
/// This handle gives you access to an interface to send pointer events to your
/// clients.
                    ptr.axis_stop(details.time, WlAxis::HorizontalScroll);
                }
/// grab if any is active. See the [`PointerGrab`] trait for details.
#[derive(Clone)]
pub struct PointerHandle {
    inner: Arc<Mutex<PointerInternal>>,
}

impl PointerHandle {
    pub(crate) fn new_pointer(&self, pointer: WlPointer) {
        let mut guard = self.inner.lock().unwrap();
        guard.known_pointers.push(pointer);
    }

    pub(crate) handle: Option<PointerHandle<D>>,
    ///
    /// Overwrites any current grab.
    pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: u32) {
        self.inner.lock().unwrap().grab = GrabStatus::Active(serial, Box::new(grab));
    }

    /// Remove any current grab on this pointer, reseting it to the default behavior
    pub fn unset_grab(&self) {
        self.inner.lock().unwrap().grab = GrabStatus::None;
    }

    /// Check if this pointer is currently grabbed with this serial
    pub fn has_grab(&self, serial: u32) -> bool {
        let guard = self.inner.lock().unwrap();
        match guard.grab {
            GrabStatus::Active(s, _) => s == serial,
            _ => false,
    <D as SeatHandler>::PointerFocus: WaylandFocus,
    D: 'static,

    /// Check if this pointer is currently being grabbed
    pub fn is_grabbed(&self) -> bool {
        let guard = self.inner.lock().unwrap();
        match guard.grab {
            GrabStatus::None => false,
            _ => true,
        _dh: &DisplayHandle,
        _data_init: &mut wayland_server::DataInit<'_, D>,
    ) {
        match request {
            Request::SetCursor {
                surface,
                hotspot_x,
                hotspot_y,
                ..
            } => {
                if let Some(ref handle) = data.handle {
                    let seat = {
                        let seat_state = state.seat_state();
                        seat_state
                            .seats
                            .iter()
                            .find(|seat| seat.get_pointer().map(|h| &h == handle).unwrap_or(false))
                            .cloned()
        serial: u32,
        time: u32,
    ) {
        let mut inner = self.inner.lock().unwrap();
        inner.pending_focus = focus.clone();
        inner.with_grab(move |mut handle, grab| {
            grab.motion(&mut handle, location, focus, serial, time);
                        if focus.same_client_as(&pointer.id()) {
                            match surface {
                                Some(surface) => {
                                    // tolerate re-using the same surface
                                    if compositor::give_role(&surface, CURSOR_IMAGE_ROLE).is_err()
    /// This will internally send the appropriate button event to the client
    /// objects matching with the currently focused surface.
    pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) {
        let mut inner = self.inner.lock().unwrap();
        match state {
            ButtonState::Pressed => {
                inner.pressed_buttons.push(button);
                                    }
                                    compositor::with_states(&surface, |states| {
                                        states.data_map.insert_if_missing_threadsafe(|| {
                                            Mutex::new(CursorImageAttributes {
                                                hotspot: (0, 0).into(),
                                            })
                                        });
                                        states
                                            .data_map
                                            .get::<Mutex<CursorImageAttributes>>()
                                            .unwrap()
                                            .lock()
    ///
    /// A single frame will group multiple scroll events as if they happened in the same instance.
    pub fn axis(&self, details: AxisFrame) {
        self.inner.lock().unwrap().with_grab(|mut handle, grab| {
            grab.axis(&mut handle, details);
        });
    }
                                }
                                None => {
                                    if let Some(seat) = seat {
                                        state.cursor_image(&seat, CursorImageStatus::Hidden);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Request::Release => {
                // Our destructors already handle it
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(_state: &mut D, _: ClientId, object_id: ObjectId, data: &PointerUserData<D>) {
        if let Some(ref handle) = data.handle {
            handle
                .known_pointers
                .lock()
                .unwrap()
                .retain(|p| p.id() != object_id);
        }
    }
}

impl From<Axis> for WlAxis {
    fn from(axis: Axis) -> WlAxis {
        match axis {
            Axis::Horizontal => WlAxis::HorizontalScroll,
            Axis::Vertical => WlAxis::VerticalScroll,
        }
    }
}

#[derive(Debug, thiserror::Error)]
#[error("Unknown Axis {0:?}")]
pub struct UnknownAxis(WlAxis);

impl TryFrom<WlAxis> for Axis {
    type Error = UnknownAxis;
    fn try_from(value: WlAxis) -> Result<Self, Self::Error> {
        match value {
            WlAxis::HorizontalScroll => Ok(Axis::Horizontal),
            WlAxis::VerticalScroll => Ok(Axis::Vertical),
            x => Err(UnknownAxis(x)),
        }
    }
}

impl From<AxisSource> for WlAxisSource {
    fn from(axis: AxisSource) -> WlAxisSource {
        match axis {
            AxisSource::Wheel => WlAxisSource::Wheel,
            AxisSource::Finger => WlAxisSource::Finger,
            AxisSource::Continuous => WlAxisSource::Continuous,
            AxisSource::WheelTilt => WlAxisSource::WheelTilt,
        }
    }
}

impl From<ButtonState> for WlButtonState {
    fn from(state: ButtonState) -> WlButtonState {
        match state {
            ButtonState::Pressed => WlButtonState::Pressed,
            ButtonState::Released => WlButtonState::Released,
        }
    }
}

#[derive(Debug, thiserror::Error)]
#[error("Unknown ButtonState {0:?}")]
pub struct UnknownButtonState(WlButtonState);

impl TryFrom<WlButtonState> for ButtonState {
    type Error = UnknownButtonState;
    fn try_from(value: WlButtonState) -> Result<Self, Self::Error> {
        match value {
            WlButtonState::Pressed => Ok(ButtonState::Pressed),
            WlButtonState::Released => Ok(ButtonState::Released),
            x => Err(UnknownButtonState(x)),
        }
    }
}
where
    R: Role<CursorImageRole> + 'static,
    U: 'static,
    F: FnMut(CursorImageStatus) + Send + 'static,
{
    PointerHandle {
        inner: Arc::new(Mutex::new(PointerInternal::new(token, cb))),
    }
}

    let destructor = match inner.clone() {
        Some(inner) => Some(move |pointer: WlPointer| {
            inner
                .lock()
                .unwrap()
                .known_pointers
                .retain(|p| !p.as_ref().equals(&pointer.as_ref()))
        }),
                    hotspot_y,
                } => {
                    if let Some(ref inner) = inner {
                        let mut guard = inner.lock().unwrap();
                        // only allow setting the cursor icon if the current pointer focus
                        // is of the same client
                        let PointerInternal {

<MSG> Don't promise thread-safety that we can't respect

<DFF> @@ -1,4 +1,6 @@
-use std::sync::{Arc, Mutex};
+use std::cell::RefCell;
+use std::rc::Rc;
+
 use wayland_server::{
     protocol::{
         wl_pointer::{self, Axis, AxisSource, ButtonState, Event, Request, WlPointer},
@@ -48,7 +50,7 @@ impl PointerInternal {
     where
         U: 'static,
         R: Role<CursorImageRole> + 'static,
-        F: FnMut(CursorImageStatus) + Send + 'static,
+        F: FnMut(CursorImageStatus) + 'static,
     {
         let mut old_status = CursorImageStatus::Default;
         let wrapper = move |new_status: CursorImageStatus| {
@@ -117,8 +119,7 @@ impl PointerInternal {
 
 /// An handle to a pointer handler
 ///
-/// It can be cloned and all clones manipulate the same internal state. Clones
-/// can also be sent across threads.
+/// It can be cloned and all clones manipulate the same internal state.
 ///
 /// This handle gives you access to an interface to send pointer events to your
 /// clients.
@@ -127,12 +128,12 @@ impl PointerInternal {
 /// grab if any is active. See the [`PointerGrab`] trait for details.
 #[derive(Clone)]
 pub struct PointerHandle {
-    inner: Arc<Mutex<PointerInternal>>,
+    inner: Rc<RefCell<PointerInternal>>,
 }
 
 impl PointerHandle {
     pub(crate) fn new_pointer(&self, pointer: WlPointer) {
-        let mut guard = self.inner.lock().unwrap();
+        let mut guard = self.inner.borrow_mut();
         guard.known_pointers.push(pointer);
     }
 
@@ -140,17 +141,17 @@ impl PointerHandle {
     ///
     /// Overwrites any current grab.
     pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: u32) {
-        self.inner.lock().unwrap().grab = GrabStatus::Active(serial, Box::new(grab));
+        self.inner.borrow_mut().grab = GrabStatus::Active(serial, Box::new(grab));
     }
 
     /// Remove any current grab on this pointer, reseting it to the default behavior
     pub fn unset_grab(&self) {
-        self.inner.lock().unwrap().grab = GrabStatus::None;
+        self.inner.borrow_mut().grab = GrabStatus::None;
     }
 
     /// Check if this pointer is currently grabbed with this serial
     pub fn has_grab(&self, serial: u32) -> bool {
-        let guard = self.inner.lock().unwrap();
+        let guard = self.inner.borrow_mut();
         match guard.grab {
             GrabStatus::Active(s, _) => s == serial,
             _ => false,
@@ -159,7 +160,7 @@ impl PointerHandle {
 
     /// Check if this pointer is currently being grabbed
     pub fn is_grabbed(&self) -> bool {
-        let guard = self.inner.lock().unwrap();
+        let guard = self.inner.borrow_mut();
         match guard.grab {
             GrabStatus::None => false,
             _ => true,
@@ -184,7 +185,7 @@ impl PointerHandle {
         serial: u32,
         time: u32,
     ) {
-        let mut inner = self.inner.lock().unwrap();
+        let mut inner = self.inner.borrow_mut();
         inner.pending_focus = focus.clone();
         inner.with_grab(move |mut handle, grab| {
             grab.motion(&mut handle, location, focus, serial, time);
@@ -196,7 +197,7 @@ impl PointerHandle {
     /// This will internally send the appropriate button event to the client
     /// objects matching with the currently focused surface.
     pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) {
-        let mut inner = self.inner.lock().unwrap();
+        let mut inner = self.inner.borrow_mut();
         match state {
             ButtonState::Pressed => {
                 inner.pressed_buttons.push(button);
@@ -215,7 +216,7 @@ impl PointerHandle {
     ///
     /// A single frame will group multiple scroll events as if they happened in the same instance.
     pub fn axis(&self, details: AxisFrame) {
-        self.inner.lock().unwrap().with_grab(|mut handle, grab| {
+        self.inner.borrow_mut().with_grab(|mut handle, grab| {
             grab.axis(&mut handle, details);
         });
     }
@@ -517,10 +518,10 @@ pub(crate) fn create_pointer_handler<F, U, R>(token: CompositorToken<U, R>, cb:
 where
     R: Role<CursorImageRole> + 'static,
     U: 'static,
-    F: FnMut(CursorImageStatus) + Send + 'static,
+    F: FnMut(CursorImageStatus) + 'static,
 {
     PointerHandle {
-        inner: Arc::new(Mutex::new(PointerInternal::new(token, cb))),
+        inner: Rc::new(RefCell::new(PointerInternal::new(token, cb))),
     }
 }
 
@@ -537,8 +538,7 @@ where
     let destructor = match inner.clone() {
         Some(inner) => Some(move |pointer: WlPointer| {
             inner
-                .lock()
-                .unwrap()
+                .borrow_mut()
                 .known_pointers
                 .retain(|p| !p.as_ref().equals(&pointer.as_ref()))
         }),
@@ -554,7 +554,7 @@ where
                     hotspot_y,
                 } => {
                     if let Some(ref inner) = inner {
-                        let mut guard = inner.lock().unwrap();
+                        let mut guard = inner.borrow_mut();
                         // only allow setting the cursor icon if the current pointer focus
                         // is of the same client
                         let PointerInternal {

Don't promise thread-safety that we can't respect