From c0a8c84eb4bfa8be5fc77d44d25c1a523c022d5c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 Nov 2019 11:49:14 +0100 Subject: Avoid initializing QFlags with 0 or nullptr in further cases Amends 744e77b841878fb017c0f2d60607090008f28180. Change-Id: I16e37aaf503eb62f67fca0e48be4c92c4a72ae46 Reviewed-by: Ulf Hermann --- .../multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/auto/quick/pointerhandlers') 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 -- cgit v1.2.3 From 23df1603f514407d245a2740f32f589318ef654e Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 10 Oct 2019 16:51:13 +0200 Subject: MouseArea: react to touch ungrab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an event handler (such as DragHandler) takes the exclusive grab of a touchpoint that MouseArea had already grabbed as a synth-mouse, it should react in the same way as if its grab of the actual mouse was stolen: release the pressed state, etc. Fixes: QTBUG-77624 Change-Id: I51f4fb253f7d0377be421c23e617942507616e72 Reviewed-by: Jan Arve Sæther --- .../data/dragTakeOverFromSibling.qml | 58 ++++++++ .../mousearea_interop/mousearea_interop.pro | 15 ++ .../mousearea_interop/tst_mousearea_interop.cpp | 160 +++++++++++++++++++++ .../auto/quick/pointerhandlers/pointerhandlers.pro | 1 + 4 files changed, 234 insertions(+) create mode 100644 tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml create mode 100644 tests/auto/quick/pointerhandlers/mousearea_interop/mousearea_interop.pro create mode 100644 tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp (limited to 'tests/auto/quick/pointerhandlers') 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..03cff92f46 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** 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 + +#include +#include +#include +#include +#include +#include + +#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(); + +private: + void createView(QScopedPointer &window, const char *fileName); + QTouchDevice *touchDevice; + QQuickPointerDevice *touchPointerDevice; +}; + +void tst_MouseAreaInterop::createView(QScopedPointer &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 windowPtr; + createView(windowPtr, "dragTakeOverFromSibling.qml"); + QQuickView * window = windowPtr.data(); + auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); + + QPointer handler = window->rootObject()->findChild(); + QVERIFY(handler); + QQuickMouseArea *ma = window->rootObject()->findChild(); + 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() // QTBUG-77624 +{ + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QScopedPointer windowPtr; + createView(windowPtr, "dragTakeOverFromSibling.qml"); + QQuickView * window = windowPtr.data(); + auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(touchPointerDevice); + + QPointer handler = window->rootObject()->findChild(); + QVERIFY(handler); + QQuickMouseArea *ma = window->rootObject()->findChild(); + QVERIFY(ma); + + 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 + 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); + 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/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 \ -- cgit v1.2.3 From 7cdc3727a2b01c59d0a9e19a3cfc4e226ac1ab77 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 5 Dec 2019 12:46:25 +0100 Subject: TapHandler: don't reject stationary touchpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple TapHandlers must be able to react to multiple touchpoints. Often when multiple touchpoints are in contact, some of them will be stationary. In that case TapHandler should not give up its active state, which is the result of returning false from wantsEventPoint(). This partially reverts commit dcc7367997e7241918cdf0c702c7bb8325eb1ad4. Fixes: QTBUG-76954 Change-Id: I836baf771f09d48be8d032472b0c3143e8f7f723 Reviewed-by: Jan Arve Sæther --- .../qquicktaphandler/data/Button.qml | 1 + .../qquicktaphandler/tst_qquicktaphandler.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'tests/auto/quick/pointerhandlers') 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(); -- cgit v1.2.3 From 090f404cf80da35734f712b02cc1543acecd5b62 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 4 Dec 2019 16:15:16 +0100 Subject: Don't let PointerHandler steal touch grab from preventStealing MouseArea MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The scenario: - mouse press: MouseArea grabs; DragHandler gets a passive grab - drag a little: DragHandler's drag threshold is exceeded - drag some more: DragHandler tries to take the exclusive grab This grab takeover succeeded before, because although MA has keepMouseGrab(), the event being delivered is a touch event, and MA does not have keepTouchGrab(). If this happens while QQuickWindowPrivate::touchMouseId is the same touchpoint that the DragHandler is trying to grab, it should not succeed, because we honor the keepMouseGrab() flag. I.e. keepMouseGrab() implies keepTouchGrab() whenever the touchpoint under consideration is currently the touch-mouse. On the other hand, if a DragHandler is used on some item inside a Flickable: on press, the Flickable grabs right away (it has a bad case of FOMO), but the DragHandler just gets a passive grab. When the drag threshold is exceeded, DragHandler must be able to steal the grab from Flickable, because Flickable was just being too aggressive. So now we have the rule that if the Item it wants to steal the grab from is a parent of the type that filters all events, it's OK to ignore the keepMouseGrab() flag and steal anyway (as it did before this patch). Fixes: QTBUG-79163 Change-Id: I2b3f175bea867cb737357857657653b0a7b83995 Reviewed-by: Jan Arve Sæther --- .../mousearea_interop/tst_mousearea_interop.cpp | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'tests/auto/quick/pointerhandlers') diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp index 03cff92f46..794562fea0 100644 --- a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -51,6 +51,7 @@ public: private slots: void dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse(); + void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch(); private: @@ -110,8 +111,18 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse QCOMPARE(handler->active(), false); } -void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch() // QTBUG-77624 +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data() { + QTest::addColumn("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 windowPtr; createView(windowPtr, "dragTakeOverFromSibling.qml"); @@ -122,6 +133,7 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch QVERIFY(handler); QQuickMouseArea *ma = window->rootObject()->findChild(); QVERIFY(ma); + ma->setPreventStealing(preventStealing); QPoint p1(150, 150); QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice); @@ -135,7 +147,7 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch // Start dragging // DragHandler keeps monitoring, due to its passive grab, - // and eventually steals the exclusive grab from MA + // 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); @@ -146,9 +158,15 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch } if (dragStoleGrab) qCDebug(lcPointerTests, "DragHandler stole the grab after %d events", dragStoleGrab); - QVERIFY(dragStoleGrab > 1); - QCOMPARE(handler->active(), true); - QCOMPARE(ma->pressed(), false); + 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); -- cgit v1.2.3 From 08e0742699286b47d7ea9a1cbc49b9f91130135a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 10 Jan 2020 12:33:23 +0100 Subject: Blacklist touchAndDragHandlerOnFlickable() on OpenSuse 15.0 Task-number: QTBUG-81290 Change-Id: I58f64f5eabdb72f2f01bf72e988941521a89d331 Reviewed-by: Simon Hausmann Reviewed-by: Fabian Kosmale --- tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST | 1 + 1 file changed, 1 insertion(+) (limited to 'tests/auto/quick/pointerhandlers') 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] -- cgit v1.2.3