File indexing completed on 2024-12-22 05:09:22
0001 /* 0002 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #ifndef KWAYLAND_CLIENT_POINTERCONSTRAINTS_H 0007 #define KWAYLAND_CLIENT_POINTERCONSTRAINTS_H 0008 0009 #include <QObject> 0010 0011 #include "KWayland/Client/kwaylandclient_export.h" 0012 0013 struct zwp_pointer_constraints_v1; 0014 struct zwp_locked_pointer_v1; 0015 struct zwp_confined_pointer_v1; 0016 0017 class QPointF; 0018 0019 namespace KWayland 0020 { 0021 namespace Client 0022 { 0023 class EventQueue; 0024 class LockedPointer; 0025 class Surface; 0026 class Region; 0027 class ConfinedPointer; 0028 class Pointer; 0029 0030 /** 0031 * @short Wrapper for the zwp_pointer_constraints_v1 interface. 0032 * 0033 * This class provides a convenient wrapper for the zwp_pointer_constraints_v1 interface. 0034 * 0035 * To use this class one needs to interact with the Registry. There are two 0036 * possible ways to create the PointerConstraints interface: 0037 * @code 0038 * PointerConstraints *c = registry->createPointerConstraints(name, version); 0039 * @endcode 0040 * 0041 * This creates the PointerConstraints and sets it up directly. As an alternative this 0042 * can also be done in a more low level way: 0043 * @code 0044 * PointerConstraints *c = new PointerConstraints; 0045 * c->setup(registry->bindPointerConstraints(name, version)); 0046 * @endcode 0047 * 0048 * The PointerConstraints can be used as a drop-in replacement for any zwp_pointer_constraints_v1 0049 * pointer as it provides matching cast operators. 0050 * 0051 * @see Registry 0052 * @since 5.29 0053 **/ 0054 class KWAYLANDCLIENT_EXPORT PointerConstraints : public QObject 0055 { 0056 Q_OBJECT 0057 public: 0058 /** 0059 * Creates a new PointerConstraints. 0060 * Note: after constructing the PointerConstraints it is not yet valid and one needs 0061 * to call setup. In order to get a ready to use PointerConstraints prefer using 0062 * Registry::createPointerConstraints. 0063 **/ 0064 explicit PointerConstraints(QObject *parent = nullptr); 0065 ~PointerConstraints() override; 0066 0067 /** 0068 * Setup this PointerConstraints to manage the @p pointerconstraints. 0069 * When using Registry::createPointerConstraints there is no need to call this 0070 * method. 0071 **/ 0072 void setup(zwp_pointer_constraints_v1 *pointerconstraints); 0073 /** 0074 * @returns @c true if managing a zwp_pointer_constraints_v1. 0075 **/ 0076 bool isValid() const; 0077 /** 0078 * Releases the zwp_pointer_constraints_v1 interface. 0079 * After the interface has been released the PointerConstraints instance is no 0080 * longer valid and can be setup with another zwp_pointer_constraints_v1 interface. 0081 **/ 0082 void release(); 0083 /** 0084 * Destroys the data held by this PointerConstraints. 0085 * This method is supposed to be used when the connection to the Wayland 0086 * server goes away. If the connection is not valid anymore, it's not 0087 * possible to call release anymore as that calls into the Wayland 0088 * connection and the call would fail. This method cleans up the data, so 0089 * that the instance can be deleted or set up to a new zwp_pointer_constraints_v1 interface 0090 * once there is a new connection available. 0091 * 0092 * It is suggested to connect this method to ConnectionThread::connectionDied: 0093 * @code 0094 * connect(connection, &ConnectionThread::connectionDied, pointerconstraints, &PointerConstraints::destroy); 0095 * @endcode 0096 * 0097 * @see release 0098 **/ 0099 void destroy(); 0100 0101 /** 0102 * Sets the @p queue to use for creating objects with this PointerConstraints. 0103 **/ 0104 void setEventQueue(EventQueue *queue); 0105 /** 0106 * @returns The event queue to use for creating objects with this PointerConstraints. 0107 **/ 0108 EventQueue *eventQueue(); 0109 0110 /** 0111 * These values represent different lifetime semantics. They are passed 0112 * as arguments to the factory requests to specify how the constraint 0113 * lifetimes should be managed. 0114 * @see lockPointer 0115 * @see confinePointer 0116 **/ 0117 enum class LifeTime { 0118 /** 0119 * A OneShot pointer constraint will never reactivate once it has been 0120 * deactivated. 0121 **/ 0122 OneShot, 0123 /** 0124 * A persistent pointer constraint may again reactivate once it has 0125 * been deactivated. 0126 **/ 0127 Persistent, 0128 }; 0129 0130 /** 0131 * This factory method creates a LockedPointer. 0132 * 0133 * A LockedPointer lets the client request to disable movements of 0134 * the virtual pointer (i.e. the cursor), effectively locking the pointer 0135 * to a position. 0136 * 0137 * Creating a LockedPointer does not lock the pointer immediately; in the 0138 * future, when the compositor deems implementation-specific constraints 0139 * are satisfied, the pointer lock will be activated and the compositor 0140 * sends a locked event, reported by {@link LockedPointer::locked}. 0141 * 0142 * The protocol provides no guarantee that the constraints are ever 0143 * satisfied, and does not require the compositor to send an error if the 0144 * constraints cannot ever be satisfied. It is thus possible to request a 0145 * lock that will never activate. 0146 * 0147 * There may not be another pointer constraint of any kind requested or 0148 * active on the @p surface for any of the Pointer objects of the Seat of 0149 * the passed @p pointer when requesting a lock. If there is, an error will be 0150 * raised. 0151 * 0152 * The intersection of the @p region passed with this request and the input 0153 * region of the @p surface is used to determine where the pointer must be 0154 * in order for the lock to activate. It is up to the compositor whether to 0155 * warp the pointer or require some kind of user interaction for the lock 0156 * to activate. If the @p region is null the surface input region is used. 0157 * 0158 * A Surface may receive pointer focus without the lock being activated. 0159 * 0160 * Note that while a pointer is locked, the Pointer objects of the 0161 * corresponding seat will not emit any {@link Pointer::motion} signals, but 0162 * relative motion events will still be emitted via {@link RelativePointer::relativeMotion}. 0163 * Pointer axis and button events are unaffected. 0164 * 0165 * @param surface The Surface which should be constrained in pointer motion 0166 * @param pointer The Pointer object for which this LockedPointer should be created 0167 * @param region Region where to lock the pointer, if @c null the input region of the Surface is used 0168 * @param lifetime Whether the LockedPointer becomes invalid on unlocked 0169 * @param parent The parent object for the LockedPointer 0170 * @returns The factored LockedPointer 0171 **/ 0172 LockedPointer *lockPointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent = nullptr); 0173 0174 /** 0175 * This factory method creates a ConfinedPointer. 0176 * 0177 * A ConfinedPointer lets the client request to confine the 0178 * pointer cursor to a given @p region. Creating a ConfinedPointer 0179 * does not take effect immediately; in the future, when the compositor 0180 * deems implementation-specific constraints are satisfied, the pointer 0181 * confinement will be activated and the compositor sends a confined event, 0182 * which is reported through the {@link ConfinedPointer::confined} signal. 0183 * 0184 * The intersection of the @p region passed and the input region of the 0185 * @p surface is used to determine where the pointer must be 0186 * in order for the confinement to activate. It is up to the compositor 0187 * whether to warp the pointer or require some kind of user interaction for 0188 * the confinement to activate. If the @p region is @c null the @p surface input 0189 * region is used. 0190 * 0191 * @param surface The Surface which should be constrained in pointer motion 0192 * @param pointer The Pointer object for which this LockedPointer should be created 0193 * @param region Region where to confine the pointer, if @c null the input region of the Surface is used 0194 * @param lifetime Whether the ConfinedPointer becomes invalid on unconfined 0195 * @param parent The parent object for the ConfinedPointer 0196 * @returns The factored ConfinedPointer 0197 **/ 0198 ConfinedPointer *confinePointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent = nullptr); 0199 0200 operator zwp_pointer_constraints_v1 *(); 0201 operator zwp_pointer_constraints_v1 *() const; 0202 0203 Q_SIGNALS: 0204 /** 0205 * The corresponding global for this interface on the Registry got removed. 0206 * 0207 * This signal gets only emitted if the PointerConstraints got created by 0208 * Registry::createPointerConstraints 0209 **/ 0210 void removed(); 0211 0212 private: 0213 class Private; 0214 QScopedPointer<Private> d; 0215 }; 0216 0217 /** 0218 * @short Wrapper for the zwp_locked_pointer_v1 interface. 0219 * 0220 * The LockedPointer represents a locked pointer state. 0221 * 0222 * While the lock of this object is active, the Pointer objects of the 0223 * associated seat will not emit any {@link Pointer::motion} events. 0224 * 0225 * This object will send the signal locked when the lock is activated. 0226 * Whenever the lock is activated, it is guaranteed that the locked surface 0227 * will already have received pointer focus and that the pointer will be 0228 * within the region passed to the request creating this object. 0229 * 0230 * To unlock the pointer, delete the object. 0231 * 0232 * If the compositor decides to unlock the pointer the unlocked signal is 0233 * emitted. 0234 * 0235 * When unlocking, the compositor may warp the cursor position to the set 0236 * cursor position hint. If it does, it will not result in any relative 0237 * motion events emitted via {@link RelativePointer::relativeMotion}. 0238 * 0239 * If the Surface the lock was requested on is destroyed and the lock is not 0240 * yet activated, the LockedPointer object is now defunct and must be 0241 * deleted. 0242 * 0243 * @see PointerConstraints::lockedPointer 0244 * @since 5.29 0245 **/ 0246 class KWAYLANDCLIENT_EXPORT LockedPointer : public QObject 0247 { 0248 Q_OBJECT 0249 public: 0250 ~LockedPointer() override; 0251 0252 /** 0253 * Setup this LockedPointer to manage the @p lockedpointer. 0254 * When using PointerConstraints::createLockedPointer there is no need to call this 0255 * method. 0256 **/ 0257 void setup(zwp_locked_pointer_v1 *lockedpointer); 0258 /** 0259 * @returns @c true if managing a zwp_locked_pointer_v1. 0260 **/ 0261 bool isValid() const; 0262 /** 0263 * Releases the zwp_locked_pointer_v1 interface. 0264 * After the interface has been released the LockedPointer instance is no 0265 * longer valid and can be setup with another zwp_locked_pointer_v1 interface. 0266 **/ 0267 void release(); 0268 /** 0269 * Destroys the data held by this LockedPointer. 0270 * This method is supposed to be used when the connection to the Wayland 0271 * server goes away. If the connection is not valid anymore, it's not 0272 * possible to call release anymore as that calls into the Wayland 0273 * connection and the call would fail. This method cleans up the data, so 0274 * that the instance can be deleted or set up to a new zwp_locked_pointer_v1 interface 0275 * once there is a new connection available. 0276 * 0277 * It is suggested to connect this method to ConnectionThread::connectionDied: 0278 * @code 0279 * connect(connection, &ConnectionThread::connectionDied, lockedpointer, &LockedPointer::destroy); 0280 * @endcode 0281 * 0282 * @see release 0283 **/ 0284 void destroy(); 0285 0286 /** 0287 * Set the cursor position hint relative to the top left corner of the Surface. 0288 * 0289 * If the client is drawing its own cursor, it should update the position 0290 * hint to the position of its own cursor. A compositor may use this 0291 * information to warp the pointer upon unlock in order to avoid pointer 0292 * jumps. 0293 * 0294 * The cursor position hint is double buffered. The new hint will only take 0295 * effect when the associated surface gets it pending state applied. 0296 * See {@link Surface::commit} for details. 0297 * 0298 * @param surfaceLocal The new position hint in surface local coordinates 0299 * @see Surface::commit 0300 **/ 0301 void setCursorPositionHint(const QPointF &surfaceLocal); 0302 0303 /** 0304 * Set a new region used to lock the pointer. 0305 * 0306 * The new lock region is double-buffered. The new lock region will 0307 * only take effect when the associated Surface gets its pending state 0308 * applied. See {@link Surface::commit} for details. 0309 * 0310 * @param region The new lock region. 0311 * @see Surface::commit 0312 * @see PointerConstraints::lockPointer 0313 **/ 0314 void setRegion(Region *region); 0315 0316 operator zwp_locked_pointer_v1 *(); 0317 operator zwp_locked_pointer_v1 *() const; 0318 0319 Q_SIGNALS: 0320 /** 0321 * Notification that the pointer lock of the seat's pointer is activated. 0322 * @see unlocked 0323 **/ 0324 void locked(); 0325 0326 /** 0327 * Notification that the pointer lock of the seat's pointer is no longer 0328 * active. If this is a oneshot pointer lock (see 0329 * wp_pointer_constraints.lifetime) this object is now defunct and should 0330 * be destroyed. If this is a persistent pointer lock (see 0331 * wp_pointer_constraints.lifetime) this pointer lock may again 0332 * reactivate in the future. 0333 * @see locked 0334 **/ 0335 void unlocked(); 0336 0337 private: 0338 friend class PointerConstraints; 0339 explicit LockedPointer(QObject *parent = nullptr); 0340 class Private; 0341 QScopedPointer<Private> d; 0342 }; 0343 0344 /** 0345 * @short Wrapper for zwp_confined_pointer_v1 protocol 0346 * The confine pointer interface represents a confined pointer state. 0347 * 0348 * This object will send the signal 'confined' when the confinement is 0349 * activated. Whenever the confinement is activated, it is guaranteed that 0350 * the surface the pointer is confined to will already have received pointer 0351 * focus and that the pointer will be within the region passed to the request 0352 * creating this object. It is up to the compositor to decide whether this 0353 * requires some user interaction and if the pointer will warp to within the 0354 * passed region if outside. 0355 * 0356 * To unconfine the pointer, delete the object. 0357 * 0358 * If the compositor decides to unconfine the pointer the unconfined signal is 0359 * emitted. The ConfinedPointer object is at this point defunct and should 0360 * be deleted. 0361 * @see PointerConstraints::confinePointer 0362 * @since 5.29 0363 **/ 0364 class KWAYLANDCLIENT_EXPORT ConfinedPointer : public QObject 0365 { 0366 Q_OBJECT 0367 public: 0368 ~ConfinedPointer() override; 0369 0370 /** 0371 * Setup this ConfinedPointer to manage the @p confinedpointer. 0372 * When using PointerConstraints::createConfinedPointer there is no need to call this 0373 * method. 0374 **/ 0375 void setup(zwp_confined_pointer_v1 *confinedpointer); 0376 /** 0377 * @returns @c true if managing a zwp_confined_pointer_v1. 0378 **/ 0379 bool isValid() const; 0380 /** 0381 * Releases the zwp_confined_pointer_v1 interface. 0382 * After the interface has been released the ConfinedPointer instance is no 0383 * longer valid and can be setup with another zwp_confined_pointer_v1 interface. 0384 **/ 0385 void release(); 0386 /** 0387 * Destroys the data held by this ConfinedPointer. 0388 * This method is supposed to be used when the connection to the Wayland 0389 * server goes away. If the connection is not valid anymore, it's not 0390 * possible to call release anymore as that calls into the Wayland 0391 * connection and the call would fail. This method cleans up the data, so 0392 * that the instance can be deleted or set up to a new zwp_confined_pointer_v1 interface 0393 * once there is a new connection available. 0394 * 0395 * This method is automatically invoked when the Registry which created this 0396 * PointerConstraints gets destroyed. 0397 * 0398 * @see release 0399 **/ 0400 void destroy(); 0401 0402 /** 0403 * Set a new region used to confine the pointer. 0404 * 0405 * The new confine region is double-buffered. The new confine region will 0406 * only take effect when the associated Surface gets its pending state 0407 * applied. See {@link Surface::commit} for details. 0408 * 0409 * If the confinement is active when the new confinement region is applied 0410 * and the pointer ends up outside of newly applied region, the pointer may 0411 * warped to a position within the new confinement region. If warped, a 0412 * {@link Pointer::motion} signal will be emitted, but no 0413 * {@link RelativePointer::relativeMotion} signal. 0414 * 0415 * The compositor may also, instead of using the new region, unconfine the 0416 * pointer. 0417 * 0418 * @param region The new confine region. 0419 * @see Surface::commit 0420 * @see PointerConstraints::confinePointer 0421 **/ 0422 void setRegion(Region *region); 0423 0424 operator zwp_confined_pointer_v1 *(); 0425 operator zwp_confined_pointer_v1 *() const; 0426 0427 Q_SIGNALS: 0428 /** 0429 * Notification that the pointer confinement of the seat's pointer is activated. 0430 * @see unconfined 0431 **/ 0432 void confined(); 0433 0434 /** 0435 * Notification that the pointer confinement of the seat's pointer is no 0436 * longer active. If this is a oneshot pointer confinement (see 0437 * wp_pointer_constraints.lifetime) this object is now defunct and should 0438 * be destroyed. If this is a persistent pointer confinement (see 0439 * wp_pointer_constraints.lifetime) this pointer confinement may again 0440 * reactivate in the future. 0441 * @see confined 0442 **/ 0443 void unconfined(); 0444 0445 private: 0446 friend class PointerConstraints; 0447 explicit ConfinedPointer(QObject *parent = nullptr); 0448 class Private; 0449 QScopedPointer<Private> d; 0450 }; 0451 0452 } 0453 } 0454 0455 #endif