diff options
Diffstat (limited to 'tests/auto/quick/pointerhandlers')
5 files changed, 158 insertions, 27 deletions
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml new file mode 100644 index 0000000000..dc7e5f6411 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +Item { + width: 640 + height: 480 + property alias touchpointPressed: tp1.pressed + + Rectangle { + color: tp1.pressed ? "lightsteelblue" : drag.active ? "tomato" : "wheat" + width: 180 + height: 180 + + DragHandler { id: drag } + + MultiPointTouchArea { + anchors.fill: parent + touchPoints: [ + TouchPoint { id: tp1 } + ] + } + } +} diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp index 58bc3d40b5..35fed99e8b 100644 --- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp @@ -56,6 +56,7 @@ private slots: void touchDrag(); void touchesThenPinch(); void unloadHandlerWithPassiveGrab(); + void dragHandlerInParentStealingGrabFromItem(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); @@ -300,6 +301,48 @@ void tst_MptaInterop::unloadHandlerWithPassiveGrab() QTest::mouseRelease(window, Qt::LeftButton, 0, point); // QTBUG-73819: don't crash } +void tst_MptaInterop::dragHandlerInParentStealingGrabFromItem() // QTBUG-75025 +{ + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, "dragParentOfMPTA.qml"); + QQuickView * window = windowPtr.data(); + auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); + + QPointer<QQuickPointerHandler> handler = window->rootObject()->findChild<QQuickPointerHandler*>(); + QVERIFY(handler); + QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(); + QVERIFY(mpta); + + // In QTBUG-75025 there is a QQ Controls Button; the MPTA here stands in for that, + // simply as an Item that grabs the mouse. The bug has nothing to do with MPTA specifically. + + QPoint point(20, 20); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, point); + QCOMPARE(window->mouseGrabberItem(), mpta); + QCOMPARE(window->rootObject()->property("touchpointPressed").toBool(), true); + + // Start dragging + // DragHandler keeps monitoring, due to its passive grab, + // and eventually steals the exclusive grab from MPTA + int dragStoleGrab = 0; + for (int i = 0; i < 4; ++i) { + point += QPoint(dragThreshold / 2, 0); + QTest::mouseMove(window, point); + if (!dragStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == handler) + dragStoleGrab = i; + } + if (dragStoleGrab) + qCDebug(lcPointerTests, "DragHandler stole the grab after %d events", dragStoleGrab); + QVERIFY(dragStoleGrab > 1); + QCOMPARE(handler->active(), true); + QCOMPARE(window->rootObject()->property("touchpointPressed").toBool(), false); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, point); + QCOMPARE(handler->active(), false); + QCOMPARE(window->rootObject()->property("touchpointPressed").toBool(), false); +} + QTEST_MAIN(tst_MptaInterop) #include "tst_multipointtoucharea_interop.moc" diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp index 7636bb38f1..66314f88a2 100644 --- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp @@ -54,6 +54,7 @@ private slots: void defaultPropertyValues(); void touchDrag(); + void mouseDrag_data(); void mouseDrag(); void dragFromMargin(); void snapMode_data(); @@ -195,8 +196,22 @@ void tst_DragHandler::touchDrag() QCOMPARE(centroidChangedSpy.count(), 5); } +void tst_DragHandler::mouseDrag_data() +{ + QTest::addColumn<Qt::MouseButtons>("acceptedButtons"); + QTest::addColumn<Qt::MouseButtons>("dragButton"); + QTest::newRow("left: drag") << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons(Qt::LeftButton); + QTest::newRow("right: don't drag") << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons(Qt::RightButton); + QTest::newRow("left: don't drag") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::MouseButtons(Qt::LeftButton); + QTest::newRow("right or middle: drag") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::MouseButtons(Qt::MiddleButton); +} + void tst_DragHandler::mouseDrag() { + QFETCH(Qt::MouseButtons, acceptedButtons); + QFETCH(Qt::MouseButtons, dragButton); + bool shouldDrag = bool(acceptedButtons & dragButton); + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); QScopedPointer<QQuickView> windowPtr; createView(windowPtr, "draggables.qml"); @@ -206,6 +221,7 @@ void tst_DragHandler::mouseDrag() QVERIFY(ball); QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>(); QVERIFY(dragHandler); + dragHandler->setAcceptedButtons(acceptedButtons); // QTBUG-76875 QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged())); QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged())); @@ -213,45 +229,57 @@ void tst_DragHandler::mouseDrag() QPointF ballCenter = ball->clipRect().center(); QPointF scenePressPos = ball->mapToScene(ballCenter); QPoint p1 = scenePressPos.toPoint(); - QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); + QTest::mousePress(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1); QVERIFY(!dragHandler->active()); - QCOMPARE(dragHandler->centroid().position(), ballCenter); - QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); - QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos); - QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); - QCOMPARE(dragHandler->centroid().velocity(), QVector2D()); - QCOMPARE(centroidChangedSpy.count(), 1); + if (shouldDrag) { + QCOMPARE(dragHandler->centroid().position(), ballCenter); + QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); + QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos); + QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); + QCOMPARE(dragHandler->centroid().velocity(), QVector2D()); + QCOMPARE(centroidChangedSpy.count(), 1); + } p1 += QPoint(dragThreshold, 0); QTest::mouseMove(window, p1); - QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0); - QCOMPARE(centroidChangedSpy.count(), 2); - QVERIFY(!dragHandler->active()); + if (shouldDrag) { + QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0); + QCOMPARE(centroidChangedSpy.count(), 2); + QVERIFY(!dragHandler->active()); + } p1 += QPoint(1, 0); QTest::mouseMove(window, p1); - QTRY_VERIFY(dragHandler->active()); + if (shouldDrag) + QTRY_VERIFY(dragHandler->active()); + else + QVERIFY(!dragHandler->active()); QCOMPARE(translationChangedSpy.count(), 0); - QCOMPARE(centroidChangedSpy.count(), 3); + if (shouldDrag) + QCOMPARE(centroidChangedSpy.count(), 3); QCOMPARE(dragHandler->translation().x(), 0.0); QPointF sceneGrabPos = p1; - QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); + if (shouldDrag) + QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); p1 += QPoint(19, 0); QTest::mouseMove(window, p1); - QTRY_VERIFY(dragHandler->active()); - QCOMPARE(dragHandler->centroid().position(), ballCenter); - QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); - QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter)); - QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); - QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); - QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0); - QCOMPARE(dragHandler->translation().y(), 0.0); - QVERIFY(dragHandler->centroid().velocity().x() > 0); - QCOMPARE(centroidChangedSpy.count(), 4); - QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); + QVERIFY(shouldDrag ? dragHandler->active() : !dragHandler->active()); + if (shouldDrag) { + QCOMPARE(dragHandler->centroid().position(), ballCenter); + QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); + QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter)); + QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); + QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); + QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0); + QCOMPARE(dragHandler->translation().y(), 0.0); + QVERIFY(dragHandler->centroid().velocity().x() > 0); + QCOMPARE(centroidChangedSpy.count(), 4); + } + QTest::mouseRelease(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1); QTRY_VERIFY(!dragHandler->active()); QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton); - QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1); - QCOMPARE(translationChangedSpy.count(), 1); - QCOMPARE(centroidChangedSpy.count(), 5); + if (shouldDrag) + QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1); + QCOMPARE(translationChangedSpy.count(), shouldDrag ? 1 : 0); + QCOMPARE(centroidChangedSpy.count(), shouldDrag ? 5 : 0); } void tst_DragHandler::dragFromMargin() // QTBUG-74966 diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml index 221e7df139..042b730799 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml @@ -34,6 +34,7 @@ Rectangle { property alias pressed: tap.pressed property bool checked: false property alias gesturePolicy: tap.gesturePolicy + property point tappedPosition: Qt.point(0, 0) signal tapped signal canceled @@ -51,6 +52,7 @@ Rectangle { longPressThreshold: 100 // CI can be insanely slow, so don't demand a timely release to generate onTapped onTapped: { tapFlash.start() + root.tappedPosition = point.scenePosition root.tapped() } onCanceled: root.canceled() diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp index 33cea69147..e77ea97518 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp @@ -107,6 +107,8 @@ void tst_TapHandler::touchGesturePolicyDragThreshold() QQuickItem *buttonDragThreshold = window->rootObject()->findChild<QQuickItem*>("DragThreshold"); QVERIFY(buttonDragThreshold); + QQuickTapHandler *tapHandler = buttonDragThreshold->findChild<QQuickTapHandler*>(); + QVERIFY(tapHandler); QSignalSpy dragThresholdTappedSpy(buttonDragThreshold, SIGNAL(tapped())); // DragThreshold button stays pressed while touchpoint stays within dragThreshold, emits tapped on release @@ -122,6 +124,8 @@ void tst_TapHandler::touchGesturePolicyDragThreshold() QQuickTouchUtils::flush(window); QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool()); QCOMPARE(dragThresholdTappedSpy.count(), 1); + QCOMPARE(buttonDragThreshold->property("tappedPosition").toPoint(), p1); + QCOMPARE(tapHandler->point().position(), QPointF()); // DragThreshold button is no longer pressed if touchpoint goes beyond dragThreshold dragThresholdTappedSpy.clear(); @@ -152,6 +156,8 @@ void tst_TapHandler::mouseGesturePolicyDragThreshold() QQuickItem *buttonDragThreshold = window->rootObject()->findChild<QQuickItem*>("DragThreshold"); QVERIFY(buttonDragThreshold); + QQuickTapHandler *tapHandler = buttonDragThreshold->findChild<QQuickTapHandler*>(); + QVERIFY(tapHandler); QSignalSpy dragThresholdTappedSpy(buttonDragThreshold, SIGNAL(tapped())); // DragThreshold button stays pressed while mouse stays within dragThreshold, emits tapped on release @@ -164,6 +170,8 @@ void tst_TapHandler::mouseGesturePolicyDragThreshold() QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool()); QTRY_COMPARE(dragThresholdTappedSpy.count(), 1); + QCOMPARE(buttonDragThreshold->property("tappedPosition").toPoint(), p1); + QCOMPARE(tapHandler->point().position(), QPointF()); // DragThreshold button is no longer pressed if mouse goes beyond dragThreshold dragThresholdTappedSpy.clear(); |