smithay_client_toolkit/seat/
relative_pointer.rs

1use wayland_client::{
2    globals::GlobalList, protocol::wl_pointer, Connection, Dispatch, QueueHandle,
3};
4use wayland_protocols::wp::relative_pointer::zv1::client::{
5    zwp_relative_pointer_manager_v1, zwp_relative_pointer_v1,
6};
7
8use crate::{error::GlobalError, globals::GlobalData, registry::GlobalProxy};
9
10#[derive(Debug)]
11pub struct RelativePointerState {
12    relative_pointer_manager:
13        GlobalProxy<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1>,
14}
15
16impl RelativePointerState {
17    /// Bind `zwp_relative_pointer_manager_v1` global, if it exists
18    pub fn bind<D>(globals: &GlobalList, qh: &QueueHandle<D>) -> Self
19    where
20        D: Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData>
21            + 'static,
22    {
23        let relative_pointer_manager = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData));
24        Self { relative_pointer_manager }
25    }
26
27    pub fn get_relative_pointer<D>(
28        &self,
29        pointer: &wl_pointer::WlPointer,
30        qh: &QueueHandle<D>,
31    ) -> Result<zwp_relative_pointer_v1::ZwpRelativePointerV1, GlobalError>
32    where
33        D: Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData> + 'static,
34    {
35        let udata = RelativePointerData { wl_pointer: pointer.clone() };
36        Ok(self.relative_pointer_manager.get()?.get_relative_pointer(pointer, qh, udata))
37    }
38}
39
40#[derive(Debug)]
41pub struct RelativeMotionEvent {
42    /// (x, y) motion vector
43    pub delta: (f64, f64),
44    /// Unaccelerated (x, y) motion vector
45    pub delta_unaccel: (f64, f64),
46    /// Timestamp in microseconds
47    pub utime: u64,
48}
49
50pub trait RelativePointerHandler: Sized {
51    fn relative_pointer_motion(
52        &mut self,
53        conn: &Connection,
54        qh: &QueueHandle<Self>,
55        relative_pointer: &zwp_relative_pointer_v1::ZwpRelativePointerV1,
56        pointer: &wl_pointer::WlPointer,
57        event: RelativeMotionEvent,
58    );
59}
60
61#[doc(hidden)]
62#[derive(Debug)]
63pub struct RelativePointerData {
64    wl_pointer: wl_pointer::WlPointer,
65}
66
67impl<D> Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData, D>
68    for RelativePointerState
69where
70    D: Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData>
71        + RelativePointerHandler,
72{
73    fn event(
74        _data: &mut D,
75        _manager: &zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
76        _event: zwp_relative_pointer_manager_v1::Event,
77        _: &GlobalData,
78        _conn: &Connection,
79        _qh: &QueueHandle<D>,
80    ) {
81        unreachable!()
82    }
83}
84
85impl<D> Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData, D>
86    for RelativePointerState
87where
88    D: Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData>
89        + RelativePointerHandler,
90{
91    fn event(
92        data: &mut D,
93        relative_pointer: &zwp_relative_pointer_v1::ZwpRelativePointerV1,
94        event: zwp_relative_pointer_v1::Event,
95        udata: &RelativePointerData,
96        conn: &Connection,
97        qh: &QueueHandle<D>,
98    ) {
99        match event {
100            zwp_relative_pointer_v1::Event::RelativeMotion {
101                utime_hi,
102                utime_lo,
103                dx,
104                dy,
105                dx_unaccel,
106                dy_unaccel,
107            } => {
108                data.relative_pointer_motion(
109                    conn,
110                    qh,
111                    relative_pointer,
112                    &udata.wl_pointer,
113                    RelativeMotionEvent {
114                        utime: ((utime_hi as u64) << 32) | (utime_lo as u64),
115                        delta: (dx, dy),
116                        delta_unaccel: (dx_unaccel, dy_unaccel),
117                    },
118                );
119            }
120            _ => unreachable!(),
121        }
122    }
123}
124
125#[macro_export]
126macro_rules! delegate_relative_pointer {
127    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
128        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
129            $crate::reexports::protocols::wp::relative_pointer::zv1::client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: $crate::globals::GlobalData
130        ] => $crate::seat::relative_pointer::RelativePointerState);
131        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
132            $crate::reexports::protocols::wp::relative_pointer::zv1::client::zwp_relative_pointer_v1::ZwpRelativePointerV1: $crate::seat::relative_pointer::RelativePointerData
133        ] => $crate::seat::relative_pointer::RelativePointerState);
134    };
135}