File indexing completed on 2024-05-19 16:35:24

0001 /*
0002     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0003     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #pragma once
0009 
0010 #include "kwin_export.h"
0011 
0012 #include <QObject>
0013 #include <QRegion>
0014 #include <memory>
0015 
0016 struct wl_resource;
0017 
0018 namespace KWaylandServer
0019 {
0020 class ConfinedPointerV1InterfacePrivate;
0021 class Display;
0022 class LockedPointerV1InterfacePrivate;
0023 class PointerConstraintsV1InterfacePrivate;
0024 class SurfaceInterface;
0025 
0026 /**
0027  * Manager object to create pointer constraints.
0028  *
0029  * To create this manager use {@link Display::createPointerConstraintsV1}
0030  *
0031  * @see ConfinedPointerV1Interface
0032  * @see LockedPointerV1Interface
0033  */
0034 class KWIN_EXPORT PointerConstraintsV1Interface : public QObject
0035 {
0036     Q_OBJECT
0037 
0038 public:
0039     explicit PointerConstraintsV1Interface(Display *display, QObject *parent = nullptr);
0040     ~PointerConstraintsV1Interface() override;
0041 
0042 private:
0043     std::unique_ptr<PointerConstraintsV1InterfacePrivate> d;
0044 };
0045 
0046 /**
0047  * The LockedPointerV1Interface lets the client request to disable movements of
0048  * the virtual pointer (i.e. the cursor), effectively locking the pointer
0049  * to a position.
0050  *
0051  * It is up to the compositor whether the lock gets activated.
0052  * To activate it needs to use {@link LockedPointerV1Interface::setLocked}.
0053  * The compositor needs to ensure that the SurfaceInterface has pointer focus
0054  * and that the pointer is inside the {@link LockedPointerV1Interface::region} when
0055  * it activates the lock.
0056  *
0057  * While the lock is active the PointerInterface does no longer Q_EMIT pointer motion
0058  * events, but still emits relative pointer motion events.
0059  */
0060 class KWIN_EXPORT LockedPointerV1Interface : public QObject
0061 {
0062     Q_OBJECT
0063 
0064 public:
0065     ~LockedPointerV1Interface() override;
0066 
0067     enum class LifeTime : uint {
0068         OneShot = 1,
0069         Persistent = 2,
0070     };
0071 
0072     LifeTime lifeTime() const;
0073 
0074     /**
0075      * The intersection of this region and the input region of the SurfaceInterface is used
0076      * to determine where the pointer must be in order for the lock to activate.
0077      * It is up to the compositor whether to warp the pointer or require some kind of
0078      * user interaction for the lock to activate.
0079      *
0080      * If the region is empty the SurfaceInterface input region is used.
0081      *
0082      * @see regionChanged
0083      * @see SurfaceInterface::input
0084      */
0085     QRegion region() const;
0086 
0087     /**
0088      * Indicates where the mouse cursor should be positioned after it has been unlocked again.
0089      * The compositor can warp the cursor at this moment to the position. For that it
0090      * will not Q_EMIT any relative motion events. The hint is relative to the top-left
0091      * corner of the surface the lock was applied to. Only non-negative x and y values
0092      * are allowed. Otherwise the hint is invalid and should be ignored by the compositor.
0093      *
0094      * In case the client never set the hint, an invalid one will be returned.
0095      *
0096      * This function should be called when the compositor decides to break the lock or the
0097      * client unbinds the resource. To set the position in this case the compositor should
0098      * call this function when the aboutToBeUnbound signal has been emitted.
0099      *
0100      * @see cursorPositionHintChanged
0101      */
0102     QPointF cursorPositionHint() const;
0103 
0104     /**
0105      * Whether the Compositor set this pointer lock to be active.
0106      * @see setLocked
0107      * @see lockedChanged
0108      */
0109     bool isLocked() const;
0110 
0111     /**
0112      * Activates or deactivates the lock.
0113      *
0114      * A pointer lock can only be activated if the SurfaceInterface
0115      * this LockedPointerV1Interface was created for has pointer focus
0116      * and the pointer is inside the {@link region}.
0117      *
0118      * Unlocking resets the cursor position hint.
0119      *
0120      * @param locked Whether the lock should be active
0121      * @see isLocked
0122      * @see lockedChanged
0123      */
0124     void setLocked(bool locked);
0125 
0126 Q_SIGNALS:
0127     /**
0128      * This is signal is emitted when the locked pointer is about to be destroyed.
0129      */
0130     void aboutToBeDestroyed();
0131 
0132     /**
0133      * Emitted whenever the region changes.
0134      * This happens when the parent SurfaceInterface gets committed
0135      * @see region
0136      */
0137     void regionChanged();
0138 
0139     /**
0140      * Emitted whenever the cursor position hint changes.
0141      * This happens when the parent SurfaceInterface gets committed
0142      * @see cursorPositionHint
0143      */
0144     void cursorPositionHintChanged();
0145 
0146     /**
0147      * Emitted whenever the {@link isLocked} state changes.
0148      * @see isLocked
0149      * @see setLocked
0150      */
0151     void lockedChanged();
0152 
0153 private:
0154     LockedPointerV1Interface(SurfaceInterface *surface, LifeTime lifeTime, const QRegion &region, ::wl_resource *resource);
0155     std::unique_ptr<LockedPointerV1InterfacePrivate> d;
0156     friend class LockedPointerV1InterfacePrivate;
0157     friend class PointerConstraintsV1InterfacePrivate;
0158 };
0159 
0160 /**
0161  *
0162  * The ConfinedPointerV1Interface gets installed on a SurfaceInterface.
0163  * The confinement indicates that the SurfaceInterface wants to confine the
0164  * pointer to a region of the SurfaceInterface.
0165  *
0166  * It is up to the compositor whether the confinement gets activated.
0167  * To activate it needs to use {@link ConfinedPointerV1Interface::setConfined}.
0168  * The compositor needs to ensure that the SurfaceInterface has pointer focus
0169  * and that the pointer is inside the {@link ConfinedPointerV1Interface::region} when
0170  * it activates the confinement.
0171  *
0172  * From client side the confinement gets deactivated by destroying the ConfinedPointerV1Interface.
0173  * From compositor side the confinement can be deactivated by setting
0174  * {@link ConfinedPointerV1Interface::setConfined} to @c false.
0175  */
0176 class KWIN_EXPORT ConfinedPointerV1Interface : public QObject
0177 {
0178     Q_OBJECT
0179 
0180 public:
0181     ~ConfinedPointerV1Interface() override;
0182 
0183     enum class LifeTime : uint {
0184         OneShot = 1,
0185         Persistent = 2,
0186     };
0187 
0188     LifeTime lifeTime() const;
0189 
0190     /**
0191      * The intersection of this region and the input region of the SurfaceInterface is used
0192      * to determine where the pointer must be in order for the confinement to activate.
0193      * It is up to the compositor whether to warp the pointer or require some kind of
0194      * user interaction for the confinement to activate.
0195      *
0196      * If the region is empty the SurfaceInterface input region is used.
0197      *
0198      * @see regionChanged
0199      * @see SurfaceInterface::input
0200      */
0201     QRegion region() const;
0202 
0203     /**
0204      * Whether the Compositor set this pointer confinement to be active.
0205      * @see setConfined
0206      * @see confinedChanged
0207      */
0208     bool isConfined() const;
0209 
0210     /**
0211      * Activates or deactivates the confinement.
0212      *
0213      * A pointer confinement can only be activated if the SurfaceInterface
0214      * this ConfinedPointerV1Interface was created for has pointer focus
0215      * and the pointer is inside the {@link region}.
0216      *
0217      * @param confined Whether the confinement should be active
0218      * @see isConfined
0219      * @see confinedChanged
0220      */
0221     void setConfined(bool confined);
0222 
0223 Q_SIGNALS:
0224     /**
0225      * Emitted whenever the region changes.
0226      * This happens when the parent SurfaceInterface gets committed
0227      * @see region
0228      */
0229     void regionChanged();
0230 
0231     /**
0232      * Emitted whenever the {@link isConfined} state changes.
0233      * @see isConfined
0234      * @see setConfined
0235      */
0236     void confinedChanged();
0237 
0238 private:
0239     ConfinedPointerV1Interface(SurfaceInterface *surface, LifeTime lifeTime, const QRegion &region, ::wl_resource *resource);
0240     std::unique_ptr<ConfinedPointerV1InterfacePrivate> d;
0241     friend class ConfinedPointerV1InterfacePrivate;
0242     friend class PointerConstraintsV1InterfacePrivate;
0243 };
0244 
0245 } // namespace KWaylandServer