diff options
Diffstat (limited to 'tests/auto/quick/touchmouse')
-rw-r--r-- | tests/auto/quick/touchmouse/BLACKLIST | 4 | ||||
-rw-r--r-- | tests/auto/quick/touchmouse/CMakeLists.txt | 24 | ||||
-rw-r--r-- | tests/auto/quick/touchmouse/data/oneMouseArea.qml | 14 | ||||
-rw-r--r-- | tests/auto/quick/touchmouse/tst_touchmouse.cpp | 243 |
4 files changed, 210 insertions, 75 deletions
diff --git a/tests/auto/quick/touchmouse/BLACKLIST b/tests/auto/quick/touchmouse/BLACKLIST index 9afc86c2fe..aaf5b8e95d 100644 --- a/tests/auto/quick/touchmouse/BLACKLIST +++ b/tests/auto/quick/touchmouse/BLACKLIST @@ -8,3 +8,7 @@ windows gcc developer-build # QTBUG-74517 [touchButtonOnFlickable] windows gcc developer-build + +# QTBUG-118059 +[tapOnDismissiveTopMouseAreaClicksBottomOne] +opensuse-leap diff --git a/tests/auto/quick/touchmouse/CMakeLists.txt b/tests/auto/quick/touchmouse/CMakeLists.txt index 703f4f7578..bca541bbfb 100644 --- a/tests/auto/quick/touchmouse/CMakeLists.txt +++ b/tests/auto/quick/touchmouse/CMakeLists.txt @@ -1,9 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + # Generated from touchmouse.pro. ##################################################################### ## tst_touchmouse Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_touchmouse LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + # Collect test data file(GLOB_RECURSE test_data_glob RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} @@ -12,21 +21,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_touchmouse SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_touchmouse.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -35,10 +37,10 @@ qt_internal_add_test(tst_touchmouse qt_internal_extend_target(tst_touchmouse CONDITION ANDROID OR IOS DEFINES - QT_QMLTEST_DATADIR=\\\":/data\\\" + QT_QMLTEST_DATADIR=":/data" ) qt_internal_extend_target(tst_touchmouse CONDITION NOT ANDROID AND NOT IOS DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" + QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data" ) diff --git a/tests/auto/quick/touchmouse/data/oneMouseArea.qml b/tests/auto/quick/touchmouse/data/oneMouseArea.qml new file mode 100644 index 0000000000..dccc5792c8 --- /dev/null +++ b/tests/auto/quick/touchmouse/data/oneMouseArea.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + width: 320; height: 240 + + Rectangle { + width: parent.width / 2; height: parent.height; x: width + color: ma.containsPress ? "steelblue" : "lightsteelblue" + MouseArea { + id: ma + anchors.fill: parent + } + } +} diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index ef0df0cddb..501d996797 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QtTest> @@ -46,8 +21,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -79,7 +54,7 @@ QDebug operator<<(QDebug dbg, const struct Event &event) { if (event.points.isEmpty()) dbg << " @ " << event.mousePos << " global " << event.mousePosGlobal; else - dbg << ", " << event.points.count() << " touchpoints: " << event.points; + dbg << ", " << event.points.size() << " touchpoints: " << event.points; dbg << ')'; return dbg; } @@ -150,6 +125,12 @@ public: ++touchUngrabCount; } + void dumpEventList() + { + for (const auto &event : eventList) + qDebug() << event; + } + bool event(QEvent *event) override { return QQuickItem::event(event); } @@ -185,12 +166,22 @@ class GrabMonitor : public QObject { public: QObject *exclusiveGrabber = nullptr; + int transitionCount = 0; bool fromMouseEvent = false; bool canceled = false; + void reset() + { + exclusiveGrabber = nullptr; + transitionCount = 0; + fromMouseEvent = false; + canceled = false; + } + void onGrabChanged(QObject *grabber, QPointingDevice::GrabTransition transition, const QPointerEvent *event, const QEventPoint &point) { qCDebug(lcTests) << grabber << transition << event << point << point.device(); + ++transitionCount; switch (transition) { case QPointingDevice::GrabTransition::GrabExclusive: exclusiveGrabber = grabber; @@ -217,6 +208,7 @@ class tst_TouchMouse : public QQmlDataTest Q_OBJECT public: tst_TouchMouse() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -246,6 +238,11 @@ private slots: void hoverEnabled(); void implicitUngrab(); + void touchCancelWillCancelMousePress(); + + void oneTouchInsideAndOneOutside(); + + void strayTouchDoesntAutograb(); protected: bool eventFilter(QObject *, QEvent *event) override @@ -429,7 +426,7 @@ void tst_TouchMouse::testEventFilter() // QScopedPointer<QQuickView> window(createView()); // window.setSource(testFileUrl("singleitem.qml")); // window.show(); -// QQuickViewTestUtil::centerOnScreen(&window); +// QQuickVisualTestUtils::centerOnScreen(&window); // QVERIFY(QTest::qWaitForWindowActive(&window)); // QVERIFY(window->rootObject() != 0); @@ -716,7 +713,7 @@ void tst_TouchMouse::touchButtonOnFlickable() QTRY_COMPARE(eventItem2->touchUngrabCount, 1); qCDebug(lcTests) << "expected delivered events: press(touch) move(touch)" << eventItem2->eventList; - QCOMPARE(eventItem2->eventList.size(), 2); + QCOMPARE(eventItem2->eventList.size(), 3); QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate); QCOMPARE(grabMonitor.exclusiveGrabber, flickable); // both EventItem and Flickable handled the actual touch, so synth-mouse doesn't happen @@ -799,7 +796,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() qCDebug(lcTests) << "expected filtered events: actual TouchBegin and replayed TouchBegin" << filteredEventList; QTRY_COMPARE(eventItem1->eventList.size(), 1); QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress); - QCOMPARE(filteredEventList.count(), 2); // actual touch begin and replayed touch begin + QCOMPARE(filteredEventList.size(), 2); // actual touch begin and replayed touch begin } if (!releaseBeforeDelayIsOver) { @@ -814,7 +811,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() if (scrollBeforeDelayIsOver) { QCOMPARE(eventItem1->eventList.size(), 0); qCDebug(lcTests) << "expected filtered events: 1 TouchBegin and 3 TouchUpdate" << filteredEventList; - QCOMPARE(filteredEventList.count(), 4); + QCOMPARE(filteredEventList.size(), 4); } else { qCDebug(lcTests) << "expected delivered events: press(mouse), move(mouse), move(mouse), ungrab(mouse)" << eventItem1->eventList; QCOMPARE(eventItem1->eventList.size(), 4); @@ -822,7 +819,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseMove); QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse); qCDebug(lcTests) << "expected filtered events: 2 TouchBegin and 3 TouchUpdate" << filteredEventList; - QCOMPARE(filteredEventList.count(), 5); + QCOMPARE(filteredEventList.size(), 5); } // flickable should have the touchpoint grab: it no longer relies on synth-mouse @@ -843,17 +840,17 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonRelease); QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse); // QQuickWindow filters the delayed press and release - QCOMPARE(filteredEventList.count(), 4); - QCOMPARE(filteredEventList.at(filteredEventList.count() - 2).type, QEvent::TouchBegin); + QCOMPARE(filteredEventList.size(), 4); + QCOMPARE(filteredEventList.at(filteredEventList.size() - 2).type, QEvent::TouchBegin); QCOMPARE(filteredEventList.last().type, QEvent::TouchEnd); } else { // QQuickWindow filters the delayed press if there was one if (scrollBeforeDelayIsOver) { qCDebug(lcTests) << "expected filtered events: 1 TouchBegin, 3 TouchUpdate, 1 TouchEnd" << filteredEventList; - QCOMPARE(filteredEventList.count(), 5); + QCOMPARE(filteredEventList.size(), 5); } else { qCDebug(lcTests) << "expected filtered events: 2 TouchBegin, 3 TouchUpdate, 1 TouchEnd" << filteredEventList; - QCOMPARE(filteredEventList.count(), 6); + QCOMPARE(filteredEventList.size(), 6); QCOMPARE(filteredEventList.at(0).type, QEvent::TouchBegin); QCOMPARE(filteredEventList.last().type, QEvent::TouchEnd); } @@ -968,7 +965,7 @@ void tst_TouchMouse::buttonOnTouch() touchSeq.press(0, p1, &window).press(1, p2, &window).commit(); QQuickTouchUtils::flush(&window); QCOMPARE(button1->scale(), 1); - QCOMPARE(eventItem1->eventList.count(), 1); + QCOMPARE(eventItem1->eventList.size(), 1); QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress); p1 -= QPoint(10, 0); @@ -1280,16 +1277,16 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne() QTest::touchEvent(&window, device).release(0, p1, &window); QQuickTouchUtils::flush(&window); - QCOMPARE(bottomClickedSpy.count(), 1); - QCOMPARE(bottomDoubleClickedSpy.count(), 0); + QCOMPARE(bottomClickedSpy.size(), 1); + QCOMPARE(bottomDoubleClickedSpy.size(), 0); QTest::touchEvent(&window, device).press(0, p1, &window); QQuickTouchUtils::flush(&window); QTest::touchEvent(&window, device).release(0, p1, &window); QQuickTouchUtils::flush(&window); - QCOMPARE(bottomClickedSpy.count(), 1); - QCOMPARE(bottomDoubleClickedSpy.count(), 1); + QCOMPARE(bottomClickedSpy.size(), 1); + QCOMPARE(bottomDoubleClickedSpy.size(), 1); } /* @@ -1443,6 +1440,7 @@ void tst_TouchMouse::hoverEnabled() // QTBUG-40856 QQuickView window; QVERIFY(QQuickTest::showView(window, testFileUrl("hoverMouseAreas.qml"))); QQuickItem *root = window.rootObject(); + auto deliveryAgent = QQuickWindowPrivate::get(&window)->deliveryAgentPrivate(); QQuickMouseArea *mouseArea1 = root->findChild<QQuickMouseArea*>("mouseArea1"); QVERIFY(mouseArea1 != nullptr); @@ -1452,11 +1450,11 @@ void tst_TouchMouse::hoverEnabled() // QTBUG-40856 QSignalSpy enterSpy1(mouseArea1, SIGNAL(entered())); QSignalSpy exitSpy1(mouseArea1, SIGNAL(exited())); - QSignalSpy clickSpy1(mouseArea1, SIGNAL(clicked(QQuickMouseEvent *))); + QSignalSpy clickSpy1(mouseArea1, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy enterSpy2(mouseArea2, SIGNAL(entered())); QSignalSpy exitSpy2(mouseArea2, SIGNAL(exited())); - QSignalSpy clickSpy2(mouseArea2, SIGNAL(clicked(QQuickMouseEvent *))); + QSignalSpy clickSpy2(mouseArea2, SIGNAL(clicked(QQuickMouseEvent*))); QPoint p1(150, 150); QPoint p2(150, 250); @@ -1464,54 +1462,60 @@ void tst_TouchMouse::hoverEnabled() // QTBUG-40856 // ------------------------- Mouse move to mouseArea1 QTest::mouseMove(&window, p1); - QVERIFY(enterSpy1.count() == 1); + QVERIFY(enterSpy1.size() == 1); QVERIFY(mouseArea1->hovered()); QVERIFY(!mouseArea2->hovered()); // ------------------------- Touch click on mouseArea1 QTest::touchEvent(&window, device).press(0, p1, &window); + deliveryAgent->flushFrameSynchronousEvents(&window); - QCOMPARE(enterSpy1.count(), 1); - QCOMPARE(enterSpy2.count(), 0); - QVERIFY(mouseArea1->pressed()); + QCOMPARE(enterSpy1.size(), 1); + QCOMPARE(enterSpy2.size(), 0); + QVERIFY(mouseArea1->isPressed()); QVERIFY(mouseArea1->hovered()); QVERIFY(!mouseArea2->hovered()); QTest::touchEvent(&window, device).release(0, p1, &window); - QVERIFY(clickSpy1.count() == 1); + deliveryAgent->flushFrameSynchronousEvents(&window); + QVERIFY(clickSpy1.size() == 1); QVERIFY(mouseArea1->hovered()); QVERIFY(!mouseArea2->hovered()); // ------------------------- Touch click on mouseArea2 QTest::touchEvent(&window, device).press(0, p2, &window); + deliveryAgent->flushFrameSynchronousEvents(&window); - QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea1->hovered()); QVERIFY(mouseArea2->hovered()); - QVERIFY(mouseArea2->pressed()); - QCOMPARE(enterSpy1.count(), 1); - QCOMPARE(enterSpy2.count(), 1); + QVERIFY(mouseArea2->isPressed()); + QCOMPARE(enterSpy1.size(), 1); + QCOMPARE(enterSpy2.size(), 1); QTest::touchEvent(&window, device).release(0, p2, &window); + deliveryAgent->flushFrameSynchronousEvents(&window); - QVERIFY(clickSpy2.count() == 1); - QVERIFY(mouseArea1->hovered()); + QVERIFY(clickSpy2.size() == 1); + QVERIFY(!mouseArea1->hovered()); QVERIFY(!mouseArea2->hovered()); - QCOMPARE(exitSpy1.count(), 0); - QCOMPARE(exitSpy2.count(), 1); + QCOMPARE(exitSpy1.size(), 1); + QCOMPARE(exitSpy2.size(), 1); // ------------------------- Another touch click on mouseArea1 QTest::touchEvent(&window, device).press(0, p1, &window); + deliveryAgent->flushFrameSynchronousEvents(&window); - QCOMPARE(enterSpy1.count(), 1); - QCOMPARE(enterSpy2.count(), 1); - QVERIFY(mouseArea1->pressed()); + QCOMPARE(enterSpy1.size(), 2); + QCOMPARE(enterSpy2.size(), 1); + QVERIFY(mouseArea1->isPressed()); QVERIFY(mouseArea1->hovered()); QVERIFY(!mouseArea2->hovered()); QTest::touchEvent(&window, device).release(0, p1, &window); - QCOMPARE(clickSpy1.count(), 2); + deliveryAgent->flushFrameSynchronousEvents(&window); + QCOMPARE(clickSpy1.size(), 2); QVERIFY(mouseArea1->hovered()); - QVERIFY(!mouseArea1->pressed()); + QVERIFY(!mouseArea1->isPressed()); QVERIFY(!mouseArea2->hovered()); } @@ -1545,6 +1549,117 @@ void tst_TouchMouse::implicitUngrab() QCOMPARE(eventItem->eventList.at(0).type, QEvent::UngrabMouse); QTest::touchEvent(&window, device).release(0, p1); // clean up potential state } + +void tst_TouchMouse::touchCancelWillCancelMousePress() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("singleitem.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root != nullptr); + + EventItem *eventItem = root->findChild<EventItem*>("eventItem1"); + eventItem->acceptMouse = true; + eventItem->setAcceptTouchEvents(false); + QPoint p1(20, 20); + + // Begin a new touch, that gets converted to a mouse press + QTest::touchEvent(&window, device).press(0, p1); + QCOMPARE(eventItem->eventList.size(), 1); + QCOMPARE(eventItem->eventList.at(0).type, QEvent::MouseButtonPress); + + // Cancel it... + QTouchEvent cancelEvent(QEvent::TouchCancel, device); + QCoreApplication::sendEvent(&window, &cancelEvent); + QCOMPARE(eventItem->eventList.size(), 3); + QCOMPARE(eventItem->eventList.at(1).type, QEvent::TouchCancel); + QCOMPARE(eventItem->eventList.at(2).type, QEvent::UngrabMouse); + + // Begin a second touch. Since the last one was cancelled, this + // should end up as a new mouse press on the target item. + QTest::touchEvent(&window, device).press(0, p1); + QVERIFY(eventItem->eventList.size() >= 5); + QCOMPARE(eventItem->eventList.at(3).type, QEvent::MouseButtonPress); + + QTest::touchEvent(&window, device).release(0, p1); // clean up potential state +} + +void tst_TouchMouse::oneTouchInsideAndOneOutside() // QTBUG-102996 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("oneMouseArea.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root); + QQuickMouseArea *ma = root->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + + // Press the MouseArea + QPoint p1 = ma->mapToScene(ma->boundingRect().center()).toPoint(); + QTest::touchEvent(&window, device).press(1, p1); + QQuickTouchUtils::flush(&window); + QVERIFY(ma->isPressed()); + + // Tap outside the MouseArea with a second finger + QPoint p2(100, 100); + QTest::touchEvent(&window, device).stationary(1).press(2, p2); + QQuickTouchUtils::flush(&window); + QTest::touchEvent(&window, device).stationary(1).release(2, p2); + QQuickTouchUtils::flush(&window); + QVERIFY(ma->isPressed()); + + // Press again outside the MouseArea with a second finger + QTest::touchEvent(&window, device).stationary(1).press(2, p2); + + // Release the first finger: MouseArea should be released + QTest::touchEvent(&window, device).release(1, p1).stationary(2); + QQuickTouchUtils::flush(&window); + QCOMPARE(ma->isPressed(), false); + + // Release the second finger + QTest::touchEvent(&window, device).release(2, p2); + QQuickTouchUtils::flush(&window); +} + +void tst_TouchMouse::strayTouchDoesntAutograb() // QTBUG-107867 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("singleitem.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root); + EventItem *eventItem = root->findChild<EventItem*>(); + QVERIFY(eventItem); + // This item accepts (synth-)mouse events but NOT touch + eventItem->acceptMouse = true; + QCOMPARE(eventItem->acceptTouchEvents(), false); // the default in Qt 6 + QPoint p1(6, 6); + grabMonitor.reset(); + + // Begin a new touch, that gets converted to a mouse press + QTest::touchEvent(&window, device).press(0, p1); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "after touch press:" << eventItem->eventList; + QCOMPARE(eventItem->eventList.size(), 1); + QCOMPARE(eventItem->eventList.at(0).type, QEvent::MouseButtonPress); + QCOMPARE(grabMonitor.exclusiveGrabber, eventItem); + + // Drag + for (int i = 0; i < 3; ++i) { + QTest::touchEvent(&window, device).move(0, p1 + QPoint(i * 5, i * 5), &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(grabMonitor.transitionCount, 1); // no new grab + QCOMPARE(eventItem->eventList.size(), i + 2); + QCOMPARE(eventItem->eventList.last().type, QEvent::MouseMove); + } + + // Press an extra point: EventItem should see nothing + QTest::touchEvent(&window, device).stationary(0).press(1, p1); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "after press of second touchpoint:" << eventItem->eventList; + QCOMPARE(eventItem->eventList.size(), 4); + QCOMPARE(grabMonitor.transitionCount, 1); // no new grab + + QTest::touchEvent(&window, device).release(0, p1).release(1, p1); +} + QTEST_MAIN(tst_TouchMouse) #include "tst_touchmouse.moc" |