Skip to main content

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::{dispatch2::Dispatch2, 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> Dispatch2<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, D> for GlobalData
68where
69    D: RelativePointerHandler,
70{
71    fn event(
72        &self,
73        _data: &mut D,
74        _manager: &zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
75        _event: zwp_relative_pointer_manager_v1::Event,
76        _conn: &Connection,
77        _qh: &QueueHandle<D>,
78    ) {
79        unreachable!()
80    }
81}
82
83impl<D> Dispatch2<zwp_relative_pointer_v1::ZwpRelativePointerV1, D> for RelativePointerData
84where
85    D: RelativePointerHandler,
86{
87    fn event(
88        &self,
89        data: &mut D,
90        relative_pointer: &zwp_relative_pointer_v1::ZwpRelativePointerV1,
91        event: zwp_relative_pointer_v1::Event,
92        conn: &Connection,
93        qh: &QueueHandle<D>,
94    ) {
95        match event {
96            zwp_relative_pointer_v1::Event::RelativeMotion {
97                utime_hi,
98                utime_lo,
99                dx,
100                dy,
101                dx_unaccel,
102                dy_unaccel,
103            } => {
104                data.relative_pointer_motion(
105                    conn,
106                    qh,
107                    relative_pointer,
108                    &self.wl_pointer,
109                    RelativeMotionEvent {
110                        utime: ((utime_hi as u64) << 32) | (utime_lo as u64),
111                        delta: (dx, dy),
112                        delta_unaccel: (dx_unaccel, dy_unaccel),
113                    },
114                );
115            }
116            _ => unreachable!(),
117        }
118    }
119}