chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0)
1use std::fmt;
2
3use downcast_rs::{impl_downcast, Downcast};
4
5use crate::{
6 backend::input::TouchSlot,
7 input::SeatHandler,
8 utils::{Logical, Point, Serial},
9};
10
11use super::{DownEvent, MotionEvent, OrientationEvent, ShapeEvent, TouchInnerHandle, UpEvent};
12
13/// A trait to implement a touch grab
14///
15/// In some context, it is necessary to temporarily change the behavior of the touch handler. This is
16/// typically known as a touch grab. A typical example would be, during a drag'n'drop operation,
17/// the underlying surfaces will no longer receive classic pointer event, but rather special events.
18///
19/// This trait is the interface to intercept regular touch events and change them as needed, its
20/// interface mimics the [`TouchHandle`](super::TouchHandle) interface.
21///
22/// Any interactions with [`TouchHandle`](super::TouchHandle)
23/// should be done using [`TouchInnerHandle`], as handle is borrowed/locked before grab methods are called,
24/// so calling methods on [`TouchHandle`](super::TouchHandle) would result in a deadlock.
25///
26/// If your logic decides that the grab should end, both [`TouchInnerHandle`]
27/// and [`TouchHandle`](super::TouchHandle) have
28/// a method to change it.
29///
30/// When your grab ends (either as you requested it or if it was forcefully cancelled by the server),
31/// the struct implementing this trait will be dropped. As such you should put clean-up logic in the destructor,
32/// rather than trying to guess when the grab will end.
33pub trait TouchGrab<D: SeatHandler>: Send + Downcast {
34 /// A new touch point appeared
35 ///
36 /// This method allows you attach additional behavior to a down event, possibly altering it.
37 /// You generally will want to invoke [`TouchInnerHandle::down`] as part of your processing. If you
38 /// don't, the rest of the compositor will behave as if the down event never occurred.
39 ///
40 /// Some grabs (such as drag'n'drop, shell resize and motion) drop down events while they are active,
41 /// the default touch grab will keep the focus on the surface that started the grab.
42 fn down(
43 &mut self,
44 data: &mut D,
45 handle: &mut TouchInnerHandle<'_, D>,
46 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
47 event: &DownEvent,
48 seq: Serial,
49 );
50 /// A touch point disappeared
51 ///
52 /// This method allows you attach additional behavior to a up event, possibly altering it.
53 /// You generally will want to invoke [`TouchInnerHandle::up`] as part of your processing.
54 /// If you don't, the rest of the compositor will behave as if the up event never occurred.
55 ///
56 /// Some grabs (such as drag'n'drop, shell resize and motion) drop up events while they are active,
57 /// but will end when the touch point that initiated the grab disappeared.
58 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial);
59
60 /// A touch point has changed coordinates.
61 ///
62 /// This method allows you attach additional behavior to a motion event, possibly altering it.
63 /// You generally will want to invoke [`TouchInnerHandle::motion`] as part of your processing.
64 /// If you don't, the rest of the compositor will behave as if the motion event never occurred.
65 ///
66 /// **Note** that this is **not** intended to update the focus of the touch point, the focus
67 /// is only set on a down event. The focus provided to this function can be used to find DnD
68 /// targets during touch motion.
69 fn motion(
70 &mut self,
71 data: &mut D,
72 handle: &mut TouchInnerHandle<'_, D>,
73 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
74 event: &MotionEvent,
75 seq: Serial,
76 );
77
78 /// Marks the end of a set of events that logically belong together.
79 ///
80 /// This method allows you attach additional behavior to a frame event, possibly altering it.
81 /// You generally will want to invoke [`TouchInnerHandle::frame`] as part of your processing.
82 /// If you don't, the rest of the compositor will behave as if the frame event never occurred.
83 ///
84 /// This will to be called after one or more calls to down/motion events.
85 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial);
86
87 /// A touch session has been cancelled.
88 ///
89 /// This method allows you attach additional behavior to a cancel event, possibly altering it.
90 /// You generally will want to invoke [`TouchInnerHandle::cancel`] as part of your processing.
91 /// If you don't, the rest of the compositor will behave as if the cancel event never occurred.
92 ///
93 /// Usually called in case the compositor decides the touch stream is a global gesture.
94 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial);
95
96 /// A touch point has changed its shape.
97 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial);
98
99 /// A touch point has changed its orientation.
100 fn orientation(
101 &mut self,
102 data: &mut D,
103 handle: &mut TouchInnerHandle<'_, D>,
104 event: &OrientationEvent,
105 seq: Serial,
106 );
107
108 /// The data about the event that started the grab.
109 fn start_data(&self) -> &GrabStartData<D>;
110
111 /// The grab has been unset or replaced with another grab.
112 fn unset(&mut self, data: &mut D);
113}
114
115impl_downcast!(TouchGrab<D> where D: SeatHandler);
116
117/// Data about the event that started the grab.
118pub struct GrabStartData<D: SeatHandler> {
119 /// The focused surface and its location, if any, at the start of the grab.
120 ///
121 /// The location coordinates are in the global compositor space.
122 pub focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
123 /// The touch point that initiated the grab.
124 pub slot: TouchSlot,
125 /// The location of the down event that initiated the grab, in the global compositor space.
126 pub location: Point<f64, Logical>,
127}
128
129impl<D: SeatHandler + 'static> fmt::Debug for GrabStartData<D> {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 f.debug_struct("GrabStartData")
132 .field("focus", &self.focus.as_ref().map(|_| "..."))
133 .field("slot", &self.slot)
134 .field("location", &self.location)
135 .finish()
136 }
137}
138
139impl<D: SeatHandler + 'static> Clone for GrabStartData<D> {
140 fn clone(&self) -> Self {
141 GrabStartData {
142 focus: self.focus.clone(),
143 slot: self.slot,
144 location: self.location,
145 }
146 }
147}
148
149/// The default grab, the behavior when no particular grab is in progress
150#[derive(Debug)]
151pub struct DefaultGrab;
152
153impl<D: SeatHandler + 'static> TouchGrab<D> for DefaultGrab {
154 fn down(
155 &mut self,
156 data: &mut D,
157 handle: &mut TouchInnerHandle<'_, D>,
158 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
159 event: &DownEvent,
160 seq: Serial,
161 ) {
162 handle.down(data, focus.clone(), event, seq);
163 handle.set_grab(
164 self,
165 data,
166 event.serial,
167 TouchDownGrab {
168 start_data: GrabStartData {
169 focus,
170 slot: event.slot,
171 location: event.location,
172 },
173 touch_points: 1,
174 },
175 );
176 }
177
178 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial) {
179 handle.up(data, event, seq)
180 }
181
182 fn motion(
183 &mut self,
184 data: &mut D,
185 handle: &mut TouchInnerHandle<'_, D>,
186 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
187 event: &MotionEvent,
188 seq: Serial,
189 ) {
190 handle.motion(data, focus, event, seq)
191 }
192
193 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
194 handle.frame(data, seq)
195 }
196
197 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
198 handle.cancel(data, seq)
199 }
200
201 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial) {
202 handle.shape(data, event, seq)
203 }
204
205 fn orientation(
206 &mut self,
207 data: &mut D,
208 handle: &mut TouchInnerHandle<'_, D>,
209 event: &OrientationEvent,
210 seq: Serial,
211 ) {
212 handle.orientation(data, event, seq)
213 }
214
215 fn start_data(&self) -> &GrabStartData<D> {
216 unreachable!()
217 }
218
219 fn unset(&mut self, _data: &mut D) {}
220}
221
222/// A touch down grab, basic grab started when an user touches a surface
223/// to maintain it focused until the user releases the touch.
224///
225/// In case the user maintains several simultaneous touch points, release
226/// the grab once all are released.
227pub struct TouchDownGrab<D: SeatHandler> {
228 /// Start date for this grab
229 pub start_data: GrabStartData<D>,
230 /// Currently active touch points
231 pub touch_points: usize,
232}
233
234impl<D: SeatHandler + 'static> fmt::Debug for TouchDownGrab<D> {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 f.debug_struct("TouchDownGrab")
237 .field("start_data", &self.start_data)
238 .field("touch_points", &self.touch_points)
239 .finish()
240 }
241}
242
243impl<D: SeatHandler + 'static> TouchGrab<D> for TouchDownGrab<D> {
244 fn down(
245 &mut self,
246 data: &mut D,
247 handle: &mut TouchInnerHandle<'_, D>,
248 _focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
249 event: &DownEvent,
250 seq: Serial,
251 ) {
252 handle.down(data, self.start_data.focus.clone(), event, seq);
253 self.touch_points += 1;
254 }
255
256 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial) {
257 handle.up(data, event, seq);
258 self.touch_points = self.touch_points.saturating_sub(1);
259 if self.touch_points == 0 {
260 handle.unset_grab(self, data);
261 }
262 }
263
264 fn motion(
265 &mut self,
266 data: &mut D,
267 handle: &mut TouchInnerHandle<'_, D>,
268 _focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
269 event: &MotionEvent,
270 seq: Serial,
271 ) {
272 handle.motion(data, self.start_data.focus.clone(), event, seq)
273 }
274
275 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
276 handle.frame(data, seq)
277 }
278
279 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
280 handle.cancel(data, seq);
281 handle.unset_grab(self, data);
282 }
283
284 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial) {
285 handle.shape(data, event, seq)
286 }
287
288 fn orientation(
289 &mut self,
290 data: &mut D,
291 handle: &mut TouchInnerHandle<'_, D>,
292 event: &OrientationEvent,
293 seq: Serial,
294 ) {
295 handle.orientation(data, event, seq)
296 }
297
298 fn start_data(&self) -> &GrabStartData<D> {
299 &self.start_data
300 }
301
302 fn unset(&mut self, _data: &mut D) {}
303}