diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-05-08 10:20:33 +0200 |
---|---|---|
committer | Antti Kokko <antti.kokko@qt.io> | 2017-05-08 10:43:32 +0000 |
commit | 9f80a466772c7e61bf7013e5c2e1726ca7c85b50 (patch) | |
tree | 12b501c1b3d4b0910cee9ffdfe2c658cbf7d55ac /src/quicktemplates2/qquickoverlay.cpp | |
parent | beb250bb5dc5ab14f64618a097b09257b6eb3041 (diff) |
Fix drawers not to be touch-draggable through modal popup shadows
Material style popups have a shadow outside the popup. QQuickOverlay
cannot block press events to children of a popup, because otherwise
interacting with popup contents would be impossible. However, since
the shadow is outside of the popup, touch events don't propagate to
the popup and get naturally blocked by the popup background. Instead,
the touch event propagates to the overlay. At this point, we must do
an additional check whether we're allowed to start dragging a drawer.
Task-number: QTBUG-60602
Change-Id: I9b5c81246bca7ea40bce0e46dc2e94558a0b9204
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickoverlay.cpp')
-rw-r--r-- | src/quicktemplates2/qquickoverlay.cpp | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index 0f7edc77..15104808 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -181,11 +181,23 @@ QQuickOverlayPrivate::QQuickOverlayPrivate() { } -bool QQuickOverlayPrivate::startDrag(QEvent *event) +bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos) { + Q_Q(QQuickOverlay); if (allDrawers.isEmpty()) return false; + // don't start dragging a drawer if a modal popup overlay is blocking (QTBUG-60602) + QQuickItem *item = q->childAt(pos.x(), pos.y()); + if (item) { + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup); + if (p->dimmer == item && popup->isVisible() && popup->isModal()) + return false; + } + } + const QVector<QQuickDrawer *> drawers = stackingOrderDrawers(); for (QQuickDrawer *drawer : drawers) { QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer); @@ -251,7 +263,7 @@ bool QQuickOverlayPrivate::handleMouseEvent(QQuickItem *source, QMouseEvent *eve { switch (event->type()) { case QEvent::MouseButtonPress: - if (!target && startDrag(event)) + if (!target && startDrag(event, event->windowPos())) return true; return handlePress(source, event, target); case QEvent::MouseMove: @@ -269,17 +281,12 @@ bool QQuickOverlayPrivate::handleTouchEvent(QQuickItem *source, QTouchEvent *eve bool handled = false; switch (event->type()) { case QEvent::TouchBegin: - if (!target && startDrag(event)) - handled = true; - else - handled = handlePress(source, event, target); - break; - case QEvent::TouchUpdate: + case QEvent::TouchEnd: for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { switch (point.state()) { case Qt::TouchPointPressed: - if (!target && startDrag(event)) + if (!target && startDrag(event, point.scenePos())) handled = true; else handled |= handlePress(source, event, target); @@ -296,10 +303,6 @@ bool QQuickOverlayPrivate::handleTouchEvent(QQuickItem *source, QTouchEvent *eve } break; - case QEvent::TouchEnd: - handled = handleRelease(source, event, target ? target : mouseGrabberPopup.data()); - break; - default: break; } |