1 | use wayland_client::{ |
2 | globals::GlobalList, |
3 | protocol::{wl_pointer, wl_region, wl_surface}, |
4 | Connection, Dispatch, QueueHandle, |
5 | }; |
6 | use wayland_protocols::wp::pointer_constraints::zv1::client::{ |
7 | zwp_confined_pointer_v1, zwp_locked_pointer_v1, zwp_pointer_constraints_v1, |
8 | }; |
9 | |
10 | use crate::{ |
11 | error::GlobalError, |
12 | globals::{GlobalData, ProvidesBoundGlobal}, |
13 | registry::GlobalProxy, |
14 | }; |
15 | |
16 | #[derive (Debug)] |
17 | pub struct PointerConstraintsState { |
18 | pointer_constraints: GlobalProxy<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1>, |
19 | } |
20 | |
21 | impl PointerConstraintsState { |
22 | /// Bind `zwp_pointer_constraints_v1` global, if it exists |
23 | pub fn bind<D>(globals: &GlobalList, qh: &QueueHandle<D>) -> Self |
24 | where |
25 | D: Dispatch<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, GlobalData> + 'static, |
26 | { |
27 | let pointer_constraints = GlobalProxy::from(globals.bind(qh, 1..=1, GlobalData)); |
28 | Self { pointer_constraints } |
29 | } |
30 | |
31 | /// Request that the compositor confine the pointer to a region |
32 | /// |
33 | /// It is a protocol error to call when a constraint already exists for a pointer on the seat. |
34 | pub fn confine_pointer<D>( |
35 | &self, |
36 | surface: &wl_surface::WlSurface, |
37 | pointer: &wl_pointer::WlPointer, |
38 | region: Option<&wl_region::WlRegion>, |
39 | lifetime: zwp_pointer_constraints_v1::Lifetime, |
40 | qh: &QueueHandle<D>, |
41 | ) -> Result<zwp_confined_pointer_v1::ZwpConfinedPointerV1, GlobalError> |
42 | where |
43 | D: Dispatch<zwp_confined_pointer_v1::ZwpConfinedPointerV1, PointerConstraintData> + 'static, |
44 | { |
45 | let udata = PointerConstraintData { surface: surface.clone(), pointer: pointer.clone() }; |
46 | Ok(self |
47 | .pointer_constraints |
48 | .get()? |
49 | .confine_pointer(surface, pointer, region, lifetime, qh, udata)) |
50 | } |
51 | |
52 | /// Request that the compositor lock the pointer in place |
53 | /// |
54 | /// It is a protocol error to call when a constraint already exists for a pointer on the seat. |
55 | pub fn lock_pointer<D>( |
56 | &self, |
57 | surface: &wl_surface::WlSurface, |
58 | pointer: &wl_pointer::WlPointer, |
59 | region: Option<&wl_region::WlRegion>, |
60 | lifetime: zwp_pointer_constraints_v1::Lifetime, |
61 | qh: &QueueHandle<D>, |
62 | ) -> Result<zwp_locked_pointer_v1::ZwpLockedPointerV1, GlobalError> |
63 | where |
64 | D: Dispatch<zwp_locked_pointer_v1::ZwpLockedPointerV1, PointerConstraintData> + 'static, |
65 | { |
66 | let udata = PointerConstraintData { surface: surface.clone(), pointer: pointer.clone() }; |
67 | Ok(self |
68 | .pointer_constraints |
69 | .get()? |
70 | .lock_pointer(surface, pointer, region, lifetime, qh, udata)) |
71 | } |
72 | } |
73 | |
74 | impl ProvidesBoundGlobal<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, 1> |
75 | for PointerConstraintsState |
76 | { |
77 | fn bound_global( |
78 | &self, |
79 | ) -> Result<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, GlobalError> { |
80 | self.pointer_constraints.get().cloned() |
81 | } |
82 | } |
83 | |
84 | pub trait PointerConstraintsHandler: Sized { |
85 | /// Pointer confinement activated by compositor |
86 | fn confined( |
87 | &mut self, |
88 | conn: &Connection, |
89 | qh: &QueueHandle<Self>, |
90 | confined_pointer: &zwp_confined_pointer_v1::ZwpConfinedPointerV1, |
91 | surface: &wl_surface::WlSurface, |
92 | pointer: &wl_pointer::WlPointer, |
93 | ); |
94 | |
95 | /// Pointer confinement deactivated by compositor |
96 | /// |
97 | /// For `Oneshot` constraints, it will not be reactivated. |
98 | fn unconfined( |
99 | &mut self, |
100 | conn: &Connection, |
101 | qh: &QueueHandle<Self>, |
102 | confined_pointer: &zwp_confined_pointer_v1::ZwpConfinedPointerV1, |
103 | surface: &wl_surface::WlSurface, |
104 | pointer: &wl_pointer::WlPointer, |
105 | ); |
106 | |
107 | /// Pointer lock activated by compositor |
108 | fn locked( |
109 | &mut self, |
110 | conn: &Connection, |
111 | qh: &QueueHandle<Self>, |
112 | locked_pointer: &zwp_locked_pointer_v1::ZwpLockedPointerV1, |
113 | surface: &wl_surface::WlSurface, |
114 | pointer: &wl_pointer::WlPointer, |
115 | ); |
116 | |
117 | /// Pointer lock deactivated by compositor |
118 | /// |
119 | /// For `Oneshot` constraints, it will not be reactivated. |
120 | fn unlocked( |
121 | &mut self, |
122 | conn: &Connection, |
123 | qh: &QueueHandle<Self>, |
124 | locked_pointer: &zwp_locked_pointer_v1::ZwpLockedPointerV1, |
125 | surface: &wl_surface::WlSurface, |
126 | pointer: &wl_pointer::WlPointer, |
127 | ); |
128 | } |
129 | |
130 | #[doc (hidden)] |
131 | #[derive (Debug)] |
132 | pub struct PointerConstraintData { |
133 | surface: wl_surface::WlSurface, |
134 | pointer: wl_pointer::WlPointer, |
135 | } |
136 | |
137 | impl<D> Dispatch<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, GlobalData, D> |
138 | for PointerConstraintsState |
139 | where |
140 | D: Dispatch<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, GlobalData> |
141 | + PointerConstraintsHandler, |
142 | { |
143 | fn event( |
144 | _data: &mut D, |
145 | _constraints: &zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, |
146 | _event: zwp_pointer_constraints_v1::Event, |
147 | _: &GlobalData, |
148 | _conn: &Connection, |
149 | _qh: &QueueHandle<D>, |
150 | ) { |
151 | unreachable!() |
152 | } |
153 | } |
154 | |
155 | impl<D> Dispatch<zwp_confined_pointer_v1::ZwpConfinedPointerV1, PointerConstraintData, D> |
156 | for PointerConstraintsState |
157 | where |
158 | D: Dispatch<zwp_confined_pointer_v1::ZwpConfinedPointerV1, PointerConstraintData> |
159 | + PointerConstraintsHandler, |
160 | { |
161 | fn event( |
162 | data: &mut D, |
163 | confined_pointer: &zwp_confined_pointer_v1::ZwpConfinedPointerV1, |
164 | event: zwp_confined_pointer_v1::Event, |
165 | udata: &PointerConstraintData, |
166 | conn: &Connection, |
167 | qh: &QueueHandle<D>, |
168 | ) { |
169 | match event { |
170 | zwp_confined_pointer_v1::Event::Confined => { |
171 | data.confined(conn, qh, confined_pointer, &udata.surface, &udata.pointer) |
172 | } |
173 | zwp_confined_pointer_v1::Event::Unconfined => { |
174 | data.unconfined(conn, qh, confined_pointer, &udata.surface, &udata.pointer) |
175 | } |
176 | _ => unreachable!(), |
177 | } |
178 | } |
179 | } |
180 | |
181 | impl<D> Dispatch<zwp_locked_pointer_v1::ZwpLockedPointerV1, PointerConstraintData, D> |
182 | for PointerConstraintsState |
183 | where |
184 | D: Dispatch<zwp_locked_pointer_v1::ZwpLockedPointerV1, PointerConstraintData> |
185 | + PointerConstraintsHandler, |
186 | { |
187 | fn event( |
188 | data: &mut D, |
189 | locked_pointer: &zwp_locked_pointer_v1::ZwpLockedPointerV1, |
190 | event: zwp_locked_pointer_v1::Event, |
191 | udata: &PointerConstraintData, |
192 | conn: &Connection, |
193 | qh: &QueueHandle<D>, |
194 | ) { |
195 | match event { |
196 | zwp_locked_pointer_v1::Event::Locked => { |
197 | data.locked(conn, qh, locked_pointer, &udata.surface, &udata.pointer) |
198 | } |
199 | zwp_locked_pointer_v1::Event::Unlocked => { |
200 | data.unlocked(conn, qh, locked_pointer, &udata.surface, &udata.pointer) |
201 | } |
202 | _ => unreachable!(), |
203 | } |
204 | } |
205 | } |
206 | |
207 | #[macro_export ] |
208 | macro_rules! delegate_pointer_constraints { |
209 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { |
210 | $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ |
211 | $crate::reexports::protocols::wp::pointer_constraints::zv1::client::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1: $crate::globals::GlobalData |
212 | ] => $crate::seat::pointer_constraints::PointerConstraintsState); |
213 | $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ |
214 | $crate::reexports::protocols::wp::pointer_constraints::zv1::client::zwp_confined_pointer_v1::ZwpConfinedPointerV1: $crate::seat::pointer_constraints::PointerConstraintData |
215 | ] => $crate::seat::pointer_constraints::PointerConstraintsState); |
216 | $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ |
217 | $crate::reexports::protocols::wp::pointer_constraints::zv1::client::zwp_locked_pointer_v1::ZwpLockedPointerV1: $crate::seat::pointer_constraints::PointerConstraintData |
218 | ] => $crate::seat::pointer_constraints::PointerConstraintsState); |
219 | }; |
220 | } |
221 | |