Changeset View
Changeset View
Standalone View
Standalone View
src/client/pointerconstraints.h
- This file was added.
1 | /**************************************************************************** | ||||
---|---|---|---|---|---|
2 | Copyright 2016 Martin Gräßlin <mgraesslin@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Lesser General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | later version accepted by the membership of KDE e.V. (or its | ||||
9 | successor approved by the membership of KDE e.V.), which shall | ||||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | | ||||
12 | This library is distributed in the hope that it will be useful, | ||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | Lesser General Public License for more details. | ||||
16 | | ||||
17 | You should have received a copy of the GNU Lesser General Public | ||||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | ****************************************************************************/ | ||||
20 | #ifndef KWAYLAND_CLIENT_POINTERCONSTRAINTS_H | ||||
21 | #define KWAYLAND_CLIENT_POINTERCONSTRAINTS_H | ||||
22 | | ||||
23 | #include <QObject> | ||||
24 | | ||||
25 | #include <KWayland/Client/kwaylandclient_export.h> | ||||
26 | | ||||
27 | struct zwp_pointer_constraints_v1; | ||||
28 | struct zwp_locked_pointer_v1; | ||||
29 | struct zwp_confined_pointer_v1; | ||||
30 | | ||||
31 | class QPointF; | ||||
32 | | ||||
33 | namespace KWayland | ||||
34 | { | ||||
35 | namespace Client | ||||
36 | { | ||||
37 | | ||||
38 | class EventQueue; | ||||
39 | class LockedPointer; | ||||
40 | class Surface; | ||||
41 | class Region; | ||||
42 | class ConfinedPointer; | ||||
43 | class Pointer; | ||||
44 | | ||||
45 | /** | ||||
46 | * @short Wrapper for the zwp_pointer_constraints_v1 interface. | ||||
47 | * | ||||
48 | * This class provides a convenient wrapper for the zwp_pointer_constraints_v1 interface. | ||||
49 | * | ||||
50 | * To use this class one needs to interact with the Registry. There are two | ||||
51 | * possible ways to create the PointerConstraints interface: | ||||
52 | * @code | ||||
53 | * PointerConstraints *c = registry->createPointerConstraints(name, version); | ||||
54 | * @endcode | ||||
55 | * | ||||
56 | * This creates the PointerConstraints and sets it up directly. As an alternative this | ||||
57 | * can also be done in a more low level way: | ||||
58 | * @code | ||||
59 | * PointerConstraints *c = new PointerConstraints; | ||||
60 | * c->setup(registry->bindPointerConstraints(name, version)); | ||||
61 | * @endcode | ||||
62 | * | ||||
63 | * The PointerConstraints can be used as a drop-in replacement for any zwp_pointer_constraints_v1 | ||||
64 | * pointer as it provides matching cast operators. | ||||
65 | * | ||||
66 | * @see Registry | ||||
67 | * @since 5.29 | ||||
68 | **/ | ||||
69 | class KWAYLANDCLIENT_EXPORT PointerConstraints : public QObject | ||||
70 | { | ||||
71 | Q_OBJECT | ||||
72 | public: | ||||
73 | /** | ||||
74 | * Creates a new PointerConstraints. | ||||
75 | * Note: after constructing the PointerConstraints it is not yet valid and one needs | ||||
76 | * to call setup. In order to get a ready to use PointerConstraints prefer using | ||||
77 | * Registry::createPointerConstraints. | ||||
78 | **/ | ||||
79 | explicit PointerConstraints(QObject *parent = nullptr); | ||||
80 | virtual ~PointerConstraints(); | ||||
81 | | ||||
82 | /** | ||||
83 | * Setup this PointerConstraints to manage the @p pointerconstraints. | ||||
84 | * When using Registry::createPointerConstraints there is no need to call this | ||||
85 | * method. | ||||
86 | **/ | ||||
87 | void setup(zwp_pointer_constraints_v1 *pointerconstraints); | ||||
88 | /** | ||||
89 | * @returns @c true if managing a zwp_pointer_constraints_v1. | ||||
90 | **/ | ||||
91 | bool isValid() const; | ||||
92 | /** | ||||
93 | * Releases the zwp_pointer_constraints_v1 interface. | ||||
94 | * After the interface has been released the PointerConstraints instance is no | ||||
95 | * longer valid and can be setup with another zwp_pointer_constraints_v1 interface. | ||||
96 | **/ | ||||
97 | void release(); | ||||
98 | /** | ||||
99 | * Destroys the data held by this PointerConstraints. | ||||
100 | * This method is supposed to be used when the connection to the Wayland | ||||
101 | * server goes away. If the connection is not valid anymore, it's not | ||||
102 | * possible to call release anymore as that calls into the Wayland | ||||
103 | * connection and the call would fail. This method cleans up the data, so | ||||
104 | * that the instance can be deleted or set up to a new zwp_pointer_constraints_v1 interface | ||||
105 | * once there is a new connection available. | ||||
106 | * | ||||
107 | * It is suggested to connect this method to ConnectionThread::connectionDied: | ||||
108 | * @code | ||||
109 | * connect(connection, &ConnectionThread::connectionDied, pointerconstraints, &PointerConstraints::destroy); | ||||
110 | * @endcode | ||||
111 | * | ||||
112 | * @see release | ||||
113 | **/ | ||||
114 | void destroy(); | ||||
115 | | ||||
116 | /** | ||||
117 | * Sets the @p queue to use for creating objects with this PointerConstraints. | ||||
118 | **/ | ||||
119 | void setEventQueue(EventQueue *queue); | ||||
120 | /** | ||||
121 | * @returns The event queue to use for creating objects with this PointerConstraints. | ||||
122 | **/ | ||||
123 | EventQueue *eventQueue(); | ||||
124 | | ||||
125 | /** | ||||
126 | * These values represent different lifetime semantics. They are passed | ||||
127 | * as arguments to the factory requests to specify how the constraint | ||||
128 | * lifetimes should be managed. | ||||
129 | * @see lockPointer | ||||
130 | * @see confinePointer | ||||
131 | **/ | ||||
132 | enum class LifeTime { | ||||
133 | /** | ||||
134 | * A OneShot pointer constraint will never reactivate once it has been | ||||
135 | * deactivated. | ||||
136 | **/ | ||||
137 | OneShot, | ||||
138 | /** | ||||
139 | * A persistent pointer constraint may again reactivate once it has | ||||
140 | * been deactivated. | ||||
141 | **/ | ||||
142 | Persistent | ||||
143 | }; | ||||
144 | | ||||
145 | /** | ||||
146 | * This factory method creates a LockedPointer. | ||||
147 | * | ||||
148 | * A LockedPointer lets the client request to disable movements of | ||||
149 | * the virtual pointer (i.e. the cursor), effectively locking the pointer | ||||
150 | * to a position. | ||||
151 | * | ||||
152 | * Creating a LockedPointer does not lock the pointer immediately; in the | ||||
153 | * future, when the compositor deems implementation-specific constraints | ||||
154 | * are satisfied, the pointer lock will be activated and the compositor | ||||
155 | * sends a locked event, reported by @link{LockedPointer::locked}. | ||||
156 | * | ||||
157 | * The protocol provides no guarantee that the constraints are ever | ||||
158 | * satisfied, and does not require the compositor to send an error if the | ||||
159 | * constraints cannot ever be satisfied. It is thus possible to request a | ||||
160 | * lock that will never activate. | ||||
161 | * | ||||
162 | * There may not be another pointer constraint of any kind requested or | ||||
163 | * active on the @p surface for any of the Pointer objects of the Seat of | ||||
164 | * the passed @p pointer when requesting a lock. If there is, an error will be | ||||
165 | * raised. | ||||
166 | * | ||||
167 | * The intersection of the @p region passed with this request and the input | ||||
168 | * region of the @p surface is used to determine where the pointer must be | ||||
169 | * in order for the lock to activate. It is up to the compositor whether to | ||||
170 | * warp the pointer or require some kind of user interaction for the lock | ||||
171 | * to activate. If the @p region is null the surface input region is used. | ||||
172 | * | ||||
173 | * A Surface may receive pointer focus without the lock being activated. | ||||
174 | * | ||||
175 | * Note that while a pointer is locked, the Pointer objects of the | ||||
176 | * corresponding seat will not emit any @link{Pointer::motion} signals, but | ||||
177 | * relative motion events will still be emitted via @link{RelativePointer::relativeMotion}. | ||||
178 | * Pointer axis and button events are unaffected. | ||||
179 | * | ||||
180 | * @param surface The Surface which should be constrained in pointer motion | ||||
181 | * @param pointer The Pointer object for which this LockedPointer should be created | ||||
182 | * @param region Region where to lock the pointer, if @c null the input region of the Surface is used | ||||
183 | * @param lifetime Whether the LockedPointer becomes invalid on unlocked | ||||
184 | * @param parent The parent object for the LockedPointer | ||||
185 | * @returns The factored LockedPointer | ||||
186 | **/ | ||||
187 | LockedPointer *lockPointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent = nullptr); | ||||
188 | | ||||
189 | /** | ||||
190 | * This factory method creates a ConfinedPointer. | ||||
191 | * | ||||
192 | * A ConfinedPointer lets the client request to confine the | ||||
193 | * pointer cursor to a given @p region. Creating a ConfinedPointer | ||||
194 | * does not take effect immediately; in the future, when the compositor | ||||
195 | * deems implementation-specific constraints are satisfied, the pointer | ||||
196 | * confinement will be activated and the compositor sends a confined event, | ||||
197 | * which is reported through the @link{ConfinedPointer::confined} signal. | ||||
198 | * | ||||
199 | * The intersection of the @p region passed and the input region of the | ||||
200 | * @p surface is used to determine where the pointer must be | ||||
201 | * in order for the confinement to activate. It is up to the compositor | ||||
202 | * whether to warp the pointer or require some kind of user interaction for | ||||
203 | * the confinement to activate. If the @p region is @c null the @p surface input | ||||
204 | * region is used. | ||||
205 | * | ||||
206 | * @param surface The Surface which should be constrained in pointer motion | ||||
207 | * @param pointer The Pointer object for which this LockedPointer should be created | ||||
208 | * @param region Region where to confine the pointer, if @c null the input region of the Surface is used | ||||
209 | * @param lifetime Whether the ConfinedPointer becomes invalid on unconfined | ||||
210 | * @param parent The parent object for the ConfinedPointer | ||||
211 | * @returns The factored ConfinedPointer | ||||
212 | **/ | ||||
213 | ConfinedPointer *confinePointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent = nullptr); | ||||
214 | | ||||
215 | operator zwp_pointer_constraints_v1*(); | ||||
216 | operator zwp_pointer_constraints_v1*() const; | ||||
217 | | ||||
218 | Q_SIGNALS: | ||||
219 | /** | ||||
220 | * The corresponding global for this interface on the Registry got removed. | ||||
221 | * | ||||
222 | * This signal gets only emitted if the PointerConstraints got created by | ||||
223 | * Registry::createPointerConstraints | ||||
224 | **/ | ||||
225 | void removed(); | ||||
226 | | ||||
227 | private: | ||||
228 | class Private; | ||||
229 | QScopedPointer<Private> d; | ||||
230 | }; | ||||
231 | | ||||
232 | /** | ||||
233 | * @short Wrapper for the zwp_locked_pointer_v1 interface. | ||||
234 | * | ||||
235 | * The LockedPointer represents a locked pointer state. | ||||
236 | * | ||||
237 | * While the lock of this object is active, the Pointer objects of the | ||||
238 | * associated seat will not emit any @link{Pointer::motion} events. | ||||
239 | * | ||||
240 | * This object will send the signal locked when the lock is activated. | ||||
241 | * Whenever the lock is activated, it is guaranteed that the locked surface | ||||
242 | * will already have received pointer focus and that the pointer will be | ||||
243 | * within the region passed to the request creating this object. | ||||
244 | * | ||||
245 | * To unlock the pointer, delete the object. | ||||
246 | * | ||||
247 | * If the compositor decides to unlock the pointer the unlocked signal is | ||||
248 | * emitted. | ||||
249 | * | ||||
250 | * When unlocking, the compositor may warp the cursor position to the set | ||||
251 | * cursor position hint. If it does, it will not result in any relative | ||||
252 | * motion events emitted via @link{RelativePointer::relativeMotion}. | ||||
253 | * | ||||
254 | * If the Surface the lock was requested on is destroyed and the lock is not | ||||
255 | * yet activated, the LockedPointer object is now defunct and must be | ||||
256 | * deleted. | ||||
257 | * | ||||
258 | * @see PointerConstraints::lockedPointer | ||||
259 | * @since 5.29 | ||||
260 | **/ | ||||
261 | class KWAYLANDCLIENT_EXPORT LockedPointer : public QObject | ||||
262 | { | ||||
263 | Q_OBJECT | ||||
264 | public: | ||||
265 | virtual ~LockedPointer(); | ||||
266 | | ||||
267 | /** | ||||
268 | * Setup this LockedPointer to manage the @p lockedpointer. | ||||
269 | * When using PointerConstraints::createLockedPointer there is no need to call this | ||||
270 | * method. | ||||
271 | **/ | ||||
272 | void setup(zwp_locked_pointer_v1 *lockedpointer); | ||||
273 | /** | ||||
274 | * @returns @c true if managing a zwp_locked_pointer_v1. | ||||
275 | **/ | ||||
276 | bool isValid() const; | ||||
277 | /** | ||||
278 | * Releases the zwp_locked_pointer_v1 interface. | ||||
279 | * After the interface has been released the LockedPointer instance is no | ||||
280 | * longer valid and can be setup with another zwp_locked_pointer_v1 interface. | ||||
281 | **/ | ||||
282 | void release(); | ||||
283 | /** | ||||
284 | * Destroys the data held by this LockedPointer. | ||||
285 | * This method is supposed to be used when the connection to the Wayland | ||||
286 | * server goes away. If the connection is not valid anymore, it's not | ||||
287 | * possible to call release anymore as that calls into the Wayland | ||||
288 | * connection and the call would fail. This method cleans up the data, so | ||||
289 | * that the instance can be deleted or set up to a new zwp_locked_pointer_v1 interface | ||||
290 | * once there is a new connection available. | ||||
291 | * | ||||
292 | * It is suggested to connect this method to ConnectionThread::connectionDied: | ||||
293 | * @code | ||||
294 | * connect(connection, &ConnectionThread::connectionDied, lockedpointer, &LockedPointer::destroy); | ||||
295 | * @endcode | ||||
296 | * | ||||
297 | * @see release | ||||
298 | **/ | ||||
299 | void destroy(); | ||||
300 | | ||||
301 | /** | ||||
302 | * Set the cursor position hint relative to the top left corner of the Surface. | ||||
303 | * | ||||
304 | * If the client is drawing its own cursor, it should update the position | ||||
305 | * hint to the position of its own cursor. A compositor may use this | ||||
306 | * information to warp the pointer upon unlock in order to avoid pointer | ||||
307 | * jumps. | ||||
308 | * | ||||
309 | * The cursor position hint is double buffered. The new hint will only take | ||||
310 | * effect when the associated surface gets it pending state applied. | ||||
311 | * See @link{Surface::commit} for details. | ||||
312 | * | ||||
313 | * @param surfaceLocal The new position hint in surface local coordinates | ||||
314 | * @see Surface::commit | ||||
315 | **/ | ||||
316 | void setCursorPositionHint(const QPointF &surfaceLocal); | ||||
317 | | ||||
318 | /** | ||||
319 | * Set a new region used to lock the pointer. | ||||
320 | * | ||||
321 | * The new lock region is double-buffered. The new lock region will | ||||
322 | * only take effect when the associated Surface gets its pending state | ||||
323 | * applied. See @link{Surface::commit} for details. | ||||
324 | * | ||||
325 | * @param region The new lock region. | ||||
326 | * @see Surface::commit | ||||
327 | * @see PointerConstraints::lockPointer | ||||
328 | **/ | ||||
329 | void setRegion(Region *region); | ||||
330 | | ||||
331 | operator zwp_locked_pointer_v1*(); | ||||
332 | operator zwp_locked_pointer_v1*() const; | ||||
333 | | ||||
334 | Q_SIGNALS: | ||||
335 | /** | ||||
336 | * Notification that the pointer lock of the seat's pointer is activated. | ||||
337 | * @see unlocked | ||||
338 | **/ | ||||
339 | void locked(); | ||||
340 | | ||||
341 | /** | ||||
342 | * Notification that the pointer lock of the seat's pointer is no longer | ||||
343 | * active. If this is a oneshot pointer lock (see | ||||
344 | * wp_pointer_constraints.lifetime) this object is now defunct and should | ||||
345 | * be destroyed. If this is a persistent pointer lock (see | ||||
346 | * wp_pointer_constraints.lifetime) this pointer lock may again | ||||
347 | * reactivate in the future. | ||||
348 | * @see locked | ||||
349 | **/ | ||||
350 | void unlocked(); | ||||
351 | | ||||
352 | private: | ||||
353 | friend class PointerConstraints; | ||||
354 | explicit LockedPointer(QObject *parent = nullptr); | ||||
355 | class Private; | ||||
356 | QScopedPointer<Private> d; | ||||
357 | }; | ||||
358 | | ||||
359 | /** | ||||
360 | * @short Wrapper for zwp_confined_pointer_v1 protocol | ||||
361 | * The confine pointer interface represents a confined pointer state. | ||||
362 | * | ||||
363 | * This object will send the signal 'confined' when the confinement is | ||||
364 | * activated. Whenever the confinement is activated, it is guaranteed that | ||||
365 | * the surface the pointer is confined to will already have received pointer | ||||
366 | * focus and that the pointer will be within the region passed to the request | ||||
367 | * creating this object. It is up to the compositor to decide whether this | ||||
368 | * requires some user interaction and if the pointer will warp to within the | ||||
369 | * passed region if outside. | ||||
370 | * | ||||
371 | * To unconfine the pointer, delete the object. | ||||
372 | * | ||||
373 | * If the compositor decides to unconfine the pointer the unconfined signal is | ||||
374 | * emitted. The ConfinedPointer object is at this point defunct and should | ||||
375 | * be deleted. | ||||
376 | * @see PointerConstraints::confinePointer | ||||
377 | * @since 5.29 | ||||
378 | **/ | ||||
379 | class KWAYLANDCLIENT_EXPORT ConfinedPointer : public QObject | ||||
380 | { | ||||
381 | Q_OBJECT | ||||
382 | public: | ||||
383 | virtual ~ConfinedPointer(); | ||||
384 | | ||||
385 | /** | ||||
386 | * Setup this ConfinedPointer to manage the @p confinedpointer. | ||||
387 | * When using PointerConstraints::createConfinedPointer there is no need to call this | ||||
388 | * method. | ||||
389 | **/ | ||||
390 | void setup(zwp_confined_pointer_v1 *confinedpointer); | ||||
391 | /** | ||||
392 | * @returns @c true if managing a zwp_confined_pointer_v1. | ||||
393 | **/ | ||||
394 | bool isValid() const; | ||||
395 | /** | ||||
396 | * Releases the zwp_confined_pointer_v1 interface. | ||||
397 | * After the interface has been released the ConfinedPointer instance is no | ||||
398 | * longer valid and can be setup with another zwp_confined_pointer_v1 interface. | ||||
399 | **/ | ||||
400 | void release(); | ||||
401 | /** | ||||
402 | * Destroys the data held by this ConfinedPointer. | ||||
403 | * This method is supposed to be used when the connection to the Wayland | ||||
404 | * server goes away. If the connection is not valid anymore, it's not | ||||
405 | * possible to call release anymore as that calls into the Wayland | ||||
406 | * connection and the call would fail. This method cleans up the data, so | ||||
407 | * that the instance can be deleted or set up to a new zwp_confined_pointer_v1 interface | ||||
408 | * once there is a new connection available. | ||||
409 | * | ||||
410 | * It is suggested to connect this method to ConnectionThread::connectionDied: | ||||
411 | * @code | ||||
412 | * connect(connection, &ConnectionThread::connectionDied, confinedpointer, &ConfinedPointer::destroy); | ||||
413 | * @endcode | ||||
414 | * | ||||
415 | * @see release | ||||
416 | **/ | ||||
417 | void destroy(); | ||||
418 | | ||||
419 | /** | ||||
420 | * Set a new region used to confine the pointer. | ||||
421 | * | ||||
422 | * The new confine region is double-buffered. The new confine region will | ||||
423 | * only take effect when the associated Surface gets its pending state | ||||
424 | * applied. See @link{Surface::commit} for details. | ||||
425 | * | ||||
426 | * If the confinement is active when the new confinement region is applied | ||||
427 | * and the pointer ends up outside of newly applied region, the pointer may | ||||
428 | * warped to a position within the new confinement region. If warped, a | ||||
429 | * @link{Pointer::motion} signal will be emitted, but no | ||||
430 | * @link{RelativePointer::relativeMotion} signal. | ||||
431 | * | ||||
432 | * The compositor may also, instead of using the new region, unconfine the | ||||
433 | * pointer. | ||||
434 | * | ||||
435 | * @param region The new confine region. | ||||
436 | * @see Surface::commit | ||||
437 | * @see PointerConstraints::confinePointer | ||||
438 | **/ | ||||
439 | void setRegion(Region *region); | ||||
440 | | ||||
441 | operator zwp_confined_pointer_v1*(); | ||||
442 | operator zwp_confined_pointer_v1*() const; | ||||
443 | | ||||
444 | Q_SIGNALS: | ||||
445 | /** | ||||
446 | * Notification that the pointer confinement of the seat's pointer is activated. | ||||
447 | * @see unconfined | ||||
448 | **/ | ||||
449 | void confined(); | ||||
450 | | ||||
451 | /** | ||||
452 | * Notification that the pointer confinement of the seat's pointer is no | ||||
453 | * longer active. If this is a oneshot pointer confinement (see | ||||
454 | * wp_pointer_constraints.lifetime) this object is now defunct and should | ||||
455 | * be destroyed. If this is a persistent pointer confinement (see | ||||
456 | * wp_pointer_constraints.lifetime) this pointer confinement may again | ||||
457 | * reactivate in the future. | ||||
458 | * @see confined | ||||
459 | **/ | ||||
460 | void unconfined(); | ||||
461 | | ||||
462 | private: | ||||
463 | friend class PointerConstraints; | ||||
464 | explicit ConfinedPointer(QObject *parent = nullptr); | ||||
465 | class Private; | ||||
466 | QScopedPointer<Private> d; | ||||
467 | }; | ||||
468 | | ||||
469 | | ||||
470 | } | ||||
471 | } | ||||
472 | | ||||
473 | #endif |