diff options
Diffstat (limited to 'src/quick/handlers/qquickpointerhandler.cpp')
-rw-r--r-- | src/quick/handlers/qquickpointerhandler.cpp | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 11c29ee812..12b064a79b 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -302,7 +302,8 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QPointin */ void QQuickPointerHandler::setPassiveGrab(QPointerEvent *event, const QEventPoint &point, bool grab) { - qCDebug(lcPointerHandlerGrab) << point << grab; + qCDebug(lcPointerHandlerGrab) << this << point << grab << "via" + << QQuickDeliveryAgentPrivate::currentOrItemDeliveryAgent(parentItem()); if (grab) { event->addPassiveGrabber(point, this); } else { @@ -338,8 +339,8 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv { Q_D(const QQuickPointerHandler); bool allowed = false; + QObject* existingGrabber = event->exclusiveGrabber(point); if (proposedGrabber == this) { - QObject* existingGrabber = event->exclusiveGrabber(point); allowed = (existingGrabber == nullptr) || ((d->grabPermissions & CanTakeOverFromAnything) == CanTakeOverFromAnything); if (existingGrabber) { if (QQuickPointerHandler *existingPhGrabber = qobject_cast<QQuickPointerHandler *>(event->exclusiveGrabber(point))) { @@ -350,10 +351,17 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv existingPhGrabber->metaObject()->className() == metaObject()->className()) allowed = true; } else if ((d->grabPermissions & CanTakeOverFromItems)) { + allowed = true; QQuickItem * existingItemGrabber = qobject_cast<QQuickItem *>(event->exclusiveGrabber(point)); - if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && QQuickWindowPrivate::isMouseEvent(event)) || - (existingItemGrabber->keepTouchGrab() && QQuickWindowPrivate::isTouchEvent(event)))) { - allowed = true; + auto da = parentItem() ? QQuickItemPrivate::get(parentItem())->deliveryAgentPrivate() + : QQuickDeliveryAgentPrivate::currentEventDeliveryAgent ? static_cast<QQuickDeliveryAgentPrivate *>( + QQuickDeliveryAgentPrivate::get(QQuickDeliveryAgentPrivate::currentEventDeliveryAgent)) : nullptr; + const bool isTouchMouse = (da && da->isDeliveringTouchAsMouse()); + if (existingItemGrabber && + ((existingItemGrabber->keepMouseGrab() && + (QQuickWindowPrivate::isMouseEvent(event) || isTouchMouse)) || + (existingItemGrabber->keepTouchGrab() && QQuickWindowPrivate::isTouchEvent(event)))) { + allowed = false; // 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 // normally filters events (such as a Flickable): it needs to be possible for e.g. a @@ -362,15 +370,20 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv // at first and then expects to be able to steal the grab later on. It cannot respect // Flickable's wishes in that case, because then it would never have a chance. if (existingItemGrabber->keepMouseGrab() && - !(existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem()))) { - auto da = QQuickItemPrivate::get(parentItem())->deliveryAgentPrivate(); + existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem())) { Q_ASSERT(da); - if (da->isDeliveringTouchAsMouse() && point.id() == da->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; + if (isTouchMouse && point.id() == da->touchMouseId) { + qCDebug(lcPointerHandlerGrab) << this << "steals touchpoint" << point.id() + << "despite parent touch-mouse grabber with keepMouseGrab=true" << existingItemGrabber; + allowed = true; } } + if (!allowed) { + qCDebug(lcPointerHandlerGrab) << this << "wants to grab point" << point.id() + << "but declines to steal from grabber" << existingItemGrabber + << "with keepMouseGrab=" << existingItemGrabber->keepMouseGrab() + << "keepTouchGrab=" << existingItemGrabber->keepTouchGrab(); + } } } } @@ -394,7 +407,8 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv } qCDebug(lcPointerHandlerGrab) << "point" << Qt::hex << point.id() << "permission" << QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) << - ':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber; + ':' << this << (allowed ? "approved from" : "denied from") << + existingGrabber << "to" << proposedGrabber; return allowed; } @@ -516,8 +530,11 @@ bool QQuickPointerHandler::parentContains(const QPointF &scenePosition) const { if (QQuickItem *par = parentItem()) { if (par->window()) { + QRect windowGeometry = par->window()->geometry(); + if (!par->window()->isTopLevel()) + windowGeometry = QRect(QWindowPrivate::get(par->window())->globalPosition(), par->window()->size()); QPoint screenPosition = par->window()->mapToGlobal(scenePosition.toPoint()); - if (!par->window()->geometry().contains(screenPosition)) + if (!windowGeometry.contains(screenPosition)) return false; } QPointF p = par->mapFromScene(scenePosition); |