aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-05-06 17:46:37 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2022-05-28 15:37:12 +0200
commit375e4003902e56e1cfd4192cee47566161b7b32d (patch)
tree11847fb62455231f592ac25fde744bfe1997b174 /tests
parent6d2d4914f884fc1a88382ba5cb6eeeeab272874e (diff)
Implement support for passive grabbers with mouse/touch events
Send mouse and touch events through passive grabbers. With support for passive grabbers, the drawer can now make itself a passive grabber for the mouse when it is pressed inside the margin area. It will then see the update events that are delivered to the exclusive grabber, and can try to grab the mouse when the e.g. move has progressed enough. Then the earlier grabber gets an ungrab event that allows it to cancel the action. Done-with: Doris Verria <doris.verria@qt.io> Fixes: QTBUG-59141 Change-Id: Ie8e79c2ec2aa1f5a00056f23856bd0bed19af2d6 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquickdeliveryagent/data/passiveGrabberItem.qml34
-rw-r--r--tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp129
2 files changed, 163 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickdeliveryagent/data/passiveGrabberItem.qml b/tests/auto/quick/qquickdeliveryagent/data/passiveGrabberItem.qml
new file mode 100644
index 0000000000..71e0ac8989
--- /dev/null
+++ b/tests/auto/quick/qquickdeliveryagent/data/passiveGrabberItem.qml
@@ -0,0 +1,34 @@
+import QtQuick
+
+import Test
+
+Item {
+ width: 320
+ height: 240
+ property alias exclusiveGrabber: exGrabber
+ property alias passiveGrabber: psGrabber
+ ExclusiveGrabber {
+ id: exGrabber
+ width: parent.width
+ height: 30
+ color: "blue"
+ anchors.verticalCenter: parent.verticalCenter
+ Text {
+ anchors.centerIn: parent
+ text: "Exclusive Grabber"
+ }
+ }
+ PassiveGrabber {
+ id: psGrabber
+ width: parent.width * 0.3
+ height: parent.height
+ color: "yellow"
+ opacity: 0.5
+ Text {
+ anchors.centerIn: parent
+ text: "Passive Grabber"
+ rotation: 90
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp
index ac00cfede7..cd6eb3a93c 100644
--- a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp
+++ b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp
@@ -34,6 +34,7 @@
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickWindow>
+#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquickflickable_p.h>
#include <QtQuick/private/qquickpointhandler_p.h>
#include <QtQuick/private/qquickshadereffectsource_p.h>
@@ -153,6 +154,7 @@ public:
private slots:
void passiveGrabberOrder();
+ void passiveGrabberItems();
void tapHandlerDoesntOverrideSubsceneGrabber();
void touchCompression();
void hoverPropagation_nested_data();
@@ -216,6 +218,133 @@ void tst_qquickdeliveryagent::passiveGrabberOrder()
QCOMPARE(spy.senders.last(), rootTap);
}
+class PassiveGrabberItem : public QQuickRectangle
+{
+public:
+ PassiveGrabberItem(QQuickItem *parent = nullptr) : QQuickRectangle(parent) {
+ setAcceptedMouseButtons(Qt::LeftButton);
+ }
+ void mousePressEvent(QMouseEvent *event) override {
+ qCDebug(lcTests) << "Passive grabber pressed";
+ lastPressed = true;
+ event->addPassiveGrabber(event->point(0), this);
+ event->ignore();
+ }
+ void mouseMoveEvent(QMouseEvent *event) override {
+ qCDebug(lcTests) << "Mouse move handled by passive grabber";
+ const QPointF pos = event->scenePosition();
+ const int threshold = 20;
+ bool overThreshold = pos.x() >= threshold;
+ if (overThreshold) {
+ event->setExclusiveGrabber(event->point(0), this);
+ this->setKeepMouseGrab(true);
+ event->accept();
+ } else {
+ event->ignore();
+ }
+ }
+ void mouseReleaseEvent(QMouseEvent *event) override {
+ qCDebug(lcTests) << "Passive grabber released";
+ lastPressed = false;
+ event->ignore();
+ }
+
+ bool lastPressed = false;
+};
+
+class ExclusiveGrabberItem : public QQuickRectangle
+{
+public:
+ ExclusiveGrabberItem(QQuickItem *parent = nullptr) : QQuickRectangle(parent) {
+ setAcceptedMouseButtons(Qt::LeftButton);
+ }
+ void mousePressEvent(QMouseEvent *event) override {
+ qCDebug(lcTests) << "Exclusive grabber pressed";
+ lastPressed = true;
+ event->accept();
+ }
+ void mouseMoveEvent(QMouseEvent *event) override {
+ event->accept();
+ }
+ void mouseReleaseEvent(QMouseEvent *event) override {
+ qCDebug(lcTests) << "Exclusive grabber released";
+ lastPressed = false;
+ event->accept();
+ }
+ void mouseUngrabEvent() override {
+ qCDebug(lcTests) << "Exclusive grab ended";
+ ungrabbed = true;
+ }
+
+ bool lastPressed = false;
+ bool ungrabbed = false;
+};
+
+void tst_qquickdeliveryagent::passiveGrabberItems()
+{
+ QQuickView view;
+ QQmlComponent component(view.engine());
+ qmlRegisterType<PassiveGrabberItem>("Test", 1, 0, "PassiveGrabber");
+ qmlRegisterType<ExclusiveGrabberItem>("Test", 1, 0, "ExclusiveGrabber");
+ component.loadUrl(testFileUrl("passiveGrabberItem.qml"));
+ view.setContent(QUrl(), &component, component.create());
+ QQuickItem *root = qobject_cast<QQuickItem*>(view.rootObject());
+ QVERIFY(root);
+ ExclusiveGrabberItem *exclusiveGrabber = root->property("exclusiveGrabber").value<ExclusiveGrabberItem*>();
+ PassiveGrabberItem *passiveGrabber = root->property("passiveGrabber").value<PassiveGrabberItem *>();
+ QVERIFY(exclusiveGrabber);
+ QVERIFY(passiveGrabber);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(exclusiveGrabber->x() + 1, exclusiveGrabber->y() + 1));
+ auto devPriv = QPointingDevicePrivate::get(QPointingDevice::primaryPointingDevice());
+ const auto &persistentPoint = devPriv->activePoints.values().first();
+ QTRY_COMPARE(persistentPoint.passiveGrabbers.count(), 1);
+ QCOMPARE(persistentPoint.passiveGrabbers.first(), passiveGrabber);
+ QCOMPARE(persistentPoint.exclusiveGrabber, exclusiveGrabber);
+ QVERIFY(exclusiveGrabber->lastPressed);
+ QVERIFY(passiveGrabber->lastPressed);
+
+ // Mouse move bigger than threshold -> passive grabber becomes exclusive grabber
+ QTest::mouseMove(&view);
+ QTRY_COMPARE(persistentPoint.exclusiveGrabber, passiveGrabber);
+ QVERIFY(exclusiveGrabber->ungrabbed);
+
+ QTest::mouseRelease(&view, Qt::LeftButton);
+ // Only the passive grabber got the release event
+ // since it became the exclusive grabber on mouseMove
+ QTRY_VERIFY(!passiveGrabber->lastPressed);
+ QVERIFY(exclusiveGrabber->lastPressed);
+ QCOMPARE(persistentPoint.passiveGrabbers.count(), 0);
+ QCOMPARE(persistentPoint.exclusiveGrabber, nullptr);
+
+ exclusiveGrabber->lastPressed = false;
+ exclusiveGrabber->ungrabbed = false;
+ passiveGrabber->lastPressed = false;
+
+ QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(exclusiveGrabber->x() + 1, exclusiveGrabber->y() + 1));
+ const auto &pressedPoint = devPriv->activePoints.values().first();
+ QTRY_COMPARE(pressedPoint.passiveGrabbers.count(), 1);
+ QCOMPARE(pressedPoint.passiveGrabbers.first(), passiveGrabber);
+ QCOMPARE(pressedPoint.exclusiveGrabber, exclusiveGrabber);
+ QVERIFY(exclusiveGrabber->lastPressed);
+ QVERIFY(passiveGrabber->lastPressed);
+
+ // Mouse move smaller than threshold -> grab remains with the exclusive grabber
+ QTest::mouseMove(&view, QPoint(exclusiveGrabber->x(), exclusiveGrabber->y()));
+ QTRY_COMPARE(pressedPoint.exclusiveGrabber, exclusiveGrabber);
+
+ QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(exclusiveGrabber->x(), exclusiveGrabber->y()));
+
+ // Both the passive and the exclusive grabber get the mouseRelease event
+ QTRY_VERIFY(!passiveGrabber->lastPressed);
+ QVERIFY(!exclusiveGrabber->lastPressed);
+ QCOMPARE(pressedPoint.passiveGrabbers.count(), 0);
+ QCOMPARE(pressedPoint.exclusiveGrabber, nullptr);
+}
+
void tst_qquickdeliveryagent::tapHandlerDoesntOverrideSubsceneGrabber() // QTBUG-94012
{
QQuickView window;