aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/pointerhandlers
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/pointerhandlers')
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST6
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml49
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml24
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp247
-rw-r--r--tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/BLACKLIST5
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml6
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/unloadHandlerOnPress.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/draghandler_and_pinchhandler.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/snapMode.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST3
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/changingCursor.qml37
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverDeviceCursors.qml80
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml17
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp85
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchAndDrag.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml11
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/threeFingers.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/data/transformedPinchHandler.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp165
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml36
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/data/grabberSceneChange.qml78
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp112
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/data/multiPointTracker.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/data/pointTracker.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST8
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml18
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml14
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/dragReleaseMenu.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/nested.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/nestedAndSibling.qml39
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/rightTapHandler.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp380
-rw-r--r--tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickwheelhandler/data/nested.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/qquickwheelhandler/data/rectWheel.qml18
-rw-r--r--tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp2
73 files changed, 1378 insertions, 212 deletions
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
index 5c5f2c9ed9..fd3d9d96b8 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
@@ -5,8 +5,6 @@ opensuse-leap
windows gcc
[touchDragFlickableBehindButton]
windows gcc
-[touchDragSliderAndFlickable]
-* # QTBUG-86729
# QTBUG-95887
[mouseDragSlider]
opensuse-leap
@@ -26,3 +24,7 @@ android
android
[touchAndDragHandlerOnFlickable]
android
+# QTBUG-118063
+[nativeGesturePinchOnFlickableWithParentTapHandler]
+opensuse-leap
+
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt
index b3c93bf804..3836aefbb2 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_flickableinterop Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_flickableinterop LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml
index e3f15f399f..9483a12d1c 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.0
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml
index e4b2fb512d..ec790c9b99 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/GrooveDragSlider.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml
index 0afd397a62..cba135269f 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/KnobDragSlider.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml
index 7f3045595d..99b53e6afb 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml
index a253465a78..f6748da19c 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
index 224172b9d9..562dc156f9 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
index 2cbb40e416..bbd5f5b278 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
index 5468b5d98c..740b698fd4 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml
new file mode 100644
index 0000000000..e594f165b2
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml
@@ -0,0 +1,49 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+
+Flickable {
+ id: root
+ width: 800
+ height: 480
+ contentWidth: 1000
+ contentHeight: 600
+
+ Rectangle {
+ id: pinchable
+ objectName: "pinchable"
+ border.color: "black"
+ color: pinch.active ? "salmon" : "peachpuff"
+ x: 100
+ y: 100
+ width: 200
+ height: 200
+ radius: 80
+ PinchHandler {
+ id: pinch
+ }
+ PointHandler {
+ id: p1
+ target: Rectangle {
+ parent: pinchable
+ color: "green"
+ visible: p1.active
+ x: p1.point.position.x - width / 2
+ y: p1.point.position.y - height / 2
+ width: 9; height: width; radius: width / 2
+ }
+ }
+ PointHandler {
+ id: p0
+ target: Rectangle {
+ parent: pinchable
+ color: "red"
+ visible: p0.active
+ x: p0.point.position.x - width / 2
+ y: p0.point.position.y - height / 2
+ width: 9; height: width; radius: width / 2
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml
new file mode 100644
index 0000000000..2660952f16
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml
@@ -0,0 +1,24 @@
+import QtQuick
+
+Rectangle {
+ width: 320
+ height: 320
+
+ TapHandler {
+ onTapped: color = "tomato"
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: content.width
+ contentHeight: content.height
+ Rectangle {
+ id: content
+ objectName: "pinchable"
+ width: 150
+ height: 150
+ color: "wheat"
+ PinchHandler {}
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml
index 6c2854b28d..dc32b1d82c 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
index 99f3c2a98b..f4c0e5daaa 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
index baa6d99cd2..0293ad03b0 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index 05b764029a..790c7c771e 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -11,6 +11,7 @@
#include <QtQuick/private/qquickitemview_p.h>
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickdraghandler_p.h>
+#include <QtQuick/private/qquickpinchhandler_p.h>
#include <QtQuick/private/qquicktaphandler_p.h>
#include <QtQuick/private/qquicktableview_p.h>
#include <qpa/qwindowsysteminterface.h>
@@ -31,7 +32,6 @@ class tst_FlickableInterop : public QQmlDataTest
public:
tst_FlickableInterop()
: QQmlDataTest(QT_QMLTEST_DATADIR)
- , touchDevice(QTest::createTouchDevice())
{}
private slots:
@@ -55,10 +55,15 @@ private slots:
void touchDragSliderAndFlickable();
void touchAndDragHandlerOnFlickable_data();
void touchAndDragHandlerOnFlickable();
+ void pinchHandlerOnFlickable();
+ void nativeGesturePinchOnFlickableWithParentTapHandler_data();
+ void nativeGesturePinchOnFlickableWithParentTapHandler();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
- QPointingDevice *touchDevice;
+ QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+ QScopedPointer<QPointingDevice> touchpad = QScopedPointer<QPointingDevice>(
+ QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad));
};
void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName)
@@ -97,24 +102,24 @@ void tst_FlickableInterop::touchTapButton()
// Button changes pressed state and emits tapped on release
QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(button->property("pressed").toBool());
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!button->property("pressed").toBool());
QCOMPARE(tappedSpy.size(), 1);
// We can drag <= dragThreshold and the button still acts normal, Flickable doesn't grab
p1 = button->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(button->property("pressed").toBool());
p1 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(button->property("pressed").toBool());
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!button->property("pressed").toBool());
QCOMPARE(tappedSpy.size(), 2);
@@ -145,11 +150,11 @@ void tst_FlickableInterop::touchDragFlickableBehindButton()
tappedSpy.clear();
QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(button->property("pressed").toBool());
p1 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(button->property("pressed").toBool());
int i = 0;
@@ -157,14 +162,14 @@ void tst_FlickableInterop::touchDragFlickableBehindButton()
// Button is no longer pressed because Flickable steals the grab
for (; i < 100 && !flickable->isMoving(); ++i) {
p1 += QPoint(1, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
}
qCDebug(lcPointerTests) << "flickable started moving after" << i << "moves, when we got to" << p1;
QVERIFY(flickable->isMoving());
QCOMPARE(i, 2);
QVERIFY(!button->property("pressed").toBool());
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(!button->property("pressed").toBool());
QCOMPARE(tappedSpy.size(), 0);
@@ -241,7 +246,7 @@ void tst_FlickableInterop::mouseDragFlickableBehindButton()
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
QTRY_VERIFY(button->property("pressed").toBool());
p1 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QVERIFY(button->property("pressed").toBool());
int i = 0;
for (; i < 100 && !flickable->isMoving(); ++i) {
@@ -278,19 +283,19 @@ void tst_FlickableInterop::touchDragSlider()
// Drag the slider in the allowed (vertical) direction
tappedSpy.clear();
QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint() - QPoint(0, 8);
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(slider->property("pressed").toBool());
p1 += QPoint(0, dragThreshold);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(slider->property("pressed").toBool());
QCOMPARE(slider->property("value").toInt(), 49);
p1 += QPoint(0, 1);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
p1 += QPoint(0, 10);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(slider->property("value").toInt() < 49);
QVERIFY(!flickable->isMoving());
@@ -299,12 +304,12 @@ void tst_FlickableInterop::touchDragSlider()
// Now that the DragHandler is active, the Flickable will not steal the grab
// even if we move a large distance horizontally
p1 += QPoint(dragThreshold * 2, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(!flickable->isMoving());
// Release, and do not expect the tapped signal
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
QCOMPARE(tappedSpy.size(), 0);
QCOMPARE(translationChangedSpy.size(), 1);
@@ -417,24 +422,24 @@ void tst_FlickableInterop::touchDragFlickableBehindSlider()
// because Flickable steals the grab
tappedSpy.clear();
QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
QTRY_VERIFY(slider->property("pressed").toBool());
p1 += QPoint(dragThreshold, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(slider->property("pressed").toBool());
int i = 0;
for (; i < 100 && !flickable->isMoving(); ++i) {
p1 += QPoint(1, 0);
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
}
qCDebug(lcPointerTests) << "flickable started moving after" << i << "moves, when we got to" << p1;
QVERIFY(flickable->isMoving());
QCOMPARE(i, 2);
QVERIFY(!slider->property("pressed").toBool());
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(!slider->property("pressed").toBool());
QCOMPARE(tappedSpy.size(), 0);
@@ -508,19 +513,19 @@ void tst_FlickableInterop::touchDragFlickableBehindItemWithHandlers()
QPoint p1 = rect->mapToScene(rect->clipRect().center()).toPoint();
QPoint originP1 = p1;
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).press(1, p1, window);
QQuickTouchUtils::flush(window);
for (int i = 0; i < dragThreshold * 3; ++i) {
p1 = originP1;
p1.rx() += i;
- QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).move(1, p1, window);
QQuickTouchUtils::flush(window);
}
QCOMPARE(flickable->isMoving(), expectedFlickableMoving);
if (!expectedFlickableMoving) {
QVERIFY(rect->mapToScene(rect->clipRect().center()).toPoint().x() > originP1.x());
}
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QTest::touchEvent(window, touchDevice.get()).release(1, p1, window);
QQuickTouchUtils::flush(window);
}
@@ -585,7 +590,7 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
QVERIFY(knob);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
QVERIFY(flickable);
- QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice.get(), false);
// The knob is initially centered over the slider's "groove"
qreal initialXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).x() - slider->mapToScene
@@ -623,7 +628,10 @@ void tst_FlickableInterop::touchDragSliderAndFlickable()
QQuickTouchUtils::flush(window);
qCDebug(lcPointerTests) << "step" << i << ": fingers @" << p1 << p2 << "is Flickable moving yet?" << flickable->isMoving();
}
- QVERIFY(flickable->isMoving());
+ // In Qt 6, Flickable doesn't see the second touchpoint, so it doesn't move.
+ // One way to see this is that Flickable is more immune to stray touches than it otherwise would be.
+ // But time will tell if we are missing out on something useful, which was possible in Qt 5 (QTBUG-123490).
+ QCOMPARE(flickable->isMoving(), false);
qreal knobSliderXOffset = qAbs(knob->mapToScene(knob->clipRect().center()).toPoint().x() -
slider->mapToScene(slider->clipRect().center()).toPoint().x()) - initialXOffset;
if (knobSliderXOffset > 1)
@@ -715,7 +723,7 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
}
// Drag one finger on the Flickable (between delegates) and make sure it flicks
- QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
+ QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice.get(), false);
QPoint p1(780, 460);
if (delegate)
p1 = delegate->mapToScene(delegate->clipRect().bottomRight()).toPoint() + QPoint(-1, 1);
@@ -782,6 +790,187 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
touchSeq.release(1, p1, window).commit();
}
+void tst_FlickableInterop::pinchHandlerOnFlickable()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("pinchOnFlickable.qml")));
+ QQuickFlickable *flickable = qmlobject_cast<QQuickFlickable*>(window.rootObject());
+ QVERIFY(flickable);
+ QQuickPointerHandler *pinchHandler = flickable->findChild<QQuickPointerHandler*>();
+ QVERIFY(pinchHandler);
+ QQuickItem *pinchable = pinchHandler->target();
+ QVERIFY(pinchable);
+
+ QSignalSpy flickMoveSpy(flickable, &QQuickFlickable::movementStarted);
+ QSignalSpy grabChangedSpy(touchDevice.get(), &QPointingDevice::grabChanged);
+
+ QObject *grabber = nullptr;
+ connect(touchDevice.get(), &QPointingDevice::grabChanged,
+ [&grabber](QObject *g, QPointingDevice::GrabTransition transition, const QPointerEvent *, const QEventPoint &) {
+ if (transition == QPointingDevice::GrabTransition::GrabExclusive)
+ grabber = g;
+ });
+
+ QPoint p0 = pinchable->mapToScene({50, 100}).toPoint();
+ QPoint p1 = pinchable->mapToScene({150, 100}).toPoint();
+ QTest::QTouchEventSequence touch = QTest::touchEvent(&window, touchDevice.get());
+
+ touch.press(0, p0, &window).press(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ int activeStep = -1;
+ int grabTransitionCount = 0;
+ // drag two fingers down: PinchHandler moves the item; Flickable doesn't grab, because there are 2 points
+ for (int i = 0; i < 4; ++i) {
+ p0 += QPoint(0, dragThreshold);
+ p1 += QPoint(0, dragThreshold);
+ touch.move(0, p0, &window).move(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ if (pinchHandler->active() && activeStep < 0) {
+ qCDebug(lcPointerTests) << "pinch began at step" << i;
+ activeStep = i;
+ QCOMPARE(grabber, pinchHandler);
+ grabTransitionCount = grabChangedSpy.count();
+ }
+ }
+ QVERIFY(pinchHandler->active());
+ QCOMPARE(grabChangedSpy.count(), grabTransitionCount);
+ QCOMPARE(grabber, pinchHandler);
+ qreal scale = pinchable->scale();
+ QCOMPARE(scale, 1);
+ qreal rot = pinchable->rotation();
+ QCOMPARE(rot, 0);
+ // start expanding and rotating
+ for (int i = 0; i < 4; ++i) {
+ p0 += QPoint(-5, 10);
+ p1 += QPoint(5, -10);
+ touch.move(0, p0, &window).move(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ QVERIFY(pinchHandler->active());
+ // PinchHandler keeps grab: no more transitions
+ QCOMPARE(grabChangedSpy.count(), grabTransitionCount);
+ QCOMPARE(grabber, pinchHandler);
+ QTRY_COMPARE_GT(pinchable->scale(), scale);
+ scale = pinchable->scale();
+ QCOMPARE_LT(pinchable->rotation(), rot);
+ rot = pinchable->rotation();
+ }
+ touch.release(0, p0, &window).release(1, p1, &window).commit();
+ QQuickTouchUtils::flush(&window);
+ QTRY_COMPARE(pinchHandler->active(), false);
+ QCOMPARE(flickMoveSpy.count(), 0); // Flickable never moved
+}
+
+void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler_data()
+{
+ QTest::addColumn<const QPointingDevice*>("device");
+ QTest::addColumn<Qt::MouseButton>("button");
+ QTest::addColumn<Qt::NativeGestureType>("gesture");
+ QTest::addColumn<qreal>("value");
+ QTest::addColumn<qreal>("expectedPropertyValue");
+
+ const QPointingDevice *constTouchPad = touchpad.data();
+
+ QTest::newRow("touchpad: left and rotate") << constTouchPad << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("touchpad: right and rotate") << constTouchPad << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("touchpad: left and scale") << constTouchPad << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ QTest::newRow("touchpad: right and scale") << constTouchPad << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+
+ const auto *mouse = QPointingDevice::primaryPointingDevice();
+ if (mouse->type() == QInputDevice::DeviceType::Mouse) {
+ QTest::newRow("mouse: left and rotate") << mouse << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("mouse: right and rotate") << mouse << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 10.0;
+ QTest::newRow("mouse: left and scale") << mouse << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ QTest::newRow("mouse: right and scale") << mouse << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21;
+ } else {
+ qCWarning(lcPointerTests) << "skipping mouse tests: primary device is not a mouse" << mouse;
+ }
+}
+
+void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler()
+{
+ QFETCH(const QPointingDevice*, device);
+ QFETCH(Qt::MouseButton, button);
+ QFETCH(Qt::NativeGestureType, gesture);
+ QFETCH(qreal, value);
+ QFETCH(qreal, expectedPropertyValue);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("pinchOnFlickableWithParentTapHandler.qml")));
+ QQuickFlickable *flickable = window.rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QQuickPointerHandler *pinchHandler = flickable->findChild<QQuickPinchHandler*>();
+ QVERIFY(pinchHandler);
+ QQuickItem *pinchable = pinchHandler->target();
+ QVERIFY(pinchable);
+ QQuickTapHandler *tapHandler = window.rootObject()->findChild<QQuickTapHandler*>();
+ QVERIFY(tapHandler);
+ const bool expectTap = button & tapHandler->acceptedButtons();
+
+ QSignalSpy flickMoveSpy(flickable, &QQuickFlickable::movementStarted);
+ QSignalSpy grabChangedSpy(touchDevice.get(), &QPointingDevice::grabChanged);
+ QSignalSpy tapActiveSpy(tapHandler, &QQuickTapHandler::activeChanged);
+ QSignalSpy tapSpy(tapHandler, &QQuickTapHandler::tapped);
+
+ QObject *grabber = nullptr;
+ connect(device, &QPointingDevice::grabChanged,
+ [&grabber](QObject *g, QPointingDevice::GrabTransition transition, const QPointerEvent *, const QEventPoint &) {
+ if (transition == QPointingDevice::GrabTransition::GrabExclusive)
+ grabber = g;
+ });
+
+ const QPoint pinchPos(75, 75);
+ const QPoint outsidePos(200, 200);
+
+ // move to position
+ QTest::mouseMove(&window, pinchPos);
+
+ // pinch via native gesture
+ ulong ts = 502; // after the mouse move, which is at time 501 in practice
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(),
+ Qt::BeginNativeGesture, pinchPos, pinchPos);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ for (int i = 0; i < 2; ++i) {
+ QWindowSystemInterface::handleGestureEventWithRealValue(&window, ts++, touchpad.get(),
+ gesture, value, pinchPos, pinchPos);
+ }
+ if (gesture == Qt::RotateNativeGesture)
+ QTRY_COMPARE(pinchHandler->parentItem()->rotation(), expectedPropertyValue);
+ else if (gesture == Qt::ZoomNativeGesture)
+ QTRY_COMPARE(pinchHandler->parentItem()->scale(), expectedPropertyValue);
+ QVERIFY(pinchHandler->active());
+ QCOMPARE(grabChangedSpy.count(), 0);
+ QCOMPARE(grabber, nullptr);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(),
+ Qt::EndNativeGesture, pinchPos, pinchPos);
+
+ // tap in square: TapHandler detects tap iff acceptedButtons permits
+ // TODO delay; unfortunately this also begins at timestamp 502 because we don't have testlib
+ // functions to send gesture events, and QQuickTest::pointerPress() doesn't take a delay value
+ QQuickTest::pointerPress(device, &window, 0, pinchPos, button);
+ QCOMPARE(tapHandler->point().id(), expectTap ? 0 : -1);
+ QQuickTest::pointerRelease(device, &window, 0, pinchPos, button);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(tapSpy.size() != 0, expectTap);
+ QCOMPARE(tapActiveSpy.size(), 0);
+ QCOMPARE(tapHandler->point().id(), -1); // does not keep tracking after release
+
+ // move outside: nothing should happen;
+ // but QTBUG-108896 happened because TapHandler was setting pointInfo to track this moving point
+ QQuickTest::pointerMove(device, &window, 0, outsidePos);
+ QCOMPARE(tapHandler->point().id(), -1); // does not track after mouse move
+
+ // tap outside: nothing happens
+ tapSpy.clear();
+ tapActiveSpy.clear();
+ QQuickTest::pointerPress(device, &window, 0, outsidePos, button);
+ QQuickTest::pointerRelease(device, &window, 0, outsidePos, button);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(tapSpy.size(), 0);
+ QCOMPARE(tapActiveSpy.size(), 0);
+}
+
QTEST_MAIN(tst_FlickableInterop)
#include "tst_flickableinterop.moc"
diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt
index f66a7e8d0d..22123e6385 100644
--- a/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_mousearea_interop Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_mousearea_interop LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml b/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml
index 846c31cc61..1bde433dba 100644
--- a/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml
+++ b/tests/auto/quick/pointerhandlers/mousearea_interop/data/dragTakeOverFromSibling.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
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 3c288cbb3b..b1a480b9cf 100644
--- a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp
+++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -16,6 +16,8 @@
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/viewtestutils_p.h>
+#include <QtCore/qpointer.h>
+
Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
class tst_MouseAreaInterop : public QQmlDataTest
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/BLACKLIST b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/BLACKLIST
index 3f01d3a7d4..80d6dd0ee8 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/BLACKLIST
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/BLACKLIST
@@ -1,2 +1,3 @@
-[touchesThenPinch]
-* # QTBUG-86729
+# QTBUG-118062
+[touchDrag]
+opensuse-leap
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt
index b0843f726b..9f19e8b427 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_multipointtoucharea_interop Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_multipointtoucharea_interop LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml
index e6ebfdd552..ad4494eb25 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/dragParentOfMPTA.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml
index b6fad6fade..199292e015 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
@@ -35,8 +35,8 @@ Rectangle {
Item {
id: crosshairs
property TouchPoint touchPoint
- x: touchPoint.x - width / 2
- y: touchPoint.y - height / 2
+ x: touchPoint?.x - width / 2
+ y: touchPoint?.y - height / 2
width: 300; height: 300
visible: touchPoint.pressed
rotation: touchPoint.rotation
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/unloadHandlerOnPress.qml b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/unloadHandlerOnPress.qml
index e8b8fe769e..868a5265a6 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/unloadHandlerOnPress.qml
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/unloadHandlerOnPress.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
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 ab64f6bb24..a4cc182422 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -15,6 +15,8 @@
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/viewtestutils_p.h>
+#include <QtCore/qpointer.h>
+
Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
class tst_MptaInterop : public QQmlDataTest
@@ -250,7 +252,7 @@ void tst_MptaInterop::touchesThenPinch()
}
qCDebug(lcPointerTests) << "drag started after" << dragTookGrab
<< "moves; ended with translation" << drag->activeTranslation();
- QCOMPARE(devPriv->pointById(1)->exclusiveGrabber, drag);
+ QCOMPARE(devPriv->pointById(2)->exclusiveGrabber, drag);
QTRY_VERIFY(drag->activeTranslation().x() > 0);
touch.release(2, p2).commit();
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt
index 06cc34441a..23087c1d48 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickdraghandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickdraghandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml
index 7a305e7b79..065b0aaed8 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml
index e3f15f399f..9483a12d1c 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.0
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml
index 502891cd1b..200e846207 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
index 1041cd4f07..47be6052ad 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.15
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draghandler_and_pinchhandler.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draghandler_and_pinchhandler.qml
index 7a4dc3a69a..5d700cdd08 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draghandler_and_pinchhandler.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draghandler_and_pinchhandler.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml
index 146881e0a4..ea71da5623 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml
index e805adbcb8..6c7a25c148 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/snapMode.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/snapMode.qml
index 0a3d3618a8..30b28ac9e8 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/snapMode.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/snapMode.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 9d6e4409d0..15df656b93 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -17,6 +17,8 @@
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/viewtestutils_p.h>
+#include <QtCore/qpointer.h>
+
Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
class tst_DragHandler : public QQmlDataTest
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST
index 1c4499753a..c0d73ff05f 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST
@@ -3,3 +3,6 @@ macos # Can't move cursor (QTBUG-76312)
# QTBUG-103065
[movingItemWithHoverHandler]
android
+[window]
+opensuse-leap # QTBUG-122405
+
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt
index 25c8dfd604..a2e7d640d5 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickhoverhandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickhoverhandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/changingCursor.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/changingCursor.qml
new file mode 100644
index 0000000000..42b658a4d4
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/changingCursor.qml
@@ -0,0 +1,37 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick 2.15
+
+
+Rectangle {
+ id: brownRect
+ objectName: "brownRect"
+
+ width: 400
+ height: 400
+
+ HoverHandler {
+ id: hh
+ cursorShape: parent.colorIndex == 0 ?
+ Qt.CrossCursor :
+ Qt.OpenHandCursor
+ }
+
+ property list<color> colors: ["beige", "brown"]
+ property int colorIndex: 0
+
+ color: colors[colorIndex]
+
+ Timer {
+ id: colorTimer
+ interval: 200
+ running: true
+ repeat: true
+
+ onTriggered: {
+ parent.colorIndex = (parent.colorIndex + 1) % parent.colors.length;
+ parent.color = parent.colors[parent.colorIndex];
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverDeviceCursors.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverDeviceCursors.qml
index edb56ffdc6..48e130a35e 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverDeviceCursors.qml
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverDeviceCursors.qml
@@ -3,47 +3,53 @@ import QtQuick
Item {
width: 200; height: 200
- HoverHandler {
- objectName: "stylus"
- acceptedDevices: PointerDevice.Stylus
- acceptedPointerTypes: PointerDevice.Pen
- cursorShape: Qt.CrossCursor
- }
+ Rectangle {
+ width: 100; height: 100
+ anchors.centerIn: parent
+ border.color: "black"
- HoverHandler {
- objectName: "stylus eraser"
- acceptedDevices: PointerDevice.Stylus
- acceptedPointerTypes: PointerDevice.Eraser
- cursorShape: Qt.PointingHandCursor
- }
+ HoverHandler {
+ objectName: "stylus"
+ acceptedDevices: PointerDevice.Stylus
+ acceptedPointerTypes: PointerDevice.Pen
+ cursorShape: Qt.CrossCursor
+ }
- HoverHandler {
- objectName: "airbrush"
- acceptedDevices: PointerDevice.Airbrush
- acceptedPointerTypes: PointerDevice.Pen
- cursorShape: Qt.BusyCursor
- }
+ HoverHandler {
+ objectName: "stylus eraser"
+ acceptedDevices: PointerDevice.Stylus
+ acceptedPointerTypes: PointerDevice.Eraser
+ cursorShape: Qt.PointingHandCursor
+ }
- HoverHandler {
- objectName: "airbrush eraser"
- acceptedDevices: PointerDevice.Airbrush
- acceptedPointerTypes: PointerDevice.Eraser
- cursorShape: Qt.OpenHandCursor
- }
+ HoverHandler {
+ objectName: "airbrush"
+ acceptedDevices: PointerDevice.Airbrush
+ acceptedPointerTypes: PointerDevice.Pen
+ cursorShape: Qt.BusyCursor
+ }
- HoverHandler {
- objectName: "mouse"
- acceptedDevices: PointerDevice.Mouse
- // acceptedPointerTypes can be omitted because Mouse is not ambiguous.
- // When a genuine mouse move is sent, there's a conflict, and this one should win.
- cursorShape: Qt.IBeamCursor
- }
+ HoverHandler {
+ objectName: "airbrush eraser"
+ acceptedDevices: PointerDevice.Airbrush
+ acceptedPointerTypes: PointerDevice.Eraser
+ cursorShape: Qt.OpenHandCursor
+ }
+
+ HoverHandler {
+ objectName: "mouse"
+ acceptedDevices: PointerDevice.Mouse
+ // acceptedPointerTypes can be omitted because Mouse is not ambiguous.
+ // When a genuine mouse move is sent, there's a conflict, and this one should win.
+ cursorShape: Qt.IBeamCursor
+ }
- HoverHandler {
- objectName: "conflictingMouse"
- acceptedDevices: PointerDevice.Mouse
- // acceptedPointerTypes can be omitted because Mouse is not ambiguous.
- // When a genuine mouse move is sent, there's a conflict, and this one should lose.
- cursorShape: Qt.ClosedHandCursor
+ HoverHandler {
+ objectName: "conflictingMouse"
+ acceptedDevices: PointerDevice.Mouse
+ // acceptedPointerTypes can be omitted because Mouse is not ambiguous.
+ // When a genuine mouse move is sent, there's a conflict, and this one should lose.
+ cursorShape: Qt.ClosedHandCursor
+ }
}
}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml
new file mode 100644
index 0000000000..60dfc53c40
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml
@@ -0,0 +1,17 @@
+import QtQuick
+
+Item {
+ width: 320
+ height: 240
+
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ color: hh.hovered ? "lightsteelblue" : "beige"
+
+ HoverHandler {
+ id: hh
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
index 43d9827ad7..ca30a7fe99 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.15
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
index e488c0486f..0569fed472 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -48,9 +48,13 @@ private slots:
void deviceCursor();
void addHandlerFromCpp();
void ensureHoverHandlerWorksWhenItemHasHoverDisabled();
+ void changeCursor();
+ void touchDrag();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+
+ QScopedPointer<QPointingDevice> touchscreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
};
void tst_HoverHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
@@ -567,6 +571,17 @@ void tst_HoverHandler::deviceCursor()
QCOMPARE(eraserHandler->isHovered(), false);
QCOMPARE(aibrushHandler->isHovered(), false);
QCOMPARE(airbrushEraserHandler->isHovered(), true); // there was no fresh QTabletEvent to tell it not to be hovered
+
+ // hover with the stylus again, then move the mouse outside the handlers' parent item
+ testStylusDevice(QInputDevice::DeviceType::Stylus, QPointingDevice::PointerType::Pen,
+ Qt::CrossCursor, stylusHandler);
+ QTest::mouseMove(&window, QPoint(180, 180));
+ // the mouse has left the item: all its HoverHandlers should be unhovered (QTBUG-116505)
+ QCOMPARE(stylusHandler->isHovered(), false);
+ QCOMPARE(eraserHandler->isHovered(), false);
+ QCOMPARE(aibrushHandler->isHovered(), false);
+ QCOMPARE(airbrushEraserHandler->isHovered(), false);
+ QCOMPARE(mouseHandler->isHovered(), false);
}
void tst_HoverHandler::addHandlerFromCpp()
@@ -671,6 +686,74 @@ void tst_HoverHandler::ensureHoverHandlerWorksWhenItemHasHoverDisabled()
QCOMPARE(spy.size(), 2);
}
+void tst_HoverHandler::changeCursor()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "changingCursor.qml");
+ QQuickView * window = windowPtr.data();
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickItem *item = window->findChild<QQuickItem *>("brownRect");
+ QVERIFY(item);
+ QQuickHoverHandler *hh = item->findChild<QQuickHoverHandler *>();
+ QVERIFY(hh);
+
+ QPoint itemCenter(item->mapToScene(QPointF(item->width() / 2, item->height() / 2)).toPoint());
+ QSignalSpy hoveredSpy(hh, SIGNAL(hoveredChanged()));
+
+ QTest::mouseMove(window, itemCenter);
+
+ QTRY_COMPARE(hoveredSpy.size(), 1);
+
+#if QT_CONFIG(cursor)
+ QTRY_COMPARE(window->cursor().shape(), Qt::CrossCursor);
+ QTRY_COMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+ QTRY_COMPARE(window->cursor().shape(), Qt::CrossCursor);
+ QTRY_COMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+#endif
+}
+
+void tst_HoverHandler::touchDrag()
+{
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("hoverHandler.qml")));
+ const QQuickItem *root = window.rootObject();
+ QQuickHoverHandler *handler = root->findChild<QQuickHoverHandler *>();
+ QVERIFY(handler);
+
+ // polishAndSync() calls flushFrameSynchronousEvents() before emitting afterAnimating()
+ QSignalSpy frameSyncSpy(&window, &QQuickWindow::afterAnimating);
+
+ const QPoint out(root->width() - 1, root->height() / 2);
+ QPoint in(root->width() / 2, root->height() / 2);
+
+ QTest::touchEvent(&window, touchscreen.get()).press(0, out, &window);
+ QQuickTouchUtils::flush(&window);
+ QCOMPARE(handler->isHovered(), false);
+
+ frameSyncSpy.clear();
+ QTest::touchEvent(&window, touchscreen.get()).move(0, in, &window);
+ QQuickTouchUtils::flush(&window);
+ QTRY_COMPARE(handler->isHovered(), true);
+ QCOMPARE(handler->point().scenePosition(), in);
+
+ in += {10, 10};
+ QTest::touchEvent(&window, touchscreen.get()).move(0, in, &window);
+ QQuickTouchUtils::flush(&window);
+ // ensure that the color change is visible
+ QTRY_COMPARE_GE(frameSyncSpy.size(), 1);
+ QCOMPARE(handler->isHovered(), true);
+ QCOMPARE(handler->point().scenePosition(), in);
+
+ QTest::touchEvent(&window, touchscreen.get()).move(0, out, &window);
+ QQuickTouchUtils::flush(&window);
+ QTRY_COMPARE_GE(frameSyncSpy.size(), 2);
+ QCOMPARE(handler->isHovered(), false);
+
+ QTest::touchEvent(&window, touchscreen.get()).release(0, out, &window);
+}
+
QTEST_MAIN(tst_HoverHandler)
#include "tst_qquickhoverhandler.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt
index f16dfa3421..1334607ab2 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickpinchhandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickpinchhandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml
index a348938aca..9d9903fc0e 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.15
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchAndDrag.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchAndDrag.qml
index 70c105836f..ddd63ec720 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchAndDrag.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchAndDrag.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml
index 37f22c949a..2b9b3eb156 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
@@ -35,7 +35,14 @@ Rectangle {
}
}
- Text { color: "magenta"; z: 1; text: "scale: " + blackRect.scale}
+ Text {
+ color: "magenta"
+ z: 1
+ text: "scale: " + blackRect.scale +
+ "\npos: " + blackRect.x.toFixed(2) + ", " + blackRect.y.toFixed(2) +
+ "\ntranslation: active " + pincharea.activeTranslation.x.toFixed(2) + ", " + pincharea.activeTranslation.y.toFixed(2) +
+ "\n persistent " + pincharea.persistentTranslation.x.toFixed(2) + ", " + pincharea.persistentTranslation.y.toFixed(2)
+ }
Rectangle {
id: blackRect
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/threeFingers.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/threeFingers.qml
index dbebf92933..ed9220f99e 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/threeFingers.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/threeFingers.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/transformedPinchHandler.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/transformedPinchHandler.qml
index 56fa8c9f8e..f25d0e9f38 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/transformedPinchHandler.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/transformedPinchHandler.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
index a61cbd76db..78483c5bdb 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
#include <QtTest/QSignalSpy>
@@ -34,6 +34,8 @@ private slots:
void scaleThreeFingers();
void scaleNativeGesture_data();
void scaleNativeGesture();
+ void cumulativeNativeGestures_data();
+ void cumulativeNativeGestures();
void pan();
void dragAxesEnabled_data();
void dragAxesEnabled();
@@ -43,8 +45,8 @@ private slots:
void transformedpinchHandler();
private:
- QPointingDevice *touchscreen = QTest::createTouchDevice();
- QPointingDevice *touchpad = QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad);
+ QScopedPointer<QPointingDevice> touchscreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+ QScopedPointer<QPointingDevice> touchpad = QScopedPointer<QPointingDevice>(QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad));
};
void tst_QQuickPinchHandler::cleanupTestCase()
@@ -230,13 +232,13 @@ void tst_QQuickPinchHandler::scale()
QVERIFY(pinchHandler != nullptr);
QQuickItem *blackRect = (hasTarget ? pinchHandler->target() : pinchHandler->parentItem());
QVERIFY(blackRect != nullptr);
- QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
+ QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition,QEventPoint)));
QSignalSpy scaleChangedSpy(pinchHandler, &QQuickPinchHandler::scaleChanged);
if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
QPoint p0(80, 80);
QPoint p1(100, 100);
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&window, touchscreen.get());
pinchSequence.press(0, p0, &window).commit();
QQuickTouchUtils::flush(&window);
// In order for the stationary point to remember its previous position,
@@ -383,7 +385,7 @@ void tst_QQuickPinchHandler::scaleThreeFingers()
QPoint p1(220, 80);
QPoint p2(150, 220);
{
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get());
pinchSequence.press(0, p0, window).commit();
QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
@@ -488,10 +490,10 @@ void tst_QQuickPinchHandler::scaleNativeGesture()
// so as to compensate for the change in size, to hold the centroid in place
const QPointF expectedPos = targetPos + QPointF( (pinchPos.x() - target->x()) * (expectedScale - 1),
(pinchPos.y() - target->y()) * (expectedScale - 1) );
- QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(),
Qt::BeginNativeGesture, pinchPos, pinchPos);
if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
- QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad.get(),
Qt::ZoomNativeGesture, scale - 1, pinchPos, pinchPos);
if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
QTRY_COMPARE(target->scale(), expectedScale);
@@ -509,7 +511,7 @@ void tst_QQuickPinchHandler::scaleNativeGesture()
QCOMPARE(pinchHandler->activeRotation(), 0);
QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), 0);
QCOMPARE(pinchHandler->rotationAxis()->activeValue(), 0);
- QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(),
Qt::EndNativeGesture, pinchPos, pinchPos);
QTRY_COMPARE(pinchHandler->active(), false);
QCOMPARE(target->scale(), expectedScale);
@@ -528,9 +530,9 @@ void tst_QQuickPinchHandler::scaleNativeGesture()
const qreal reverseScale = (1 / expectedScale);
pinchPos = QPointF(110, 110);
pinchLocalPos = target->mapFromScene(pinchPos);
- QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(),
Qt::BeginNativeGesture, pinchPos, pinchPos);
- QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad.get(),
Qt::ZoomNativeGesture, reverseScale - 1, pinchPos, pinchPos);
QTRY_COMPARE(target->scale(), 1);
QCOMPARE(pinchHandler->active(), true);
@@ -541,7 +543,7 @@ void tst_QQuickPinchHandler::scaleNativeGesture()
QCOMPARE(pinchHandler->persistentScale(), 1);
QCOMPARE(pinchHandler->activeScale(), reverseScale);
QCOMPARE(pinchHandler->scaleAxis()->activeValue(), reverseScale);
- QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad,
+ QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad.get(),
Qt::EndNativeGesture, pinchPos, pinchPos);
QTRY_COMPARE(pinchHandler->active(), false);
QCOMPARE(target->scale(), 1);
@@ -550,6 +552,127 @@ void tst_QQuickPinchHandler::scaleNativeGesture()
QCOMPARE(pinchHandler->scaleAxis()->activeValue(), 1);
}
+void tst_QQuickPinchHandler::cumulativeNativeGestures_data()
+{
+ QTest::addColumn<const QPointingDevice*>("device");
+ QTest::addColumn<Qt::NativeGestureType>("gesture");
+ QTest::addColumn<qreal>("value");
+ QTest::addColumn<QList<QPoint>>("expectedTargetTranslations");
+
+ const auto *touchpadDevice = touchpad.get();
+ const auto *mouse = QPointingDevice::primaryPointingDevice();
+
+ QTest::newRow("touchpad: rotate") << touchpadDevice << Qt::RotateNativeGesture << 5.0
+ << QList<QPoint>{{-2, 2}, {-5, 4}, {-7, 6}, {-10, 7}};
+ QTest::newRow("touchpad: scale") << touchpadDevice << Qt::ZoomNativeGesture << 0.1
+ << QList<QPoint>{{3, 3}, {5, 5}, {8, 8}, {12, 12}};
+ if (mouse->type() == QInputDevice::DeviceType::Mouse) {
+ QTest::newRow("mouse: rotate") << mouse << Qt::RotateNativeGesture << 5.0
+ << QList<QPoint>{{-2, 2}, {-5, 4}, {-7, 6}, {-10, 7}};
+ QTest::newRow("mouse: scale") << mouse << Qt::ZoomNativeGesture << 0.1
+ << QList<QPoint>{{3, 3}, {5, 5}, {8, 8}, {12, 12}};
+ } else {
+ qCWarning(lcPointerTests) << "skipping mouse tests: primary device is not a mouse" << mouse;
+ }
+}
+
+void tst_QQuickPinchHandler::cumulativeNativeGestures()
+{
+ QFETCH(const QPointingDevice*, device);
+ QFETCH(Qt::NativeGestureType, gesture);
+ QFETCH(qreal, value);
+ QFETCH(QList<QPoint>, expectedTargetTranslations);
+
+ QCOMPARE(expectedTargetTranslations.size(), 4);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("pinchproperties.qml")));
+ QVERIFY(window.rootObject() != nullptr);
+ qApp->processEvents();
+
+ QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject());
+ QVERIFY(root != nullptr);
+ QQuickPinchHandler *pinchHandler = root->findChild<QQuickPinchHandler*>("pinchHandler");
+ QVERIFY(pinchHandler != nullptr);
+ QQuickItem *target = root->findChild<QQuickItem*>("blackrect");
+ QVERIFY(target != nullptr);
+ QCOMPARE(pinchHandler->target(), target);
+
+ ulong ts = 1;
+ qreal expectedScale = 1;
+ qreal expectedRotation = 0;
+ QPointF pinchPos(75, 75);
+ const QPointF initialTargetPos(target->position());
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, device,
+ Qt::BeginNativeGesture, pinchPos, pinchPos);
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ for (int i = 1; i <= 4; ++i) {
+ QWindowSystemInterface::handleGestureEventWithRealValue(&window, ts++, device,
+ gesture, value, pinchPos, pinchPos);
+ qApp->processEvents();
+ switch (gesture) {
+ case Qt::ZoomNativeGesture:
+ expectedScale = qBound(qreal(0.5), qPow(1 + value, i), qreal(4));
+ break;
+ case Qt::RotateNativeGesture:
+ expectedRotation = qBound(qreal(0), value * i, qreal(90));
+ break;
+ default:
+ break; // PinchHandler doesn't react to the others
+ }
+
+ qCDebug(lcPointerTests) << i << gesture << "with value" << value
+ << ": scale" << target->scale() << "expected" << expectedScale
+ << ": rotation" << target->rotation() << "expected" << expectedRotation;
+ if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
+ QCOMPARE(target->scale(), expectedScale);
+ QCOMPARE(target->rotation(), expectedRotation);
+ QCOMPARE(pinchHandler->persistentScale(), expectedScale);
+ QCOMPARE(pinchHandler->activeScale(), expectedScale);
+ QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), expectedScale);
+ QCOMPARE(pinchHandler->scaleAxis()->activeValue(), expectedScale);
+ QCOMPARE(pinchHandler->persistentRotation(), expectedRotation);
+ QCOMPARE(pinchHandler->activeRotation(), expectedRotation);
+ QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), expectedRotation);
+ QCOMPARE(pinchHandler->rotationAxis()->activeValue(), expectedRotation);
+ // The target gets transformed around the gesture position, for which
+ // QQuickItemPrivate::adjustedPosForTransform() computes its new position to compensate.
+ QPointF delta = target->position() - initialTargetPos;
+ qCDebug(lcPointerTests) << "target moved by" << delta << "to" << target->position()
+ << "active trans" << pinchHandler->activeTranslation()
+ << "perst trans" << pinchHandler->persistentTranslation();
+ QCOMPARE_NE(target->position(), initialTargetPos);
+ QCOMPARE(delta.toPoint(), expectedTargetTranslations.at(i - 1));
+ // The native pinch gesture cannot include a translation component (and
+ // the cursor doesn't move while you are performing the gesture on a touchpad).
+ QCOMPARE(pinchHandler->activeTranslation(), QPointF());
+ // The target only moves to compensate for scale and rotation changes, and that's
+ // not reflected in PinchHandler.persistentTranslation.
+ QCOMPARE(pinchHandler->persistentTranslation(), QPointF());
+ }
+ QCOMPARE(pinchHandler->active(), true);
+ qCDebug(lcPointerTests) << "centroid: local" << pinchHandler->centroid().position()
+ << "scene" << pinchHandler->centroid().scenePosition();
+ QCOMPARE(pinchHandler->persistentScale(), expectedScale);
+ QCOMPARE(pinchHandler->activeScale(), expectedScale);
+ QCOMPARE(pinchHandler->scaleAxis()->activeValue(), expectedScale);
+ QWindowSystemInterface::handleGestureEvent(&window, ts++, device,
+ Qt::EndNativeGesture, pinchPos, pinchPos);
+ QTRY_COMPARE(pinchHandler->active(), false);
+ QCOMPARE(target->scale(), expectedScale);
+ QCOMPARE(target->rotation(), expectedRotation);
+ QCOMPARE(pinchHandler->persistentScale(), expectedScale);
+ QCOMPARE(pinchHandler->activeScale(), 1);
+ QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), expectedScale);
+ QCOMPARE(pinchHandler->scaleAxis()->activeValue(), 1);
+ QCOMPARE(pinchHandler->persistentRotation(), expectedRotation);
+ QCOMPARE(pinchHandler->activeRotation(), 0);
+ QCOMPARE(pinchHandler->rotationAxis()->persistentValue(), expectedRotation);
+ QCOMPARE(pinchHandler->rotationAxis()->activeValue(), 0);
+ QCOMPARE(pinchHandler->activeTranslation(), QPointF());
+ QCOMPARE(pinchHandler->persistentTranslation(), QPointF());
+}
+
void tst_QQuickPinchHandler::pan()
{
QQuickView *window = QQuickViewTestUtils::createView();
@@ -575,7 +698,7 @@ void tst_QQuickPinchHandler::pan()
QPoint p1(100, 100);
{
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get());
pinchSequence.press(0, p0, window).commit();
QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
@@ -649,7 +772,7 @@ void tst_QQuickPinchHandler::pan()
// pan x beyond bound
p0 += QPoint(100,100);
p1 += QPoint(100,100);
- QTest::touchEvent(window, touchscreen).move(0, p0, window).move(1, p1, window);
+ QTest::touchEvent(window, touchscreen.get()).move(0, p0, window).move(1, p1, window);
QQuickTouchUtils::flush(window);
QCOMPARE(blackRect->x(), 140.0);
@@ -657,7 +780,7 @@ void tst_QQuickPinchHandler::pan()
QCOMPARE(translationChangedSpy.size(), 5);
QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(100, 100));
- QTest::touchEvent(window, touchscreen).release(0, p0, window).release(1, p1, window);
+ QTest::touchEvent(window, touchscreen.get()).release(0, p0, window).release(1, p1, window);
QQuickTouchUtils::flush(window);
QVERIFY(!root->property("pinchActive").toBool());
}
@@ -697,7 +820,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled()
QPoint blackRectPos = blackRect->position().toPoint();
// press two points, one above the rectangle's center and one below
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get());
pinchSequence.press(0, p0, window).press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
@@ -734,7 +857,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled()
QCOMPARE(blackRect->position().toPoint().x(), xEnabled ? 140 : blackRectPos.x()); // because of xAxis.maximum
QCOMPARE(blackRect->position().toPoint().y(), yEnabled ? 170 : blackRectPos.y()); // because of yAxis.maximum
- QTest::touchEvent(window, touchscreen).release(0, p0, window).release(1, p1, window);
+ QTest::touchEvent(window, touchscreen.get()).release(0, p0, window).release(1, p1, window);
QQuickTouchUtils::flush(window);
}
@@ -763,7 +886,7 @@ void tst_QQuickPinchHandler::retouch()
QPoint p0(80, 80);
QPoint p1(100, 100);
{
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get());
pinchSequence.press(0, p0, window).commit();
QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
@@ -846,7 +969,7 @@ void tst_QQuickPinchHandler::cancel()
QPoint p0(80, 80);
QPoint p1(100, 100);
{
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen.get());
pinchSequence.press(0, p0, window).commit();
QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
@@ -876,7 +999,7 @@ void tst_QQuickPinchHandler::cancel()
QSKIP("cancel is not supported atm");
- QTouchEvent cancelEvent(QEvent::TouchCancel, touchscreen);
+ QTouchEvent cancelEvent(QEvent::TouchCancel, touchscreen.get());
QCoreApplication::sendEvent(window, &cancelEvent);
QQuickTouchUtils::flush(window);
@@ -932,7 +1055,7 @@ void tst_QQuickPinchHandler::transformedpinchHandler()
const int threshold = qApp->styleHints()->startDragDistance();
{
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, touchscreen);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, touchscreen.get());
// start pinchHandler
pinchSequence.press(0, p0, view).commit();
QQuickTouchUtils::flush(view);
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt
index da110a6398..e15b802814 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickpointerhandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickpointerhandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml
new file mode 100644
index 0000000000..7bc3907c8c
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml
@@ -0,0 +1,36 @@
+import QtQuick
+import Qt.test 1.0
+
+Item {
+ width: 200
+ height: 200
+
+ Rectangle {
+ id: circle
+ y: 0
+ width: 100
+ height: width
+ radius: width/2
+ color: "#3e1"
+ clip: true
+
+ // Rectangle contains() is not affected by its 'radius' property
+ containmentMask: QtObject {
+ property alias radius: circle.radius
+ function contains(point: point) : bool {
+ return (Math.pow(point.x - radius, 2) + Math.pow(point.y - radius, 2)) < Math.pow(radius, 2)
+ }
+ }
+ EventHandler {
+ objectName: "circle eventHandler"
+ }
+ Rectangle {
+ width: circle.width/2
+ height: width
+ color: "red"
+ EventHandler {
+ objectName: "eventHandler"
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/grabberSceneChange.qml b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/grabberSceneChange.qml
new file mode 100644
index 0000000000..7bc6028bc2
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/grabberSceneChange.qml
@@ -0,0 +1,78 @@
+import QtQuick
+
+Window {
+ id: root
+ visible: true
+ objectName: "root"
+ width: 320
+ height: 480
+
+ property bool useTimer : false
+ property int grabChangedCounter : 0
+
+ Item {
+ id: back
+ anchors.fill: parent
+
+ Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "blue"
+ }
+
+ Rectangle {
+ id: container
+ objectName: "container"
+ anchors.fill: parent
+ anchors.margins: 50
+ z: 2
+
+ Rectangle {
+ id: likeButton
+ color: "gray"
+ anchors.centerIn: parent
+ width: 200
+ height: 200
+
+ DragHandler {
+ id: handler
+ objectName: "dragHandler"
+ grabPermissions: PointerHandler.CanTakeOverFromItems
+ onGrabChanged: {
+ ++grabChangedCounter
+ }
+ }
+ }
+ }
+
+ Timer {
+ id: reparentTimer
+ running: false
+ interval: 100
+ repeat: false
+ onTriggered: {
+ container.parent = null
+ }
+ }
+
+ Rectangle {
+ id: likeButton2
+ color: "yellow"
+ anchors.centerIn: parent
+ width: 100
+ height: 100
+ z: 3
+
+ MultiPointTouchArea {
+ id: press
+ anchors.fill: parent
+ onPressed: {
+ if (useTimer)
+ reparentTimer.running = true
+ else
+ container.parent = null
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
index aa89ad0631..1120cb54c2 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -162,6 +162,7 @@ public:
class EventHandler : public QQuickPointerHandler
{
+ Q_OBJECT
public:
EventHandler(QQuickItem *parent = nullptr) :
QQuickPointerHandler(parent) {}
@@ -231,6 +232,9 @@ private slots:
void dynamicCreationInWindow();
void cppConstruction();
void reparenting();
+ void grabberSceneChange_data();
+ void grabberSceneChange();
+ void clip();
protected:
bool eventFilter(QObject *, QEvent *event) override
@@ -749,6 +753,112 @@ void tst_PointerHandlers::reparenting()
}
}
+/*!
+ Verify that removing an item that has a grabbing handler from the scene
+ does not result in crashes in our event dispatching code. The item's window()
+ pointer will be nullptr, so the handler must have released the grab, or never
+ gotten the grab, depending on when the item gets removed.
+
+ See QTBUG-114475.
+*/
+void tst_PointerHandlers::grabberSceneChange_data()
+{
+ QTest::addColumn<bool>("useTimer");
+ QTest::addColumn<int>("grabChangedCount");
+
+ QTest::addRow("Immediately") << false << 0;
+ QTest::addRow("Delayed") << true << 2;
+}
+
+void tst_PointerHandlers::grabberSceneChange()
+{
+ QFETCH(const bool, useTimer);
+ QFETCH(const int, grabChangedCount);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("grabberSceneChange.qml"));
+ QQuickWindow *window = qobject_cast<QQuickWindow*>(component.create());
+ QScopedPointer<QQuickWindow> cleanup(window);
+ QVERIFY(window);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ window->setProperty("useTimer", useTimer);
+
+ QQuickItem *container = window->findChild<QQuickItem *>("container");
+
+ QPoint p1 = QPoint(window->width() / 2, window->height() / 2);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ // The container gets removed from this window, either immediately on
+ // press, or through a timer.
+ QTRY_COMPARE(container->parentItem(), nullptr);
+
+ QEXPECT_FAIL("Delayed",
+ "PointerHandlers don't release their grab when item is removed", Continue);
+ QCOMPARE(window->property("grabChangedCounter").toInt(), grabChangedCount);
+
+ // this should not crash
+ QTest::mouseMove(window, p1 + QPoint(5, 5));
+}
+
+void tst_PointerHandlers::clip()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "clip.qml");
+ QQuickView * window = windowPtr.data();
+ QVERIFY(window);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ EventHandler *handler = window->contentItem()->findChild<EventHandler*>("eventHandler");
+ EventHandler *circleHandler = window->contentItem()->findChild<EventHandler*>("circle eventHandler");
+
+ QCOMPARE(handler->pressEventCount, 0);
+ QCOMPARE(circleHandler->pressEventCount, 0);
+ QCOMPARE(handler->releaseEventCount, 0);
+ QCOMPARE(circleHandler->releaseEventCount, 0);
+
+ const QPoint rectPt = QPoint(1, 1);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rectPt);
+ QCOMPARE(handler->pressEventCount, 1);
+ QCOMPARE(circleHandler->pressEventCount, 0);
+
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rectPt);
+ QCOMPARE(handler->releaseEventCount, 1);
+ QCOMPARE(circleHandler->releaseEventCount, 0);
+
+
+ handler->pressEventCount = 0;
+ circleHandler->pressEventCount = 0;
+ handler->releaseEventCount = 0;
+ circleHandler->releaseEventCount = 0;
+
+ const QPoint rectAndCirclePt = QPoint(49 ,49);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rectAndCirclePt);
+ QCOMPARE(handler->pressEventCount, 1);
+ QCOMPARE(circleHandler->pressEventCount, 1);
+
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rectAndCirclePt);
+ QCOMPARE(handler->releaseEventCount, 1);
+ QCOMPARE(circleHandler->releaseEventCount, 1);
+
+
+ handler->pressEventCount = 0;
+ circleHandler->pressEventCount = 0;
+ handler->releaseEventCount = 0;
+ circleHandler->releaseEventCount = 0;
+
+ const QPoint circlePt = QPoint(51 ,51);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, circlePt);
+ QCOMPARE(handler->pressEventCount, 0);
+ QCOMPARE(circleHandler->pressEventCount, 1);
+
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, circlePt);
+ QCOMPARE(handler->releaseEventCount, 0);
+ QCOMPARE(circleHandler->releaseEventCount, 1);
+}
+
QTEST_MAIN(tst_PointerHandlers)
#include "tst_qquickpointerhandler.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt
index 969df8a4ce..aa73218361 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickpointhandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickpointhandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/data/multiPointTracker.qml b/tests/auto/quick/pointerhandlers/qquickpointhandler/data/multiPointTracker.qml
index d813160f44..616d526592 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/data/multiPointTracker.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/data/multiPointTracker.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/data/pointTracker.qml b/tests/auto/quick/pointerhandlers/qquickpointhandler/data/pointTracker.qml
index 54d7ff7212..2de03703e8 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/data/pointTracker.qml
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/data/pointTracker.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
index 4435580d92..e1641c282e 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -18,6 +18,8 @@
#include <QtQuickTestUtils/private/viewtestutils_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
+#include <QtCore/qpointer.h>
+
Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
class tst_PointHandler : public QQmlDataTest
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST
index d13d25390b..1559014480 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/BLACKLIST
@@ -1,11 +1,3 @@
-# QTBUG-95939
-[touchGesturePolicyDragThreshold]
-opensuse-leap
-
-# QTBUG-95939
-[mouseGesturePolicyDragThreshold]
-opensuse-leap
-
# QTBUG-103072
[gesturePolicyDragWithinBounds]
android
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt
index cab8fc1a0d..94834e04c6 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquicktaphandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquicktaphandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml
index fa58d76e4a..fc1e623902 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
@@ -10,13 +10,20 @@ Rectangle {
property alias pressed: tap.pressed
property bool checked: false
property alias gesturePolicy: tap.gesturePolicy
+ property alias longPressThreshold: tap.longPressThreshold
property point tappedPosition: Qt.point(0, 0)
+ property real timeHeldWhenTapped: 0
+ property real timeHeldWhenLongPressed: 0
signal tapped
signal canceled
width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0
border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true
+ function assignUndefinedLongPressThreshold() {
+ tap.longPressThreshold = undefined
+ }
+
gradient: Gradient {
GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" }
GradientStop { position: 1.0; color: "#b8b5b2" }
@@ -25,14 +32,17 @@ Rectangle {
TapHandler {
id: tap
objectName: label.text
- longPressThreshold: 100 // CI can be insanely slow, so don't demand a timely release to generate onTapped
onSingleTapped: console.log("Single tap")
onDoubleTapped: console.log("Double tap")
- onTapped: {
- console.log("Tapped")
+ onTapped: (eventPoint, button) => {
+ console.log("Tapped", button, eventPoint)
tapFlash.start()
root.tappedPosition = point.scenePosition
root.tapped()
+ root.timeHeldWhenTapped = tap.timeHeld // eventPoint.timeHeld is already 0
+ }
+ onLongPressed: {
+ root.timeHeldWhenLongPressed = tap.timeHeld
}
onCanceled: root.canceled()
}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml
index e3f15f399f..9483a12d1c 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.0
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml
index c5f2f6e1ae..b36fcdef08 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml
index 5731f51f38..04fbbc176b 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
@@ -9,19 +9,25 @@ Item {
Button {
objectName: "DragThreshold"
label: "DragThreshold"
- x: 10; y: 10; width: parent.width - 20; height: 40
+ x: 10; y: 10; width: 300; height: 40
gesturePolicy: TapHandler.DragThreshold
}
Button {
objectName: "WithinBounds"
label: "WithinBounds"
- x: 10; y: 60; width: parent.width - 20; height: 40
+ x: 10; y: 60; width: 300; height: 40
gesturePolicy: TapHandler.WithinBounds
}
Button {
objectName: "ReleaseWithinBounds"
label: "ReleaseWithinBounds"
- x: 10; y: 110; width: parent.width - 20; height: 40
+ x: 10; y: 110; width: 300; height: 40
gesturePolicy: TapHandler.ReleaseWithinBounds
}
+ Button {
+ objectName: "DragWithinBounds"
+ label: "DragWithinBounds"
+ x: 10; y: 160; width: 300; height: 40
+ gesturePolicy: TapHandler.DragWithinBounds
+ }
}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/dragReleaseMenu.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/dragReleaseMenu.qml
index 1f819a937f..5f60ef879e 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/dragReleaseMenu.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/dragReleaseMenu.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nested.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nested.qml
index f9db2d7179..c0f0b10bf4 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nested.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nested.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
Item {
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nestedAndSibling.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nestedAndSibling.qml
new file mode 100644
index 0000000000..7732c42082
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/nestedAndSibling.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+import QtQuick.Controls 2.15
+
+Item {
+ width: 360
+ height: 280
+
+ Rectangle {
+ width: 200; height: 200; x: 100; y: 10
+ color: th1.pressed ? "blue" : "lightblue"
+
+ TapHandler {
+ id: th1
+ objectName: "th1"
+ }
+
+ Rectangle {
+ width: 200; height: 200; x: 50; y: 50
+ color: th2.pressed ? "steelblue" : "lightsteelblue"
+
+ TapHandler {
+ id: th2
+ objectName: "th2"
+ }
+ }
+ }
+
+ Rectangle {
+ width: 200; height: 200; x: 10; y: 50
+ color: th3.pressed ? "goldenrod" : "beige"
+
+ TapHandler {
+ id: th3
+ objectName: "th3"
+ }
+ }
+}
+
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/rightTapHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/rightTapHandler.qml
index 3517afe9c3..85f5c87b39 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/rightTapHandler.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/rightTapHandler.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
index 54adc87c54..026be48f83 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.12
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
index f000d48171..1dab0836cd 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -44,10 +44,12 @@ private slots:
void touchMultiTap();
void mouseMultiTap_data();
void mouseMultiTap();
+ void mouseMultiTapLeftRight_data();
+ void mouseMultiTapLeftRight();
void singleTapDoubleTap_data();
void singleTapDoubleTap();
- void touchLongPress();
- void mouseLongPress();
+ void longPress_data();
+ void longPress();
void buttonsMultiTouch();
void componentUserBehavioralOverride();
void rightLongPressIgnoreWheel();
@@ -55,6 +57,8 @@ private slots:
void nonTopLevelParentWindow();
void nestedDoubleTap_data();
void nestedDoubleTap();
+ void nestedAndSiblingPropagation_data();
+ void nestedAndSiblingPropagation();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName,
@@ -507,6 +511,23 @@ void tst_TapHandler::touchMultiTap()
QQuickTouchUtils::flush(window);
QTRY_VERIFY(!button->property("pressed").toBool());
QCOMPARE(tappedSpy.size(), 4);
+
+ // Test a stray touch begin
+ tappedSpy.clear();
+ constexpr int count = 2;
+ for (int i = 0; i < count; ++i) {
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 -= QPoint(dragThreshold, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ }
+ QCOMPARE(tappedSpy.count(), count);
}
void tst_TapHandler::mouseMultiTap_data()
@@ -592,6 +613,66 @@ void tst_TapHandler::mouseMultiTap()
QCOMPARE(singleTapSpy.size(), expectedSingleTapsAfterWaiting);
}
+void tst_TapHandler::mouseMultiTapLeftRight_data()
+{
+ QTest::addColumn<QQuickTapHandler::ExclusiveSignals>("exclusiveSignals");
+ QTest::addColumn<int>("expectedSingleTaps");
+ QTest::addColumn<int>("expectedDoubleTaps");
+ QTest::addColumn<int>("expectedTabCount2");
+ QTest::addColumn<int>("expectedTabCount3");
+
+ QTest::newRow("NotExclusive") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::NotExclusive)
+ << 3 << 0 << 1 << 1;
+ QTest::newRow("SingleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::SingleTap)
+ << 3 << 0 << 1 << 1;
+ QTest::newRow("DoubleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::DoubleTap)
+ << 0 << 0 << 1 << 1;
+ QTest::newRow("SingleTap|DoubleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::SingleTap | QQuickTapHandler::DoubleTap)
+ << 0 << 0 << 1 << 1;
+}
+
+void tst_TapHandler::mouseMultiTapLeftRight() //QTBUG-111557
+{
+ QFETCH(QQuickTapHandler::ExclusiveSignals, exclusiveSignals);
+ QFETCH(int, expectedSingleTaps);
+ QFETCH(int, expectedDoubleTaps);
+ QFETCH(int, expectedTabCount2);
+ QFETCH(int, expectedTabCount3);
+
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(button);
+ QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>();
+ QVERIFY(tapHandler);
+ tapHandler->setExclusiveSignals(exclusiveSignals);
+ tapHandler->setAcceptedButtons(Qt::LeftButton | Qt::RightButton);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+ QSignalSpy singleTapSpy(tapHandler, &QQuickTapHandler::singleTapped);
+ QSignalSpy doubleTapSpy(tapHandler, &QQuickTapHandler::doubleTapped);
+
+ // Click once with the left button
+ QPoint p1 = button->mapToScene(QPointF(2, 2)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
+
+ // Click again with the right button -> should reset tabCount()
+ QTest::mousePress(window, Qt::RightButton, Qt::NoModifier, p1, 10);
+ QTest::mouseRelease(window, Qt::RightButton, Qt::NoModifier, p1, 10);
+
+ QCOMPARE(tapHandler->tapCount(), expectedTabCount2);
+
+ // Click again with the left button -> should reset tabCount()
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
+
+ QCOMPARE(tapHandler->tapCount(), expectedTabCount3);
+ QCOMPARE(singleTapSpy.size(), expectedSingleTaps);
+ QCOMPARE(doubleTapSpy.size(), expectedDoubleTaps);
+}
+
void tst_TapHandler::singleTapDoubleTap_data()
{
QTest::addColumn<QPointingDevice::DeviceType>("deviceType");
@@ -653,12 +734,13 @@ void tst_TapHandler::singleTapDoubleTap()
QSignalSpy singleTapSpy(tapHandler, &QQuickTapHandler::singleTapped);
QSignalSpy doubleTapSpy(tapHandler, &QQuickTapHandler::doubleTapped);
- auto tap = [window, tapHandler, deviceType, this](const QPoint &p1) {
+ auto tap = [window, tapHandler, deviceType, this](const QPoint &p1, int delay = 10) {
switch (static_cast<QPointingDevice::DeviceType>(deviceType)) {
case QPointingDevice::DeviceType::Mouse:
- QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, p1, delay);
break;
case QPointingDevice::DeviceType::TouchScreen:
+ QTest::qWait(delay);
QTest::touchEvent(window, touchDevice).press(0, p1, window);
QTRY_VERIFY(tapHandler->isPressed());
QTest::touchEvent(window, touchDevice).release(0, p1, window);
@@ -679,78 +761,211 @@ void tst_TapHandler::singleTapDoubleTap()
QTRY_COMPARE(doubleTapSpy.size(), expectedDoubleTapCount);
QCOMPARE(tappedSpy.size(), 2);
QCOMPARE(singleTapSpy.size(), expectedEndingSingleTapCount);
-}
-void tst_TapHandler::touchLongPress()
-{
- QScopedPointer<QQuickView> windowPtr;
- createView(windowPtr, "buttons.qml");
- QQuickView * window = windowPtr.data();
+ // wait past the double-tap interval, then do it again
+ const auto delay = qApp->styleHints()->mouseDoubleClickInterval() + 10;
+ tappedSpy.clear();
+ singleTapSpy.clear();
+ doubleTapSpy.clear();
- QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
- QVERIFY(button);
- QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
- QVERIFY(tapHandler);
- QSignalSpy tappedSpy(button, SIGNAL(tapped()));
- QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
- QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
- QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
+ // tap once with delay
+ tap(p1, delay);
+ QCOMPARE(tappedSpy.size(), 1);
+ QCOMPARE(doubleTapSpy.size(), 0);
- // Reduce the threshold so that we can get a long press quickly
- tapHandler->setLongPressThreshold(0.5);
- QCOMPARE(longPressThresholdChangedSpy.size(), 1);
+ // tap again immediately afterwards
+ tap(p1);
+ QTRY_COMPARE(doubleTapSpy.size(), expectedDoubleTapCount);
+ QCOMPARE(tappedSpy.size(), 2);
+ QCOMPARE(singleTapSpy.size(), expectedEndingSingleTapCount);
+}
- // Press and hold
- QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
- QTest::touchEvent(window, touchDevice).press(1, p1, window);
- QQuickTouchUtils::flush(window);
- QTRY_VERIFY(button->property("pressed").toBool());
- QTRY_COMPARE(longPressedSpy.size(), 1);
- timeHeldSpy.wait(); // the longer we hold it, the more this will occur
- qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.size() << "times";
- QVERIFY(timeHeldSpy.size() > 0);
- QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
+void tst_TapHandler::longPress_data()
+{
+ QTest::addColumn<const QPointingDevice *>("device");
+ QTest::addColumn<QString>("buttonName");
+ QTest::addColumn<qreal>("longPressThreshold");
+ QTest::addColumn<QPoint>("releaseOffset");
+ QTest::addColumn<bool>("expectLongPress");
+ QTest::addColumn<bool>("expectTapped");
- // Release and verify that tapped was not emitted
- QTest::touchEvent(window, touchDevice).release(1, p1, window);
- QQuickTouchUtils::flush(window);
- QTRY_VERIFY(!button->property("pressed").toBool());
- QCOMPARE(tappedSpy.size(), 0);
+ const QPointingDevice *constTouchDevice = touchDevice;
+
+ // Reduce the threshold so that we can get a long press quickly (faster in CI)
+ const qreal longPressThreshold = 0.3;
+ QTest::newRow("mouse, lpt longPressThreshold: DragThreshold")
+ << QPointingDevice::primaryPointingDevice() << "DragThreshold"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: DragThreshold")
+ << constTouchDevice << "DragThreshold" << longPressThreshold
+ << QPoint(0, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: DragThreshold, drag")
+ << QPointingDevice::primaryPointingDevice() << "DragThreshold"
+ << longPressThreshold << QPoint(50, 0) << false << false;
+ QTest::newRow("touch, lpt longPressThreshold: DragThreshold, drag")
+ << constTouchDevice << "DragThreshold"
+ << longPressThreshold << QPoint(50, 0) << false << false;
+
+ QTest::newRow("mouse, lpt longPressThreshold: WithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "WithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: WithinBounds")
+ << constTouchDevice << "WithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: WithinBounds, drag")
+ << QPointingDevice::primaryPointingDevice() << "WithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: WithinBounds, drag")
+ << constTouchDevice << "WithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: WithinBounds, drag out")
+ << QPointingDevice::primaryPointingDevice() << "WithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+ QTest::newRow("touch, lpt longPressThreshold: WithinBounds, drag out")
+ << constTouchDevice << "WithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+
+ QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds")
+ << constTouchDevice << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds, drag")
+ << QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds, drag")
+ << constTouchDevice << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds, drag out")
+ << QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+ QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds, drag out")
+ << constTouchDevice << "ReleaseWithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+
+ QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds")
+ << constTouchDevice << "DragWithinBounds"
+ << longPressThreshold << QPoint(0, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds, drag")
+ << QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds, drag")
+ << constTouchDevice << "DragWithinBounds"
+ << longPressThreshold << QPoint(50, 0) << true << false;
+ QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds, drag out")
+ << QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+ QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds, drag out")
+ << constTouchDevice << "DragWithinBounds"
+ << longPressThreshold << QPoint(155, 0) << false << false;
+
+ // Zero or negative threshold means long press is disabled
+ QTest::newRow("mouse, lpt 0: DragThreshold")
+ << QPointingDevice::primaryPointingDevice() << "DragThreshold"
+ << qreal(0) << QPoint(0, 0) << false << true;
+ QTest::newRow("mouse, lpt -1: DragThreshold")
+ << QPointingDevice::primaryPointingDevice() << "DragThreshold"
+ << qreal(-1) << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt 0: DragThreshold")
+ << constTouchDevice << "DragThreshold"
+ << qreal(0) << QPoint(0, 0) << false << true;
+
+ QTest::newRow("mouse, lpt 0: WithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "WithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
+ QTest::newRow("mouse, lpt -1: WithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "WithinBounds"
+ << qreal(-1) << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt 0: WithinBounds")
+ << constTouchDevice << "WithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
+
+ QTest::newRow("mouse, lpt 0: ReleaseWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
+ QTest::newRow("mouse, lpt -1: ReleaseWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
+ << qreal(-1) << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt 0: ReleaseWithinBounds")
+ << constTouchDevice << "ReleaseWithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
+
+ QTest::newRow("mouse, lpt 0: DragWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
+ QTest::newRow("mouse, lpt -1: DragWithinBounds")
+ << QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
+ << qreal(-1) << QPoint(0, 0) << true << false;
+ QTest::newRow("touch, lpt 0: DragWithinBounds")
+ << constTouchDevice << "DragWithinBounds"
+ << qreal(0) << QPoint(0, 0) << false << true;
}
-void tst_TapHandler::mouseLongPress()
+void tst_TapHandler::longPress()
{
- QScopedPointer<QQuickView> windowPtr;
- createView(windowPtr, "buttons.qml");
- QQuickView * window = windowPtr.data();
+ QFETCH(const QPointingDevice *, device);
+ QFETCH(QString, buttonName);
+ QFETCH(qreal, longPressThreshold);
+ QFETCH(QPoint, releaseOffset);
+ QFETCH(bool, expectLongPress);
+ QFETCH(bool, expectTapped);
- QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("buttons.qml")));
+
+ QQuickItem *button = window.rootObject()->findChild<QQuickItem*>(buttonName);
QVERIFY(button);
- QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
+ QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>(buttonName);
QVERIFY(tapHandler);
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
- // Reduce the threshold so that we can get a long press quickly
- tapHandler->setLongPressThreshold(0.5);
- QCOMPARE(longPressThresholdChangedSpy.size(), 1);
+ const qreal defaultThreshold = tapHandler->longPressThreshold();
+ qsizetype changedCount = 0;
+ QCOMPARE_GT(defaultThreshold, 0);
+ tapHandler->setLongPressThreshold(longPressThreshold);
+ if (longPressThreshold > 0)
+ QCOMPARE(longPressThresholdChangedSpy.size(), ++changedCount);
+ QVERIFY(QMetaObject::invokeMethod(button, "assignUndefinedLongPressThreshold"));
+ if (longPressThreshold > 0)
+ QCOMPARE(longPressThresholdChangedSpy.size(), ++changedCount);
+ QCOMPARE(tapHandler->longPressThreshold(), defaultThreshold);
+ tapHandler->setLongPressThreshold(longPressThreshold);
// Press and hold
QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QQuickTest::pointerPress(device, &window, 1, p1);
QTRY_VERIFY(button->property("pressed").toBool());
- QTRY_COMPARE(longPressedSpy.size(), 1);
+ QTRY_COMPARE(longPressedSpy.size(), expectLongPress ? 1 : 0);
timeHeldSpy.wait(); // the longer we hold it, the more this will occur
qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.size() << "times";
- QVERIFY(timeHeldSpy.size() > 0);
- QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
+ QCOMPARE_GT(timeHeldSpy.size(), 0);
+ if (expectLongPress) {
+ // Should be > longPressThreshold but slow CI and timer granularity can interfere
+ QCOMPARE_GT(tapHandler->timeHeld(), longPressThreshold - 0.1);
+ } else {
+ // Should be quite small, but event delivery is not instantaneous
+ QCOMPARE_LT(tapHandler->timeHeld(), 0.3);
+ }
+
+ // If we have an offset, we need a move between press and release for realistic simulation
+ if (!releaseOffset.isNull())
+ QQuickTest::pointerMove(device, &window, 1, p1 + releaseOffset);
- // Release and verify that tapped was not emitted
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 500);
+ // Release (optionally at an offset) and check whether tapped was emitted
+ QQuickTest::pointerRelease(device, &window, 1, p1 + releaseOffset);
QTRY_VERIFY(!button->property("pressed").toBool());
- QCOMPARE(tappedSpy.size(), 0);
+ if (expectLongPress)
+ QCOMPARE_GT(button->property("timeHeldWhenLongPressed").toReal(), longPressThreshold - 0.1);
+ QCOMPARE(tapHandler->timeHeld(), -1);
+ QCOMPARE(tappedSpy.size(), expectTapped ? 1 : 0);
+ QCOMPARE(longPressedSpy.size(), expectLongPress ? 1 : 0);
}
void tst_TapHandler::buttonsMultiTouch()
@@ -866,8 +1081,8 @@ void tst_TapHandler::componentUserBehavioralOverride()
QQuickTapHandler *userTapHandler = button->findChild<QQuickTapHandler*>("override");
QVERIFY(userTapHandler);
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
- QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
- QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
+ QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition,QEventPoint)));
+ QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition,QEventPoint)));
QSignalSpy innerPressedChangedSpy(innerTapHandler, SIGNAL(pressedChanged()));
QSignalSpy userPressedChangedSpy(userTapHandler, SIGNAL(pressedChanged()));
@@ -1019,6 +1234,61 @@ void tst_TapHandler::nestedDoubleTap() // QTBUG-102625
childGesturePolicy == QQuickTapHandler::GesturePolicy::DragThreshold ? 4 : 2);
}
+void tst_TapHandler::nestedAndSiblingPropagation_data()
+{
+ QTest::addColumn<const QPointingDevice *>("device");
+ QTest::addColumn<QQuickTapHandler::GesturePolicy>("gesturePolicy");
+ QTest::addColumn<bool>("expectPropagation");
+
+ const QPointingDevice *constTouchDevice = touchDevice;
+
+ QTest::newRow("primary, DragThreshold") << QPointingDevice::primaryPointingDevice()
+ << QQuickTapHandler::GesturePolicy::DragThreshold << true;
+ QTest::newRow("primary, WithinBounds") << QPointingDevice::primaryPointingDevice()
+ << QQuickTapHandler::GesturePolicy::WithinBounds << false;
+ QTest::newRow("primary, ReleaseWithinBounds") << QPointingDevice::primaryPointingDevice()
+ << QQuickTapHandler::GesturePolicy::ReleaseWithinBounds << false;
+ QTest::newRow("primary, DragWithinBounds") << QPointingDevice::primaryPointingDevice()
+ << QQuickTapHandler::GesturePolicy::DragWithinBounds << false;
+
+ QTest::newRow("touch, DragThreshold") << constTouchDevice
+ << QQuickTapHandler::GesturePolicy::DragThreshold << true;
+ QTest::newRow("touch, WithinBounds") << constTouchDevice
+ << QQuickTapHandler::GesturePolicy::WithinBounds << false;
+ QTest::newRow("touch, ReleaseWithinBounds") << constTouchDevice
+ << QQuickTapHandler::GesturePolicy::ReleaseWithinBounds << false;
+ QTest::newRow("touch, DragWithinBounds") << constTouchDevice
+ << QQuickTapHandler::GesturePolicy::DragWithinBounds << false;
+}
+
+void tst_TapHandler::nestedAndSiblingPropagation() // QTBUG-117387
+{
+ QFETCH(const QPointingDevice *, device);
+ QFETCH(QQuickTapHandler::GesturePolicy, gesturePolicy);
+ QFETCH(bool, expectPropagation);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl("nestedAndSibling.qml")));
+ QQuickItem *root = window.rootObject();
+ QQuickTapHandler *th1 = root->findChild<QQuickTapHandler*>("th1");
+ QVERIFY(th1);
+ th1->setGesturePolicy(gesturePolicy);
+ QQuickTapHandler *th2 = root->findChild<QQuickTapHandler*>("th2");
+ QVERIFY(th2);
+ th2->setGesturePolicy(gesturePolicy);
+ QQuickTapHandler *th3 = root->findChild<QQuickTapHandler*>("th3");
+ QVERIFY(th3);
+ th3->setGesturePolicy(gesturePolicy);
+
+ QPoint middle(180, 140);
+ QQuickTest::pointerPress(device, &window, 0, middle);
+ QVERIFY(th3->isPressed()); // it's on top
+ QCOMPARE(th2->isPressed(), expectPropagation);
+ QCOMPARE(th1->isPressed(), expectPropagation);
+
+ QQuickTest::pointerRelease(device, &window, 0, middle);
+}
+
QTEST_MAIN(tst_TapHandler)
#include "tst_qquicktaphandler.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt
index b5cfe1fa5a..d50181dfe4 100644
--- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt
+++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qquickwheelhandler Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qquickwheelhandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/nested.qml b/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/nested.qml
index d50f6ac005..9c43df46da 100644
--- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/nested.qml
+++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/nested.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.14
diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/rectWheel.qml b/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/rectWheel.qml
index c0c5e776e9..ca6053ebcf 100644
--- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/rectWheel.qml
+++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/data/rectWheel.qml
@@ -1,5 +1,5 @@
// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 2.14
@@ -14,7 +14,23 @@ Rectangle {
}
}
+ Rectangle {
+ color: "red"
+ width: 6; height: 6; radius: 3
+ x: wheelHandler.point.position.x - radius
+ y: wheelHandler.point.position.y - radius
+ }
+
+ Text {
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: 20
+ color: "white"
+ font.pixelSize: 18
+ text: parent.x.toFixed(2) + ", " + parent.y.toFixed(2)
+ }
+
WheelHandler {
+ id: wheelHandler
activeTimeout: 0.5
}
}
diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp b/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp
index d87acc3200..c88b1af2ea 100644
--- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
#include <QtTest/QSignalSpy>