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/qquickdraghandler/data/dragAndWheel.qml32
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml34
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp127
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml39
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp55
6 files changed, 288 insertions, 3 deletions
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragAndWheel.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragAndWheel.qml
new file mode 100644
index 0000000000..811326aaba
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragAndWheel.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+
+ property bool gotWheel: false
+ property int changeCount: 0
+ property alias wheelHandlerEnabled: wheelHandler.enabled
+
+ width: 640
+ height: 480
+
+ Rectangle {
+ color: "blue"
+ width: 200
+ height: 200
+
+ DragHandler {
+ id: dragHandler
+ }
+
+ WheelHandler {
+ id: wheelHandler
+
+ enabled: !dragHandler.active
+ onEnabledChanged: root.changeCount++
+ onWheel: root.gotWheel = true
+ }
+
+ }
+
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml
new file mode 100644
index 0000000000..b24812c914
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.15
+
+import Test 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ anchors.fill: parent
+ color: "grey"
+
+ Rectangle {
+ x: 200
+ y: 200
+ width: 100
+ height: 100
+ color: "orange"
+ DragHandler {
+ grabPermissions: DragHandler.CanTakeOverFromAnything // but not anything with keepMouseGrab!
+ }
+ }
+ }
+
+ ModalLayer {
+ anchors.fill: parent
+
+ Rectangle {
+ anchors.fill: parent
+ color: "red"
+ opacity: 0.4
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 9c9ca2fe00..2cb26124ae 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -69,8 +69,11 @@ private slots:
void touchPassiveGrabbers_data();
void touchPassiveGrabbers();
void touchPinchAndMouseMove();
+ void unsuitableEventDuringDrag();
+ void underModalLayer();
private:
+ void sendWheelEvent(QQuickView &window, QPoint pos, QPoint angleDelta, QPoint pixelDelta, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, bool inverted);
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
QSet<QQuickPointerHandler *> passiveGrabbers(QQuickWindow *window, int pointId = 0);
QPointingDevice *touchDevice;
@@ -821,6 +824,130 @@ void tst_DragHandler::touchPinchAndMouseMove()
}
}
+void tst_DragHandler::unsuitableEventDuringDrag()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "dragAndWheel.qml");
+ QQuickView *window = windowPtr.data();
+ auto root = window->rootObject();
+ QQmlProperty changeCount(root, "changeCount");
+ QQmlProperty wheelHandlerEnabled(root, "wheelHandlerEnabled");
+ bool ok = false;
+ QCOMPARE(changeCount.read().toInt(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(wheelHandlerEnabled.read().toBool(), true);
+
+ QPoint p1(100, 100);
+ QPoint p2(150, 150);
+
+ QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice);
+ // When we start dragging...
+ touch.press(3,p1).commit();
+ touch.move(3, p2).commit();
+ QQuickTouchUtils::flush(window);
+ // the DragHandler becomes active
+ ok = false;
+ QCOMPARE(changeCount.read().toInt(&ok), 1);
+ QVERIFY(ok);
+ QCOMPARE(wheelHandlerEnabled.read().toBool(), false);
+
+ // When a scroll event arrives while we are dragging
+ sendWheelEvent(*window, p2, QPoint(160, 120), QPoint(-360, 120), Qt::NoModifier, Qt::ScrollBegin, false);
+ // nothing changes because the DragHandler is still active, and the wheel handler stays disabled
+ ok = false;
+ QCOMPARE(changeCount.read().toInt(&ok), 1);
+ QVERIFY(ok);
+ QCOMPARE(wheelHandlerEnabled.read().toBool(), false);
+
+ // When we stop dragging...
+ touch.release(3, p2).commit();
+ QQuickTouchUtils::flush(window);
+
+ // the wheel handler becomes active again
+ ok = false;
+ QCOMPARE(changeCount.read().toInt(&ok), 2);
+ QVERIFY(ok);
+ QCOMPARE(wheelHandlerEnabled.read().toBool(), true);
+
+ // During the whole sequence the wheel handler never got a wheel event
+ // as it was disabled:
+ QQmlProperty gotWheel(root, "gotWheel");
+ QVERIFY(!gotWheel.read().toBool());
+
+ // If the WheelHandler is unconditionally enabled...
+ wheelHandlerEnabled.write(true);
+ // it receives scroll events during drags.
+ touch.press(4,p2).commit();
+ touch.move(4, p1).commit();
+ QQuickTouchUtils::flush(window);
+ sendWheelEvent(*window, p2, QPoint(160, 120), QPoint(-360, 120), Qt::NoModifier, Qt::ScrollBegin, false);
+ touch.release(4, p2).commit();
+ QQuickTouchUtils::flush(window);
+ QVERIFY(gotWheel.read().toBool());
+}
+
+void tst_DragHandler::sendWheelEvent(QQuickView &window, QPoint pos, QPoint angleDelta, QPoint pixelDelta, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, bool inverted)
+{
+ QWheelEvent wheelEvent(pos, window.mapToGlobal(pos), pixelDelta, angleDelta,
+ Qt::NoButton, modifiers, phase, inverted);
+ QGuiApplication::sendEvent(&window, &wheelEvent);
+ qApp->processEvents();
+ QQuickTouchUtils::flush(&window);
+}
+
+class ModalLayer : public QQuickItem {
+public:
+ explicit ModalLayer(QQuickItem* parent = nullptr) : QQuickItem(parent) {
+ this->setAcceptedMouseButtons(Qt::AllButtons);
+ this->setAcceptTouchEvents(true);
+ this->setKeepMouseGrab(true);
+ this->setKeepTouchGrab(true);
+ }
+
+ bool event(QEvent* event) override {
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseTrackingChange:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchCancel:
+ case QEvent::TouchEnd: {
+ qCDebug(lcPointerTests) << "BLOCK!" << event->type();
+ return true;
+ }
+ default: break;
+ }
+ return QQuickItem::event(event);
+ }
+};
+
+void tst_DragHandler::underModalLayer() // QTBUG-78258
+{
+ qmlRegisterType<ModalLayer>("Test", 1, 0, "ModalLayer");
+
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "dragHandlerUnderModalLayer.qml");
+ QQuickView * window = windowPtr.data();
+ QPointer<QQuickDragHandler> dragHandler = window->rootObject()->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QPoint p1(250, 250);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!dragHandler->active());
+ QTest::mouseRelease(window, Qt::LeftButton);
+}
+
QTEST_MAIN(tst_DragHandler)
#include "tst_qquickdraghandler.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
index 6df672e4e8..0d29ae6516 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
@@ -211,6 +211,7 @@ void tst_QQuickPinchHandler::scale()
QQuickPinchHandler *pinchHandler = window->rootObject()->findChild<QQuickPinchHandler*>("pinchHandler");
QVERIFY(pinchHandler != nullptr);
+ QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
QVERIFY(root != nullptr);
@@ -232,6 +233,7 @@ void tst_QQuickPinchHandler::scale()
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(grabChangedSpy.count(), 1); // passive grab
QPoint pd(10, 10);
// move one point until PinchHandler activates
@@ -241,6 +243,8 @@ void tst_QQuickPinchHandler::scale()
QQuickTouchUtils::flush(window);
}
QCOMPARE(pinchHandler->active(), true);
+ // first point got a passive grab; both points got exclusive grabs
+ QCOMPARE(grabChangedSpy.count(), 3);
QLineF line(p0, p1);
const qreal startLength = line.length();
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
new file mode 100644
index 0000000000..1c18133f92
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Item {
+ id: root
+ width: 100
+ height: 100
+ property int tapCount: 0
+ TapHandler {
+ onTapped: { ++root.tapCount }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
index 7e7441685f..5fb905cbab 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -71,15 +71,25 @@ private slots:
void componentUserBehavioralOverride();
void rightLongPressIgnoreWheel();
void negativeZStackingOrder();
+ void nonTopLevelParentWindow();
private:
- void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName,
+ QWindow *parent = nullptr);
QPointingDevice *touchDevice = QTest::createTouchDevice();
+ void mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point,
+ QWindow *targetWindow, QWindow *mapToWindow);
};
-void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName,
+ QWindow *parent)
{
- window.reset(new QQuickView);
+ window.reset(new QQuickView(parent));
+ if (parent) {
+ parent->show();
+ QVERIFY(QTest::qWaitForWindowActive(parent));
+ }
+
window->setSource(testFileUrl(fileName));
QTRY_COMPARE(window->status(), QQuickView::Ready);
QQuickViewTestUtil::centerOnScreen(window.data());
@@ -90,6 +100,20 @@ void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *
QVERIFY(window->rootObject() != nullptr);
}
+void tst_TapHandler::mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point,
+ QWindow *targetWindow, QWindow *mapToWindow)
+{
+ QVERIFY(targetWindow);
+ QVERIFY(mapToWindow);
+ auto buttons = button;
+ if (type == QEvent::MouseButtonRelease) {
+ buttons = Qt::NoButton;
+ }
+ QMouseEvent me(type, point, mapToWindow->mapToGlobal(point), button, buttons,
+ Qt::KeyboardModifiers(), QPointingDevice::primaryPointingDevice());
+ QVERIFY(qApp->notify(targetWindow, &me));
+}
+
void tst_TapHandler::initTestCase()
{
// This test assumes that we don't get synthesized mouse events from QGuiApplication
@@ -777,6 +801,31 @@ void tst_TapHandler::negativeZStackingOrder() // QTBUG-83114
QVERIFY(order.at(1) == "childTapHandler");
}
+void tst_TapHandler::nonTopLevelParentWindow() // QTBUG-91716
+{
+ QScopedPointer<QQuickWindow> parentWindowPtr(new QQuickWindow);
+ auto parentWindow = parentWindowPtr.get();
+ parentWindow->setGeometry(400, 400, 250, 250);
+
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "simpleTapHandler.qml", parentWindow);
+ auto window = windowPtr.get();
+ window->setGeometry(10, 10, 100, 100);
+
+ QQuickItem *root = window->rootObject();
+
+ auto p1 = QPoint(20, 20);
+ mouseEvent(QEvent::MouseButtonPress, Qt::LeftButton, p1, window, parentWindow);
+ mouseEvent(QEvent::MouseButtonRelease, Qt::LeftButton, p1, window, parentWindow);
+
+ QCOMPARE(root->property("tapCount").toInt(), 1);
+
+ QTest::touchEvent(window, touchDevice).press(0, p1, parentWindow).commit();
+ QTest::touchEvent(window, touchDevice).release(0, p1, parentWindow).commit();
+
+ QCOMPARE(root->property("tapCount").toInt(), 2);
+}
+
QTEST_MAIN(tst_TapHandler)
#include "tst_qquicktaphandler.moc"