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