gioser

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Definiciones

⎇ main vendor/smithay/src/wayland/relative_pointer.rs Rust · 296 líneas · 11.5 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0) a91da3fea · Sergio ·

1//! Utilities for relative pointer support
2//!
3//! [PointerHandle::relative_motion] sends relative pointer events to any
4//! [ZwpRelativePointerV1] objects created by the client.
5//!
6//! ```
7//! extern crate wayland_server;
8//! extern crate smithay;
9//!
10//! use smithay::wayland::relative_pointer::RelativePointerManagerState;
11//! use smithay::delegate_relative_pointer;
12//! # use smithay::backend::input::KeyState;
13//! # use smithay::input::{
14//! #   pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
15//! #             GestureSwipeBeginEvent, GestureSwipeUpdateEvent, GestureSwipeEndEvent,
16//! #             GesturePinchBeginEvent, GesturePinchUpdateEvent, GesturePinchEndEvent,
17//! #             GestureHoldBeginEvent, GestureHoldEndEvent},
18//! #   keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
19//! #   touch::{DownEvent, UpEvent, MotionEvent as TouchMotionEvent, ShapeEvent, OrientationEvent, TouchTarget},
20//! #   Seat, SeatHandler, SeatState,
21//! # };
22//! # use smithay::utils::{IsAlive, Serial};
23//!
24//! # #[derive(Debug, Clone, PartialEq)]
25//! # struct Target;
26//! # impl IsAlive for Target {
27//! #   fn alive(&self) -> bool { true }
28//! # }
29//! # impl PointerTarget<State> for Target {
30//! #   fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
31//! #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
32//! #   fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {}
33//! #   fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {}
34//! #   fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {}
35//! #   fn frame(&self, seat: &Seat<State>, data: &mut State) {}
36//! #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {}
37//! #   fn gesture_swipe_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeBeginEvent) {}
38//! #   fn gesture_swipe_update(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeUpdateEvent) {}
39//! #   fn gesture_swipe_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeEndEvent) {}
40//! #   fn gesture_pinch_begin(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchBeginEvent) {}
41//! #   fn gesture_pinch_update(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchUpdateEvent) {}
42//! #   fn gesture_pinch_end(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchEndEvent) {}
43//! #   fn gesture_hold_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldBeginEvent) {}
44//! #   fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {}
45//! # }
46//! # impl KeyboardTarget<State> for Target {
47//! #   fn enter(&self, seat: &Seat<State>, data: &mut State, keys: Vec<KeysymHandle<'_>>, serial: Serial) {}
48//! #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial) {}
49//! #   fn key(
50//! #       &self,
51//! #       seat: &Seat<State>,
52//! #       data: &mut State,
53//! #       key: KeysymHandle<'_>,
54//! #       state: KeyState,
55//! #       serial: Serial,
56//! #       time: u32,
57//! #   ) {}
58//! #   fn modifiers(&self, seat: &Seat<State>, data: &mut State, modifiers: ModifiersState, serial: Serial) {}
59//! # }
60//! # impl TouchTarget<State> for Target {
61//! #   fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {}
62//! #   fn up(&self, seat: &Seat<State>, data: &mut State, event: &UpEvent, seq: Serial) {}
63//! #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &TouchMotionEvent, seq: Serial) {}
64//! #   fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
65//! #   fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
66//! #   fn shape(&self, seat: &Seat<State>, data: &mut State, event: &ShapeEvent, seq: Serial) {}
67//! #   fn orientation(&self, seat: &Seat<State>, data: &mut State, event: &OrientationEvent, seq: Serial) {}
68//! # }
69//! # struct State {
70//! #     seat_state: SeatState<Self>,
71//! # };
72//! # let mut display = wayland_server::Display::<State>::new().unwrap();
73//! # impl SeatHandler for State {
74//! #     type KeyboardFocus = Target;
75//! #     type PointerFocus = Target;
76//! #     type TouchFocus = Target;
77//! #
78//! #     fn seat_state(&mut self) -> &mut SeatState<Self> {
79//! #         &mut self.seat_state
80//! #     }
81//! # }
82//! let state = RelativePointerManagerState::new::<State>(&display.handle());
83//!
84//! delegate_relative_pointer!(State);
85//! ```
86
87use std::sync::{atomic::Ordering, Arc, Mutex};
88
89use atomic_float::AtomicF64;
90use wayland_protocols::wp::relative_pointer::zv1::server::{
91    zwp_relative_pointer_manager_v1::{self, ZwpRelativePointerManagerV1},
92    zwp_relative_pointer_v1::{self, ZwpRelativePointerV1},
93};
94use wayland_server::{
95    backend::{ClientId, GlobalId},
96    protocol::wl_surface::WlSurface,
97    Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
98};
99
100use crate::{
101    input::{
102        pointer::{PointerHandle, RelativeMotionEvent},
103        SeatHandler,
104    },
105    wayland::seat::PointerUserData,
106};
107
108const MANAGER_VERSION: u32 = 1;
109
110#[derive(Debug, Default)]
111pub(crate) struct WpRelativePointerHandle {
112    known_relative_pointers: Mutex<Vec<ZwpRelativePointerV1>>,
113}
114
115impl WpRelativePointerHandle {
116    fn new_relative_pointer(&self, pointer: ZwpRelativePointerV1) {
117        self.known_relative_pointers.lock().unwrap().push(pointer);
118    }
119
120    pub(super) fn relative_motion<D: SeatHandler + 'static>(
121        &self,
122        surface: &WlSurface,
123        event: &RelativeMotionEvent,
124    ) {
125        self.for_each_focused_pointer(surface, |ptr| {
126            let client_scale = ptr
127                .data::<RelativePointerUserData<D>>()
128                .unwrap()
129                .client_scale
130                .load(Ordering::Acquire);
131            let delta = event.delta.to_client(client_scale);
132            let delta_unaccel = event.delta_unaccel.to_client(client_scale);
133
134            let utime_hi = (event.utime >> 32) as u32;
135            let utime_lo = (event.utime & 0xffffffff) as u32;
136            ptr.relative_motion(
137                utime_hi,
138                utime_lo,
139                delta.x,
140                delta.y,
141                delta_unaccel.x,
142                delta_unaccel.y,
143            );
144        })
145    }
146
147    fn for_each_focused_pointer(&self, surface: &WlSurface, mut f: impl FnMut(ZwpRelativePointerV1)) {
148        let inner = self.known_relative_pointers.lock().unwrap();
149        for ptr in &*inner {
150            if ptr.id().same_client_as(&surface.id()) {
151                f(ptr.clone())
152            }
153        }
154    }
155}
156
157/// User data of ZwpRelativePointerV1 object
158#[derive(Debug)]
159pub struct RelativePointerUserData<D: SeatHandler> {
160    handle: Option<PointerHandle<D>>,
161    client_scale: Arc<AtomicF64>,
162}
163
164/// State of the relative pointer manager
165#[derive(Debug)]
166pub struct RelativePointerManagerState {
167    global: GlobalId,
168}
169
170impl RelativePointerManagerState {
171    /// Register new [ZwpRelativePointerV1] global
172    pub fn new<D>(display: &DisplayHandle) -> Self
173    where
174        D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>,
175        D: Dispatch<ZwpRelativePointerManagerV1, ()>,
176        D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
177        D: SeatHandler,
178        D: 'static,
179    {
180        let global = display.create_global::<D, ZwpRelativePointerManagerV1, _>(MANAGER_VERSION, ());
181
182        Self { global }
183    }
184
185    /// [ZwpRelativePointerV1] GlobalId getter
186    pub fn global(&self) -> GlobalId {
187        self.global.clone()
188    }
189}
190
191impl<D> Dispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
192where
193    D: Dispatch<ZwpRelativePointerManagerV1, ()>,
194    D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
195    D: SeatHandler,
196    D: 'static,
197{
198    fn request(
199        _state: &mut D,
200        _client: &wayland_server::Client,
201        _relative_pointer_manager: &ZwpRelativePointerManagerV1,
202        request: zwp_relative_pointer_manager_v1::Request,
203        _data: &(),
204        _dh: &DisplayHandle,
205        data_init: &mut wayland_server::DataInit<'_, D>,
206    ) {
207        match request {
208            zwp_relative_pointer_manager_v1::Request::GetRelativePointer { id, pointer } => {
209                let data = pointer.data::<PointerUserData<D>>().unwrap();
210                let user_data = RelativePointerUserData {
211                    handle: data.handle.clone(),
212                    client_scale: data.client_scale.clone(),
213                };
214                let pointer = data_init.init(id, user_data);
215                if let Some(handle) = &data.handle {
216                    handle.wp_relative.new_relative_pointer(pointer);
217                }
218            }
219            zwp_relative_pointer_manager_v1::Request::Destroy => {}
220            _ => unreachable!(),
221        }
222    }
223}
224
225impl<D> GlobalDispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
226where
227    D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>
228        + Dispatch<ZwpRelativePointerManagerV1, ()>
229        + SeatHandler
230        + 'static,
231{
232    fn bind(
233        _state: &mut D,
234        _dh: &DisplayHandle,
235        _client: &Client,
236        resource: New<ZwpRelativePointerManagerV1>,
237        _global_data: &(),
238        data_init: &mut DataInit<'_, D>,
239    ) {
240        data_init.init(resource, ());
241    }
242}
243
244impl<D> Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>, D> for RelativePointerManagerState
245where
246    D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
247    D: SeatHandler,
248    D: 'static,
249{
250    fn request(
251        _state: &mut D,
252        _client: &wayland_server::Client,
253        _relative_pointer: &ZwpRelativePointerV1,
254        request: zwp_relative_pointer_v1::Request,
255        _data: &RelativePointerUserData<D>,
256        _dh: &DisplayHandle,
257        _data_init: &mut wayland_server::DataInit<'_, D>,
258    ) {
259        match request {
260            zwp_relative_pointer_v1::Request::Destroy => {}
261            _ => unreachable!(),
262        }
263    }
264
265    fn destroyed(
266        _state: &mut D,
267        _: ClientId,
268        object: &ZwpRelativePointerV1,
269        data: &RelativePointerUserData<D>,
270    ) {
271        if let Some(ref handle) = data.handle {
272            handle
273                .wp_relative
274                .known_relative_pointers
275                .lock()
276                .unwrap()
277                .retain(|p| p.id() != object.id());
278        }
279    }
280}
281
282/// Macro to delegate implementation of the relative pointer protocol
283#[macro_export]
284macro_rules! delegate_relative_pointer {
285    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
286        $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
287            $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: ()
288        ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
289        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
290            $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: ()
291        ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
292        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
293            $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_v1::ZwpRelativePointerV1: $crate::wayland::relative_pointer::RelativePointerUserData<Self>
294        ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
295    };
296}