aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/handlers/qquickpointerhandler_p.h
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-11-09 10:41:53 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2017-11-14 05:35:54 +0000
commit3cc2148eab7f541bb8551087567b7580a2ea1822 (patch)
tree554f86030cbcf17e010579d02abd3e151e19362f /src/quick/handlers/qquickpointerhandler_p.h
parenta2e2c8a329768e783b205564e44b2f486b777d74 (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.h28
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)