diff options
author | Shawn Rutledge <shawn.rutledge@theqtcompany.com> | 2016-03-04 11:02:54 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@theqtcompany.com> | 2016-03-11 12:15:26 +0000 |
commit | 644a6a42a45ceb9790df6d6ee1c3ba43c7b9ab10 (patch) | |
tree | 493c315698238fb1736cbd29d90a52d5351feb0a /tests/auto/quick/qquickmousearea | |
parent | 6300f4dde0ab3279b18a0fb29f94cfe142557cba (diff) |
MouseArea: add source property to mouse event
It comes from the source() of the QMouseEvent which triggered it.
This makes it possible to distinguish real mouse events from those
that are synthesized from touch or tablet.
And for this we need to import QtQuick 2.7
[ChangeLog][QtQuick][MouseArea] Added mouse.source property
to enable distinguishing genuine mouse events from those that
are synthesized from touch or tablet events.
Change-Id: I568964f63981703bd23e05daac5288518f09d837
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Diffstat (limited to 'tests/auto/quick/qquickmousearea')
3 files changed, 146 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickmousearea/data/ignoreBySource.qml b/tests/auto/quick/qquickmousearea/data/ignoreBySource.qml new file mode 100644 index 0000000000..a53cbf7b1d --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/ignoreBySource.qml @@ -0,0 +1,31 @@ +import QtQuick 2.7 + +Item { + id: root + // by default you can flick via touch or tablet but not via mouse + property int allowedSource: Qt.MouseEventNotSynthesized + property int lastEventSource: -1 + width: 200 + height: 200 + Flickable { + objectName: "flickable" + anchors.fill: parent + contentWidth: 400 + contentHeight: 400 + Rectangle { + color: ma.pressed ? "yellow" : "steelblue" + width: 200 + height: 200 + } + } + MouseArea { + id: ma + objectName: "mousearea" + onPressed: { + root.lastEventSource = mouse.source + if (mouse.source !== root.allowedSource) + mouse.accepted = false + } + anchors.fill: parent + } +} diff --git a/tests/auto/quick/qquickmousearea/qquickmousearea.pro b/tests/auto/quick/qquickmousearea/qquickmousearea.pro index 15a080aa3e..3a4dfa946f 100644 --- a/tests/auto/quick/qquickmousearea/qquickmousearea.pro +++ b/tests/auto/quick/qquickmousearea/qquickmousearea.pro @@ -7,6 +7,7 @@ SOURCES += tst_qquickmousearea.cpp \ ../../shared/testhttpserver.cpp include (../../shared/util.pri) +include (../shared/util.pri) TESTDATA = data/* diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index d2994ca0b4..3f78bcf1eb 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -36,9 +36,11 @@ #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlengine.h> #include "../../shared/util.h" +#include "../shared/viewtestutil.h" #include <QtGui/qstylehints.h> #include <QtGui/QCursor> #include <QtGui/QScreen> +#include <qpa/qwindowsysteminterface.h> // Initialize view, set Url, center in available geometry, move mouse away if desired static bool initView(QQuickView &v, const QUrl &url, bool moveMouseOut, QByteArray *errorMessage) @@ -68,7 +70,13 @@ static bool initView(QQuickView &v, const QUrl &url, bool moveMouseOut, QByteArr class tst_QQuickMouseArea: public QQmlDataTest { Q_OBJECT +public: + tst_QQuickMouseArea() + : device(nullptr) + {} + private slots: + void initTestCase() Q_DECL_OVERRIDE; void dragProperties(); void resetDrag(); void dragging_data() { acceptedButton_data(); } @@ -113,15 +121,27 @@ private slots: void nestedStopAtBounds_data(); void containsPress_data(); void containsPress(); + void ignoreBySource(); private: void acceptedButton_data(); void rejectedButton_data(); + QTouchDevice *device; }; Q_DECLARE_METATYPE(Qt::MouseButton) Q_DECLARE_METATYPE(Qt::MouseButtons) +void tst_QQuickMouseArea::initTestCase() +{ + QQmlDataTest::initTestCase(); + if (!device) { + device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + } +} + void tst_QQuickMouseArea::acceptedButton_data() { QTest::addColumn<Qt::MouseButtons>("acceptedButtons"); @@ -1790,6 +1810,100 @@ void tst_QQuickMouseArea::containsPress() QCOMPARE(containsPressSpy.count(), 4); } +void tst_QQuickMouseArea::ignoreBySource() +{ + QQuickView window; + QByteArray errorMessage; + QVERIFY2(initView(window, testFileUrl("ignoreBySource.qml"), true, &errorMessage), errorMessage.constData()); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(window.rootObject()); + + QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject()); + QVERIFY(root); + + QQuickMouseArea *mouseArea = root->findChild<QQuickMouseArea*>("mousearea"); + QVERIFY(mouseArea); + + QQuickFlickable *flickable = root->findChild<QQuickFlickable*>("flickable"); + QVERIFY(flickable); + + // MouseArea should grab the press because it's interested in non-synthesized mouse events + QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + QVERIFY(window.mouseGrabberItem() == mouseArea); + // That was a real mouse event + QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized); + + // Flickable content should not move + QTest::mouseMove(&window,QPoint(69,69)); + QTest::mouseMove(&window,QPoint(58,58)); + QTest::mouseMove(&window,QPoint(47,47)); + QCOMPARE(flickable->contentX(), 0.); + QCOMPARE(flickable->contentY(), 0.); + + QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47)); + + // Now try touch events and confirm that MouseArea ignores them, while Flickable does its thing + + QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window); + QQuickTouchUtils::flush(&window); + QVERIFY(window.mouseGrabberItem() != mouseArea); + // That was a fake mouse event + QCOMPARE(root->property("lastEventSource").toInt(), int(Qt::MouseEventSynthesizedByQt)); + QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); + QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); + QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(window.mouseGrabberItem(), flickable); + QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window); + QQuickTouchUtils::flush(&window); + + // Flickable content should have moved + QTRY_VERIFY(flickable->contentX() > 1); + QVERIFY(flickable->contentY() > 1); + + + // Now tell the MouseArea to accept only synthesized events, and repeat the tests + root->setProperty("allowedSource", Qt::MouseEventSynthesizedByQt); + flickable->setContentX(0); + flickable->setContentY(0); + + + // MouseArea should ignore the press because it's interested in synthesized mouse events + QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + QVERIFY(window.mouseGrabberItem() != mouseArea); + // That was a real mouse event + QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized); + + // Flickable content should move + QTest::mouseMove(&window,QPoint(69,69)); + QTest::mouseMove(&window,QPoint(58,58)); + QTest::mouseMove(&window,QPoint(47,47)); + QTRY_VERIFY(flickable->contentX() > 1); + QVERIFY(flickable->contentY() > 1); + + QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47)); + flickable->setContentX(0); + flickable->setContentY(0); + + // Now try touch events and confirm that MouseArea gets them, while Flickable doesn't + + QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(window.mouseGrabberItem(), mouseArea); + QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); + QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); + QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(window.mouseGrabberItem(), mouseArea); + QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window); + QQuickTouchUtils::flush(&window); + + // Flickable content should not have moved + QCOMPARE(flickable->contentX(), 0.); + QCOMPARE(flickable->contentY(), 0.); +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" |