aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/handlers/qquickpointerhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/handlers/qquickpointerhandler.cpp')
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp150
1 files changed, 92 insertions, 58 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index ce59a35b62..0dc2435b4e 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -247,31 +247,32 @@ bool QQuickPointerHandler::isCursorShapeExplicitlySet() const
call its parent class's implementation in addition to (usually after)
whatever custom behavior it implements.
*/
-void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
+void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QPointingDevice::GrabTransition transition,
+ QPointerEvent *event, QEventPoint &point)
{
+ Q_UNUSED(event);
qCDebug(lcPointerHandlerGrab) << point << transition << grabber;
- Q_ASSERT(point);
if (grabber == this) {
bool wasCanceled = false;
switch (transition) {
- case QQuickEventPoint::GrabPassive:
- case QQuickEventPoint::GrabExclusive:
+ case QPointingDevice::GrabPassive:
+ case QPointingDevice::GrabExclusive:
break;
- case QQuickEventPoint::CancelGrabPassive:
- case QQuickEventPoint::CancelGrabExclusive:
+ case QPointingDevice::CancelGrabPassive:
+ case QPointingDevice::CancelGrabExclusive:
wasCanceled = true; // the grab was stolen by something else
Q_FALLTHROUGH();
- case QQuickEventPoint::UngrabPassive:
- case QQuickEventPoint::UngrabExclusive:
+ case QPointingDevice::UngrabPassive:
+ case QPointingDevice::UngrabExclusive:
setActive(false);
- point->setAccepted(false);
+ point.setAccepted(false);
if (auto par = parentItem()) {
Q_D(const QQuickPointerHandler);
par->setKeepMouseGrab(d->hadKeepMouseGrab);
par->setKeepTouchGrab(d->hadKeepTouchGrab);
}
break;
- case QQuickEventPoint::OverrideGrabPassive:
+ case QPointingDevice::OverrideGrabPassive:
// Passive grab is still there, but we won't receive point updates right now.
// No need to notify about this.
return;
@@ -297,13 +298,13 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEv
grab, or it may acquire an exclusive grab if the gesture clearly must not
be interpreted in another way by another handler.
*/
-void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab)
+void QQuickPointerHandler::setPassiveGrab(QPointerEvent *event, const QEventPoint &point, bool grab)
{
qCDebug(lcPointerHandlerGrab) << point << grab;
if (grab) {
- point->setGrabberPointerHandler(this, false);
+ event->addPassiveGrabber(point, this);
} else {
- point->removePassiveGrabber(this);
+ event->removePassiveGrabber(point, this);
}
}
@@ -318,11 +319,11 @@ void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab)
also calls approveGrabTransition() on the handler which is about to lose
its grab. Either one can deny the takeover.
*/
-bool QQuickPointerHandler::canGrab(QQuickEventPoint *point)
+bool QQuickPointerHandler::canGrab(QPointerEvent *event, const QEventPoint &point)
{
- QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler();
- return approveGrabTransition(point, this) &&
- (existingPhGrabber ? existingPhGrabber->approveGrabTransition(point, this) : true);
+ QQuickPointerHandler *existingPhGrabber = qobject_cast<QQuickPointerHandler *>(event->exclusiveGrabber(point));
+ return approveGrabTransition(event, point, this) &&
+ (existingPhGrabber ? existingPhGrabber->approveGrabTransition(event, point, this) : true);
}
/*!
@@ -331,15 +332,15 @@ bool QQuickPointerHandler::canGrab(QQuickEventPoint *point)
will take the grab, and once on the instance which would thereby lose its grab,
in case of a takeover scenario.
*/
-bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber)
+bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEventPoint &point, QObject *proposedGrabber)
{
Q_D(const QQuickPointerHandler);
bool allowed = false;
if (proposedGrabber == this) {
- QObject* existingGrabber = point->exclusiveGrabber();
+ QObject* existingGrabber = event->exclusiveGrabber(point);
allowed = (existingGrabber == nullptr) || ((d->grabPermissions & CanTakeOverFromAnything) == CanTakeOverFromAnything);
if (existingGrabber) {
- if (QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler()) {
+ if (QQuickPointerHandler *existingPhGrabber = qobject_cast<QQuickPointerHandler *>(event->exclusiveGrabber(point))) {
if (!allowed && (d->grabPermissions & CanTakeOverFromHandlersOfDifferentType) &&
existingPhGrabber->metaObject()->className() != metaObject()->className())
allowed = true;
@@ -347,9 +348,9 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
existingPhGrabber->metaObject()->className() == metaObject()->className())
allowed = true;
} else if ((d->grabPermissions & CanTakeOverFromItems)) {
- QQuickItem * existingItemGrabber = point->grabberItem();
- if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && point->pointerEvent()->asPointerMouseEvent()) ||
- (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent()))) {
+ QQuickItem * existingItemGrabber = qobject_cast<QQuickItem *>(event->exclusiveGrabber(point));
+ if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && QQuickWindowPrivate::isMouseEvent(event)) ||
+ (existingItemGrabber->keepTouchGrab() && QQuickWindowPrivate::isTouchEvent(event)))) {
allowed = true;
// If the handler wants to steal the exclusive grab from an Item, the Item can usually veto
// by having its keepMouseGrab flag set. But an exception is if that Item is a parent that
@@ -361,8 +362,8 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
if (existingItemGrabber->keepMouseGrab() &&
!(existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem()))) {
QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(parentItem()->window());
- if (winPriv->isDeliveringTouchAsMouse() && point->pointId() == winPriv->touchMouseId) {
- qCDebug(lcPointerHandlerGrab) << this << "wants to grab touchpoint" << point->pointId()
+ if (winPriv->isDeliveringTouchAsMouse() && point.id() == winPriv->touchMouseId) {
+ qCDebug(lcPointerHandlerGrab) << this << "wants to grab touchpoint" << point.id()
<< "but declines to steal grab from touch-mouse grabber with keepMouseGrab=true" << existingItemGrabber;
allowed = false;
}
@@ -388,7 +389,7 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
allowed = true;
}
}
- qCDebug(lcPointerHandlerGrab) << "point" << Qt::hex << point->pointId() << "permission" <<
+ qCDebug(lcPointerHandlerGrab) << "point" << Qt::hex << point.id() << "permission" <<
QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) <<
':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber;
return allowed;
@@ -449,7 +450,7 @@ void QQuickPointerHandler::componentComplete()
{
}
-QQuickPointerEvent *QQuickPointerHandler::currentEvent()
+QPointerEvent *QQuickPointerHandler::currentEvent()
{
Q_D(const QQuickPointerHandler);
return d->currentEvent;
@@ -463,52 +464,60 @@ QQuickPointerEvent *QQuickPointerHandler::currentEvent()
specified. Returns false if permission is denied either by this handler or
by the handler or item from which this handler would take over
*/
-bool QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab)
+bool QQuickPointerHandler::setExclusiveGrab(QPointerEvent *ev, const QEventPoint &point, bool grab)
{
- if ((grab && point->exclusiveGrabber() == this) || (!grab && point->exclusiveGrabber() != this))
+ if ((grab && ev->exclusiveGrabber(point) == this) || (!grab && ev->exclusiveGrabber(point) != this))
return true;
// TODO m_hadKeepMouseGrab m_hadKeepTouchGrab
bool allowed = true;
if (grab) {
- allowed = canGrab(point);
+ allowed = canGrab(ev, point);
} else {
- QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler();
+ QQuickPointerHandler *existingPhGrabber = qobject_cast<QQuickPointerHandler *>(ev->exclusiveGrabber(point));
// Ask before allowing one handler to cancel another's grab
- if (existingPhGrabber && existingPhGrabber != this && !existingPhGrabber->approveGrabTransition(point, nullptr))
+ if (existingPhGrabber && existingPhGrabber != this && !existingPhGrabber->approveGrabTransition(ev, point, nullptr))
allowed = false;
}
qCDebug(lcPointerHandlerGrab) << point << (grab ? "grab" : "ungrab") << (allowed ? "allowed" : "forbidden") <<
- point->exclusiveGrabber() << "->" << (grab ? this : nullptr);
+ ev->exclusiveGrabber(point) << "->" << (grab ? this : nullptr);
if (allowed)
- point->setGrabberPointerHandler(grab ? this : nullptr, true);
+ ev->setExclusiveGrabber(point, grab ? this : nullptr);
return allowed;
}
/*!
Cancel any existing grab of the given \a point.
*/
-void QQuickPointerHandler::cancelAllGrabs(QQuickEventPoint *point)
+void QQuickPointerHandler::cancelAllGrabs(QPointerEvent *event, QEventPoint &point)
{
qCDebug(lcPointerHandlerGrab) << point;
- point->cancelAllGrabs(this);
+ if (event->exclusiveGrabber(point) == this) {
+ event->setExclusiveGrabber(point, nullptr);
+ onGrabChanged(this, QPointingDevice::CancelGrabExclusive, event, point);
+ }
+ if (event->removePassiveGrabber(point, this))
+ onGrabChanged(this, QPointingDevice::CancelGrabPassive, event, point);
}
-QPointF QQuickPointerHandler::eventPos(const QQuickEventPoint *point) const
+QPointF QQuickPointerHandler::eventPos(const QEventPoint &point) const
{
- return (target() ? target()->mapFromScene(point->scenePosition()) : point->scenePosition());
+ return (target() ? target()->mapFromScene(point.scenePosition()) : point.scenePosition());
}
-bool QQuickPointerHandler::parentContains(const QQuickEventPoint *point) const
+bool QQuickPointerHandler::parentContains(const QEventPoint &point) const
+{
+ return parentContains(point.scenePosition());
+}
+
+bool QQuickPointerHandler::parentContains(const QPointF &scenePosition) const
{
- if (!point)
- return false;
if (QQuickItem *par = parentItem()) {
if (par->window()) {
- QPoint screenPosition = par->window()->mapToGlobal(point->scenePosition().toPoint());
+ QPoint screenPosition = par->window()->mapToGlobal(scenePosition.toPoint());
if (!par->window()->geometry().contains(screenPosition))
return false;
}
- QPointF p = par->mapFromScene(point->scenePosition());
+ QPointF p = par->mapFromScene(scenePosition);
qreal m = margin();
if (m > 0)
return p.x() >= -m && p.y() >= -m && p.x() <= par->width() + m && p.y() <= par->height() + m;
@@ -582,7 +591,29 @@ QQuickItem *QQuickPointerHandler::target() const
return d->target;
}
-void QQuickPointerHandler::handlePointerEvent(QQuickPointerEvent *event)
+/*! \internal
+ Pointer Handlers do most of their work in implementations of virtual functions
+ that are called directly from QQuickItem, not by direct event handling.
+ But it's convenient to deliver TouchCancel events via QCoreApplication::sendEvent().
+ Perhaps it will turn out that more events could be delivered this way.
+*/
+bool QQuickPointerHandler::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::TouchCancel: {
+ auto te = static_cast<QTouchEvent *>(e);
+ for (int i = 0; i < te->pointCount(); ++i)
+ onGrabChanged(this, QPointingDevice::CancelGrabExclusive, te, te->point(i));
+ return true;
+ break;
+ }
+ default:
+ return QObject::event(e);
+ break;
+ }
+}
+
+void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event)
{
bool wants = wantsPointerEvent(event);
qCDebug(lcPointerHandlerDispatch) << metaObject()->className() << objectName()
@@ -592,27 +623,30 @@ void QQuickPointerHandler::handlePointerEvent(QQuickPointerEvent *event)
handlePointerEventImpl(event);
} else {
setActive(false);
- int pCount = event->pointCount();
- for (int i = 0; i < pCount; ++i) {
- QQuickEventPoint *pt = event->point(i);
- if (pt->grabberPointerHandler() == this && pt->state() != QQuickEventPoint::Stationary)
- pt->cancelExclusiveGrab();
+ for (int i = 0; i < event->pointCount(); ++i) {
+ auto &pt = event->point(i);
+ if (event->exclusiveGrabber(pt) == this && pt.state() != QEventPoint::Stationary) {
+ event->setExclusiveGrabber(pt, nullptr);
+ onGrabChanged(this, QPointingDevice::CancelGrabExclusive, event, pt);
+ }
}
}
QQuickPointerHandlerPrivate::deviceDeliveryTargets(event->device()).append(this);
}
-bool QQuickPointerHandler::wantsPointerEvent(QQuickPointerEvent *event)
+bool QQuickPointerHandler::wantsPointerEvent(QPointerEvent *event)
{
Q_D(const QQuickPointerHandler);
Q_UNUSED(event);
return d->enabled;
}
-bool QQuickPointerHandler::wantsEventPoint(QQuickEventPoint *point)
+bool QQuickPointerHandler::wantsEventPoint(const QPointerEvent *event, const QEventPoint &point)
{
- bool ret = point->exclusiveGrabber() == this || point->passiveGrabbers().contains(this) || parentContains(point);
- qCDebug(lcPointerHandlerDispatch) << Qt::hex << point->pointId() << "@" << point->scenePosition()
+ Q_UNUSED(event);
+ bool ret = event->exclusiveGrabber(point) == this ||
+ event->passiveGrabbers(point).contains(this) || parentContains(point);
+ qCDebug(lcPointerHandlerDispatch) << Qt::hex << point.id() << "@" << point.scenePosition()
<< metaObject()->className() << objectName() << ret;
return ret;
}
@@ -638,7 +672,7 @@ void QQuickPointerHandler::setActive(bool active)
}
}
-void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event)
+void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *event)
{
Q_D(QQuickPointerHandler);
d->currentEvent = event;
@@ -689,14 +723,14 @@ QQuickPointerHandlerPrivate::QQuickPointerHandlerPrivate()
}
template <typename TEventPoint>
-bool QQuickPointerHandlerPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p) const
+bool QQuickPointerHandlerPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint &p) const
{
Q_Q(const QQuickPointerHandler);
QStyleHints *styleHints = qApp->styleHints();
bool overThreshold = qAbs(d) > q->dragThreshold();
const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
if (!overThreshold && dragVelocityLimitAvailable) {
- qreal velocity = qreal(axis == Qt::XAxis ? p->velocity().x() : p->velocity().y());
+ qreal velocity = qreal(axis == Qt::XAxis ? p.velocity().x() : p.velocity().y());
overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
}
return overThreshold;
@@ -709,9 +743,9 @@ bool QQuickPointerHandlerPrivate::dragOverThreshold(QVector2D delta) const
return qAbs(delta.x()) > threshold || qAbs(delta.y()) > threshold;
}
-bool QQuickPointerHandlerPrivate::dragOverThreshold(const QQuickEventPoint *point) const
+bool QQuickPointerHandlerPrivate::dragOverThreshold(const QEventPoint &point) const
{
- QPointF delta = point->scenePosition() - point->scenePressPosition();
+ QPointF delta = point.scenePosition() - point.scenePressPosition();
return (dragOverThreshold(delta.x(), Qt::XAxis, point) ||
dragOverThreshold(delta.y(), Qt::YAxis, point));
}