diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index b6d3ebd7f2..f0eadc0daa 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1763,6 +1763,10 @@ void QQuickFlickable::mouseUngrabEvent() d->draggingEnding(); d->stealMouse = false; setKeepMouseGrab(false); + d->fixupX(); + d->fixupY(); + if (!d->timeline.isActive()) + movementEnding(); } } diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 1fa0a90b28..b85a449c51 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1422,6 +1422,9 @@ void QQuickPathView::mouseUngrabEvent() d->stealMouse = false; setKeepMouseGrab(false); d->lastPosTime.invalidate(); + d->fixOffset(); + if (!d->tl.isActive()) + movementEnding(); } } diff --git a/tests/auto/quick/qquickflickable/data/cancel.qml b/tests/auto/quick/qquickflickable/data/cancel.qml new file mode 100644 index 0000000000..d1c3fddbf2 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/cancel.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Flickable { + width: 200; height: 200 + contentWidth: row.width; contentHeight: row.height + + Row { + id: row + objectName: "row" + Repeater { + model: 4 + Rectangle { width: 400; height: 600; color: "yellow"; border.width: 1 } + } + } +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 4b157a434b..9f5bd46864 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -77,6 +77,7 @@ private slots: void disabled(); void flickVelocity(); void margins(); + void cancel(); private: QQmlEngine engine; @@ -657,6 +658,41 @@ void tst_qquickflickable::margins() delete root; } +void tst_qquickflickable::cancel() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(testFileUrl("cancel.qml")); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10, 10)); + // drag out of bounds + QTest::mouseMove(canvas, QPoint(50, 50)); + QTest::mouseMove(canvas, QPoint(100, 100)); + QTest::mouseMove(canvas, QPoint(150, 150)); + + QVERIFY(flickable->contentX() != 0); + QVERIFY(flickable->contentY() != 0); + QVERIFY(flickable->isMoving()); + QVERIFY(flickable->isDragging()); + + // grabbing mouse will cancel flickable interaction. + QQuickItem *item = canvas->rootObject()->findChild("row"); + item->grabMouse(); + + QTRY_COMPARE(flickable->contentX(), 0.); + QTRY_COMPARE(flickable->contentY(), 0.); + QTRY_VERIFY(!flickable->isMoving()); + QTRY_VERIFY(!flickable->isDragging()); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10)); +} + + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" diff --git a/tests/auto/quick/qquickpathview/data/dragpath.qml b/tests/auto/quick/qquickpathview/data/dragpath.qml index f9c6615b04..6ba778bb80 100644 --- a/tests/auto/quick/qquickpathview/data/dragpath.qml +++ b/tests/auto/quick/qquickpathview/data/dragpath.qml @@ -14,6 +14,7 @@ PathView { preferredHighlightBegin: 0.5 preferredHighlightEnd: 0.5 Text { + objectName: "text" text: "current index: " + parent.currentIndex } } diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 8866cafd80..613156b2f5 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -123,6 +123,7 @@ private slots: void creationContext(); void currentOffsetOnInsertion(); void asynchronous(); + void cancelDrag(); }; class TestObject : public QObject @@ -1453,6 +1454,41 @@ void tst_QQuickPathView::missingPercent() delete obj; } +void tst_QQuickPathView::cancelDrag() +{ + QQuickView *canvas = createView(); + canvas->setSource(testFileUrl("dragpath.qml")); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(canvas, qGuiApp->focusWindow()); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + + // drag between snap points + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100)); + QTest::qWait(100); + QTest::mouseMove(canvas, QPoint(30, 100)); + QTest::mouseMove(canvas, QPoint(85, 100)); + + QTRY_VERIFY(pathview->offset() != qFloor(pathview->offset())); + QTRY_VERIFY(pathview->isMoving()); + + // steal mouse grab - cancels PathView dragging + QQuickItem *item = canvas->rootObject()->findChild("text"); + item->grabMouse(); + + // returns to a snap point. + QTRY_VERIFY(pathview->offset() == qFloor(pathview->offset())); + QTRY_VERIFY(!pathview->isMoving()); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100)); + + delete canvas; +} + + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc"