aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel d'Andrada <daniel.dandrada@luxoft.com>2017-10-09 17:39:44 +0200
committerTasuku Suzuki <tasuku.suzuki@qt.io>2018-04-09 03:36:36 +0000
commit2597e43497aa8a223d65c669f07bd2e8fdf7e1f1 (patch)
tree16c7b58d8fb1a2b87abf9833b2d5fb69b7be5980
parent560360a1b7218865b71ae284dc920c38ffdd60d6 (diff)
Fix bug preventing ungrabMouse() on TouchCancel
The order matters. There won't be a mouseGrabberItem() after the cancelExclusiveGrabImpl() call. So ungrab the mouse before calling it, not after. This cherry-pick includes some other changes to tst_qquickwindow.cpp (parts of 9d8fe2ac121162c15be6728495be2235b728325a) that enable the cherry-picked test function touchEvent_cancelClearsMouseGrab() to be the same as it is in 5.10 branch. Task-number: QTBUG-63680 Task-number: QTBUG-67445 Change-Id: I1ba6401c5d8eb3417907eb1e6ca20816b501f3ac Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry-picked from 0821180dc833376a738742e33f728983b9ca6f84) Reviewed-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
-rw-r--r--src/quick/items/qquickwindow.cpp9
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp91
2 files changed, 76 insertions, 24 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 15ade6767c..a1136cc3f0 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1883,6 +1883,11 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
qCDebug(DBG_TOUCH) << event;
Q_Q(QQuickWindow);
+ if (q->mouseGrabberItem())
+ q->mouseGrabberItem()->ungrabMouse();
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+
// A TouchCancel event will typically not contain any points.
// Deliver it to all items that have active touches.
QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::touchDevice(event->device()));
@@ -1891,10 +1896,6 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
for (QQuickItem *grabber: qAsConst(grabbers)) {
q->sendEvent(grabber, event);
}
- touchMouseId = -1;
- touchMouseDevice = nullptr;
- if (q->mouseGrabberItem())
- q->mouseGrabberItem()->ungrabMouse();
// The next touch event can only be a TouchBegin so clean up.
pointerEvent->clearGrabbers();
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index cb710e2c8e..4ddb37f70c 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -142,8 +142,9 @@ class TestTouchItem : public QQuickRectangle
public:
TestTouchItem(QQuickItem *parent = 0)
: QQuickRectangle(parent), acceptTouchEvents(true), acceptMouseEvents(true),
- mousePressId(0),
- spinLoopWhenPressed(false), touchEventCount(0)
+ mousePressCount(0), mouseMoveCount(0),
+ spinLoopWhenPressed(false), touchEventCount(0),
+ mouseUngrabEventCount(0)
{
border()->setWidth(1);
setAcceptedMouseButtons(Qt::LeftButton);
@@ -161,9 +162,11 @@ public:
lastMousePos = QPointF();
lastMouseCapabilityFlags = 0;
touchEventCount = 0;
+ mouseMoveCount = 0;
+ mouseUngrabEventCount = 0;
}
- static void clearMousePressCounter()
+ static void clearMouseEventCounters()
{
mousePressNum = mouseMoveNum = mouseReleaseNum = 0;
}
@@ -176,9 +179,11 @@ public:
bool acceptTouchEvents;
bool acceptMouseEvents;
TouchEventData lastEvent;
- int mousePressId;
+ int mousePressCount;
+ int mouseMoveCount;
bool spinLoopWhenPressed;
int touchEventCount;
+ int mouseUngrabEventCount;
QVector2D lastVelocity;
QVector2D lastVelocityFromMouseMove;
QPointF lastMousePos;
@@ -206,7 +211,7 @@ public:
e->ignore();
return;
}
- mousePressId = ++mousePressNum;
+ mousePressCount = ++mousePressNum;
lastMousePos = e->pos();
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
}
@@ -216,7 +221,7 @@ public:
e->ignore();
return;
}
- ++mouseMoveNum;
+ mouseMoveCount = ++mouseMoveNum;
lastVelocityFromMouseMove = QGuiApplicationPrivate::mouseEventVelocity(e);
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
lastMousePos = e->pos();
@@ -232,10 +237,23 @@ public:
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
}
- bool childMouseEventFilter(QQuickItem *, QEvent *event) {
- // TODO Is it a bug if a QTouchEvent comes here?
- if (event->type() == QEvent::MouseButtonPress)
- mousePressId = ++mousePressNum;
+ void mouseUngrabEvent() {
+ ++mouseUngrabEventCount;
+ }
+
+ bool childMouseEventFilter(QQuickItem *item, QEvent *e) {
+ qCDebug(lcTests) << objectName() << "filtering" << e << "ahead of delivery to" << item->metaObject()->className() << item->objectName();
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ mousePressCount = ++mousePressNum;
+ break;
+ case QEvent::MouseMove:
+ mouseMoveCount = ++mouseMoveNum;
+ break;
+ default:
+ break;
+ }
+
return false;
}
@@ -367,6 +385,7 @@ private slots:
void touchEvent_propagation();
void touchEvent_propagation_data();
void touchEvent_cancel();
+ void touchEvent_cancelClearsMouseGrab();
void touchEvent_reentrant();
void touchEvent_velocity();
@@ -575,7 +594,7 @@ void tst_qquickwindow::constantUpdatesOnWindow()
void tst_qquickwindow::touchEvent_basic()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -704,7 +723,7 @@ void tst_qquickwindow::touchEvent_basic()
void tst_qquickwindow::touchEvent_propagation()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QFETCH(bool, acceptTouchEvents);
QFETCH(bool, acceptMouseEvents);
@@ -848,7 +867,7 @@ void tst_qquickwindow::touchEvent_propagation_data()
void tst_qquickwindow::touchEvent_cancel()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -880,9 +899,41 @@ void tst_qquickwindow::touchEvent_cancel()
delete item;
}
+void tst_qquickwindow::touchEvent_cancelClearsMouseGrab()
+{
+ TestTouchItem::clearMouseEventCounters();
+
+ QQuickWindow *window = new QQuickWindow;
+ QScopedPointer<QQuickWindow> cleanup(window);
+
+ window->resize(250, 250);
+ window->setPosition(100, 100);
+ window->setTitle(QTest::currentTestFunction());
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ TestTouchItem *item = new TestTouchItem(window->contentItem());
+ item->setPosition(QPointF(50, 50));
+ item->setSize(QSizeF(150, 150));
+ item->acceptMouseEvents = true;
+ item->acceptTouchEvents = false;
+
+ QPointF pos(50, 50);
+ QTest::touchEvent(window, touchDevice).press(0, item->mapToScene(pos).toPoint(), window);
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(item->mousePressCount, 1);
+ QTRY_COMPARE(item->mouseUngrabEventCount, 0);
+
+ QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(item->mouseUngrabEventCount, 1);
+}
+
void tst_qquickwindow::touchEvent_reentrant()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -921,7 +972,7 @@ void tst_qquickwindow::touchEvent_reentrant()
void tst_qquickwindow::touchEvent_velocity()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -1056,7 +1107,7 @@ void tst_qquickwindow::mouseFromTouch_basic()
// should result in sending mouse events generated from the touch
// with the new event propagation system.
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
window->resize(250, 250);
@@ -1196,7 +1247,7 @@ void tst_qquickwindow::clearWindow()
void tst_qquickwindow::mouseFiltering()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -1229,9 +1280,9 @@ void tst_qquickwindow::mouseFiltering()
// 1. middleItem filters event
// 2. bottomItem filters event
// 3. topItem receives event
- QTRY_COMPARE(middleItem->mousePressId, 1);
- QTRY_COMPARE(bottomItem->mousePressId, 2);
- QTRY_COMPARE(topItem->mousePressId, 3);
+ QTRY_COMPARE(middleItem->mousePressCount, 1);
+ QTRY_COMPARE(bottomItem->mousePressCount, 2);
+ QTRY_COMPARE(topItem->mousePressCount, 3);
// clean up mouse press state for the next tests
QTest::mouseRelease(window, Qt::LeftButton, 0, pos);