diff options
Diffstat (limited to 'tests/auto/quick/pointerhandlers')
8 files changed, 278 insertions, 2 deletions
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST index 20f989fc50..92903955ac 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST +++ b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST @@ -1,5 +1,6 @@ [touchAndDragHandlerOnFlickable] windows gcc +opensuse-leap [touchDragFlickableBehindSlider] windows gcc [touchDragFlickableBehindButton] diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml b/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml new file mode 100644 index 0000000000..48b1dc86f0 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 + + Rectangle { + width: 200 + height: 200 + color: mouseArea.pressed ? "red" : "blue" + opacity: 0.6 + + MouseArea { + id: mouseArea + anchors.fill: parent + } + } + Rectangle { + y: 100 + z: -1 + width: 200 + height: 200 + color: dragHandler.active ? "orange" : "green" + opacity: 0.6 + + DragHandler { + id: dragHandler + } + } +} diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/mousearea_interop.pro b/tests/auto/quick/pointerhandlers/mousearea_interop/mousearea_interop.pro new file mode 100644 index 0000000000..0bf0ec86a9 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/mousearea_interop.pro @@ -0,0 +1,15 @@ +CONFIG += testcase + +TARGET = tst_mousearea_interop +QT += core-private gui-private qml-private quick-private testlib + +macos:CONFIG -= app_bundle + +SOURCES += tst_mousearea_interop.cpp + +include (../../../shared/util.pri) +include (../../shared/util.pri) + +TESTDATA = data/* + +OTHER_FILES += data/dragTakeOverFromSibling.qml diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp new file mode 100644 index 0000000000..794562fea0 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlproperty.h> +#include <QtQuick/private/qquickdraghandler_p.h> +#include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> + +#include "../../../shared/util.h" +#include "../../shared/viewtestutil.h" + +Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") + +class tst_MouseAreaInterop : public QQmlDataTest +{ + Q_OBJECT +public: + tst_MouseAreaInterop() + : touchDevice(QTest::createTouchDevice()) + , touchPointerDevice(QQuickPointerDevice::touchDevice(touchDevice)) + {} + +private slots: + void dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse(); + void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data(); + void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch(); + +private: + void createView(QScopedPointer<QQuickView> &window, const char *fileName); + QTouchDevice *touchDevice; + QQuickPointerDevice *touchPointerDevice; +}; + +void tst_MouseAreaInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName) +{ + window.reset(new QQuickView); + window->setSource(testFileUrl(fileName)); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window.data()); + QQuickViewTestUtil::moveMouseAway(window.data()); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(window->rootObject() != nullptr); +} + +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse() +{ + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, "dragTakeOverFromSibling.qml"); + QQuickView * window = windowPtr.data(); + auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); + + QPointer<QQuickPointerHandler> handler = window->rootObject()->findChild<QQuickPointerHandler*>(); + QVERIFY(handler); + QQuickMouseArea *ma = window->rootObject()->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + + QPoint p1(150, 150); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); + QCOMPARE(window->mouseGrabberItem(), ma); + QCOMPARE(ma->pressed(), true); + + // Start dragging + // DragHandler keeps monitoring, due to its passive grab, + // and eventually steals the exclusive grab from MA + int dragStoleGrab = 0; + for (int i = 0; i < 4; ++i) { + p1 += QPoint(dragThreshold / 2, 0); + QTest::mouseMove(window, p1); + 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(ma->pressed(), false); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); + QCOMPARE(handler->active(), false); +} + +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data() +{ + QTest::addColumn<bool>("preventStealing"); + + QTest::newRow("allow stealing") << false; + QTest::newRow("prevent stealing") << true; +} + +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch() // QTBUG-77624 and QTBUG-79163 +{ + QFETCH(bool, preventStealing); + + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, "dragTakeOverFromSibling.qml"); + QQuickView * window = windowPtr.data(); + auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(touchPointerDevice); + + QPointer<QQuickPointerHandler> handler = window->rootObject()->findChild<QQuickPointerHandler*>(); + QVERIFY(handler); + QQuickMouseArea *ma = window->rootObject()->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + ma->setPreventStealing(preventStealing); + + QPoint p1(150, 150); + QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice); + + touch.press(1, p1).commit(); + QQuickTouchUtils::flush(window); + QTRY_VERIFY(pointerEvent->point(0)->passiveGrabbers().contains(handler)); + QCOMPARE(pointerEvent->point(0)->grabberItem(), ma); + QCOMPARE(window->mouseGrabberItem(), ma); + QCOMPARE(ma->pressed(), true); + + // Start dragging + // DragHandler keeps monitoring, due to its passive grab, + // and eventually steals the exclusive grab from MA if MA allows it + int dragStoleGrab = 0; + for (int i = 0; i < 4; ++i) { + p1 += QPoint(dragThreshold / 2, 0); + touch.move(1, p1).commit(); + QQuickTouchUtils::flush(window); + if (!dragStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == handler) + dragStoleGrab = i; + } + if (dragStoleGrab) + qCDebug(lcPointerTests, "DragHandler stole the grab after %d events", dragStoleGrab); + if (preventStealing) { + QCOMPARE(dragStoleGrab, 0); + QCOMPARE(handler->active(), false); + QCOMPARE(ma->pressed(), true); + } else { + QVERIFY(dragStoleGrab > 1); + QCOMPARE(handler->active(), true); + QCOMPARE(ma->pressed(), false); + } + + touch.release(1, p1).commit(); + QQuickTouchUtils::flush(window); + QCOMPARE(handler->active(), false); +} + +QTEST_MAIN(tst_MouseAreaInterop) + +#include "tst_mousearea_interop.moc" 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 35fed99e8b..4a7a132be2 100644 --- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp @@ -295,10 +295,10 @@ void tst_MptaInterop::unloadHandlerWithPassiveGrab() QVERIFY(mpta); QPoint point(90, 90); - QTest::mousePress(window, Qt::LeftButton, 0, point); + QTest::mousePress(window, Qt::LeftButton, {}, point); QCOMPARE(window->mouseGrabberItem(), mpta); QTRY_VERIFY(handler.isNull()); // it got unloaded - QTest::mouseRelease(window, Qt::LeftButton, 0, point); // QTBUG-73819: don't crash + QTest::mouseRelease(window, Qt::LeftButton, {}, point); // QTBUG-73819: don't crash } void tst_MptaInterop::dragHandlerInParentStealingGrabFromItem() // QTBUG-75025 diff --git a/tests/auto/quick/pointerhandlers/pointerhandlers.pro b/tests/auto/quick/pointerhandlers/pointerhandlers.pro index 4d6311bdb2..7db28b6583 100644 --- a/tests/auto/quick/pointerhandlers/pointerhandlers.pro +++ b/tests/auto/quick/pointerhandlers/pointerhandlers.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs qtConfig(private_tests) { SUBDIRS += \ flickableinterop \ + mousearea_interop \ multipointtoucharea_interop \ qquickdraghandler \ qquickhoverhandler \ diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml index 042b730799..800c25c77d 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml @@ -31,6 +31,7 @@ import QtQuick 2.12 Rectangle { id: root property alias label: label.text + property alias active: tap.active property alias pressed: tap.pressed property bool checked: false property alias gesturePolicy: tap.gesturePolicy diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp index e77ea97518..419afed3ac 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp @@ -600,10 +600,32 @@ void tst_TapHandler::buttonsMultiTouch() touchSeq.stationary(1).press(2, p2, window).commit(); QQuickTouchUtils::flush(window); QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("active").toBool()); QPoint p3 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint(); touchSeq.stationary(1).stationary(2).press(3, p3, window).commit(); QQuickTouchUtils::flush(window); QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool()); + QVERIFY(buttonReleaseWithinBounds->property("active").toBool()); + QVERIFY(buttonWithinBounds->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("active").toBool()); + QVERIFY(buttonDragThreshold->property("pressed").toBool()); + + // combinations of small touchpoint movements and stationary points should not cause state changes + p1 += QPoint(2, 0); + p2 += QPoint(3, 0); + touchSeq.move(1, p1).move(2, p2).stationary(3).commit(); + QVERIFY(buttonDragThreshold->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("active").toBool()); + QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool()); + QVERIFY(buttonReleaseWithinBounds->property("active").toBool()); + p3 += QPoint(4, 0); + touchSeq.stationary(1).stationary(2).move(3, p3).commit(); + QVERIFY(buttonDragThreshold->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("pressed").toBool()); + QVERIFY(buttonWithinBounds->property("active").toBool()); + QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool()); + QVERIFY(buttonReleaseWithinBounds->property("active").toBool()); // can release top button and press again: others stay pressed the whole time touchSeq.stationary(2).stationary(3).release(1, p1, window).commit(); |