diff options
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 16 | ||||
-rw-r--r-- | tests/auto/quick/qquickflickable/data/nestedPressDelay.qml | 42 | ||||
-rw-r--r-- | tests/auto/quick/qquickflickable/tst_qquickflickable.cpp | 29 |
3 files changed, 69 insertions, 18 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index a0bd1fab8e..105989c7f1 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -2007,6 +2007,22 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event) switch (mouseEvent->type()) { case QEvent::MouseMove: + if (d->delayedPressEvent) { + // A move beyond the threshold replays the press to give nested Flickables + // the opportunity to grab the gesture. + QPointF delta = event->localPos() - d->delayedPressEvent->localPos(); + if (QQuickWindowPrivate::dragOverThreshold(qAbs(delta.x()), Qt::XAxis, event) + || QQuickWindowPrivate::dragOverThreshold(qAbs(delta.y()), Qt::YAxis, event)) { + // We replay the mouse press but the grabber we had might not be interested in the event (e.g. overlay) + // so we reset the grabber + if (c->mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + // Use the event handler that will take care of finding the proper item to propagate the event + QQuickWindowPrivate::get(window())->deliverMouseEvent(d->delayedPressEvent); + d->clearDelayedPress(); + // continue on to handle mouse move event + } + } d->handleMouseMoveEvent(mouseEvent.data()); break; case QEvent::MouseButtonPress: diff --git a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml index 60dadcc73c..557b7c4117 100644 --- a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml +++ b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml @@ -8,24 +8,30 @@ Flickable { contentHeight: 320 flickableDirection: Flickable.HorizontalFlick pressDelay: 50 - Flickable { - objectName: "innerFlickable" - flickableDirection: Flickable.VerticalFlick - width: 480 - height: 320 - contentWidth: 480 - contentHeight: 400 - pressDelay: 10000 - Rectangle { - y: 100 - anchors.horizontalCenter: parent.horizontalCenter - width: 240 - height: 100 - color: ma.pressed ? 'blue' : 'green' - MouseArea { - id: ma - objectName: "mouseArea" - anchors.fill: parent + Rectangle { + x: 20 + y: 20 + width: 400 + height: 300 + color: "yellow" + Flickable { + objectName: "innerFlickable" + anchors.fill: parent + flickableDirection: Flickable.HorizontalFlick + contentWidth: 1480 + contentHeight: 400 + pressDelay: 10000 + Rectangle { + y: 100 + x: 80 + width: 240 + height: 100 + color: ma.pressed ? 'blue' : 'green' + MouseArea { + id: ma + objectName: "mouseArea" + anchors.fill: parent + } } } } diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 703e2918e6..ceed276305 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -388,6 +388,35 @@ void tst_qquickflickable::nestedPressDelay() QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(150, 150)); + // Dragging inner Flickable should work + QTest::mousePress(window, Qt::LeftButton, 0, QPoint(80, 150)); + // the MouseArea is not pressed immediately + QVERIFY(outer->property("pressed").toBool() == false); + + QTest::mouseMove(window, QPoint(60, 150)); + QTest::mouseMove(window, QPoint(40, 150)); + QTest::mouseMove(window, QPoint(20, 150)); + + QVERIFY(outer->property("moving").toBool() == false); + QVERIFY(inner->property("moving").toBool() == true); + + QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(20, 150)); + + // Dragging the MouseArea in the inner Flickable should move the inner Flickable + QTest::mousePress(window, Qt::LeftButton, 0, QPoint(150, 150)); + // the MouseArea is not pressed immediately + QVERIFY(outer->property("pressed").toBool() == false); + + QTest::mouseMove(window, QPoint(130, 150)); + QTest::mouseMove(window, QPoint(110, 150)); + QTest::mouseMove(window, QPoint(90, 150)); + + + QVERIFY(outer->property("moving").toBool() == false); + QVERIFY(inner->property("moving").toBool() == true); + + QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(90, 150)); + delete window; } |