diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-11-09 10:41:53 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-11-14 05:35:54 +0000 |
commit | 3cc2148eab7f541bb8551087567b7580a2ea1822 (patch) | |
tree | 554f86030cbcf17e010579d02abd3e151e19362f /src/quick/handlers/qquickpointerhandler_p.h | |
parent | a2e2c8a329768e783b205564e44b2f486b777d74 (diff) |
PointerHandler: add grabPermissions, enforce in setExclusiveGrab
As soon as we enable the concept that PointerHandlers can use passive
grabs to lurk, monitor all movements, and then steal the passive grab,
they can fight over the grab. For example if there are two items with
PinchHandlers, and two or more touches occur within bounds for both,
then each update event can cause the other PinchHandler to steal the
grabs and become active.
So we replace stealing with negotiation: the handler which wants to
take over the grab checks its own flags to see whether that's allowed,
and the handler which is about to lose its grab also has the right
to approve or deny the takeover (just as QQuickItem has had
keepMouseGrab and keepTouchGrab for a long time.) Additionally,
if one handler wants to cancel another handler's grab without
taking over (simply set the grabber to null), it must be approved.
A single-point handler can simply call setExclusiveGrab, with the
expectation that permission may be granted or denied. A multi-point
handler only wants to grab all points if grabbing all of them will
be allowed, otherwise grab none; so it calls canGrab on each point
to check beforehand. Thus, when two handlers are competing for the
same grabs, one or both can be prevented from stealing from each other,
or from Handlers in general, or from Items, or some combination.
Change-Id: I5c733b2b8995ce686da0be42244394eeee82a268
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/handlers/qquickpointerhandler_p.h')
-rw-r--r-- | src/quick/handlers/qquickpointerhandler_p.h | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 24a058275d..9a77dd714a 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -67,11 +67,27 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QQuickItem * target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT) + Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged) public: explicit QQuickPointerHandler(QObject *parent = 0); virtual ~QQuickPointerHandler(); + enum GrabPermission { + TakeOverForbidden = 0x0, + CanTakeOverFromHandlersOfSameType = 0x01, + CanTakeOverFromHandlersOfDifferentType= 0x02, + CanTakeOverFromItems = 0x04, + CanTakeOverFromAnything = 0x0F, + ApprovesTakeOverByHandlersOfSameType = 0x10, + ApprovesTakeOverByHandlersOfDifferentType= 0x20, + ApprovesTakeOverByItems = 0x40, + ApprovesCancellation = 0x80, + ApprovesTakeOverByAnything = 0xF0 + }; + Q_DECLARE_FLAGS(GrabPermissions, GrabPermission) + Q_FLAG(GrabPermissions) + public: bool enabled() const { return m_enabled; } void setEnabled(bool enabled); @@ -85,11 +101,15 @@ public: void handlePointerEvent(QQuickPointerEvent *event); + GrabPermissions grabPermissions() const { return static_cast<GrabPermissions>(m_grabPermissions); } + void setGrabPermissions(GrabPermissions grabPermissions); + Q_SIGNALS: void enabledChanged(); void activeChanged(); void targetChanged(); void grabChanged(QQuickEventPoint *point); + void grabPermissionChanged(); void canceled(QQuickEventPoint *point); protected: @@ -99,8 +119,10 @@ protected: void setActive(bool active); virtual void onActiveChanged() { } virtual void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point); + virtual bool canGrab(QQuickEventPoint *point); + virtual bool approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber); void setPassiveGrab(QQuickEventPoint *point, bool grab = true); - void setExclusiveGrab(QQuickEventPoint *point, bool grab = true); + bool setExclusiveGrab(QQuickEventPoint *point, bool grab = true); void cancelAllGrabs(QQuickEventPoint *point); QPointF eventPos(const QQuickEventPoint *point) const; bool parentContains(const QQuickEventPoint *point) const; @@ -113,11 +135,15 @@ private: bool m_targetExplicitlySet : 1; bool m_hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state bool m_hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state + uint m_reserved : 19; + uint8_t m_grabPermissions : 8; friend class QQuickEventPoint; friend class QQuickWindowPrivate; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerHandler::GrabPermissions) + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickPointerHandler) |