aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Arve Sæther <jan-arve.saether@qt.io>2018-05-11 13:36:52 +0200
committerJan Arve Sæther <jan-arve.saether@qt.io>2018-05-11 21:42:56 +0000
commit1f3713a2b40a467e8a8c552d0980dbdd9f7a1ab4 (patch)
tree5e3b1cbfcf5ebe15feea07911066dfb66e6f37d5
parent0a2aaee61cfc2888bc71f54ac5b165d248cbf5e8 (diff)
Fix bug where Ungrab event was not sent
clearGrabbers() will also clear QQuickWindow::mouseGrabberItem(), so we have to retrieve a copy of the mouse grabber item in advance of calling clearGrabbers(). This could happen when a filtering parent actually called grabMouse() on mouse release(!) event. Change-Id: I287214dbdff802707be625d73c38dd9c5d723aef Task-number: QTBUG-68030 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/quick/items/qquickwindow.cpp3
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp41
2 files changed, 43 insertions, 1 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 48eba6a7a0..0f617733c4 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2311,8 +2311,9 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverMouseEvent(event->asPointerMouseEvent());
// failsafe: never allow any kind of grab to persist after release
if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) {
+ QQuickItem *oldGrabber = q->mouseGrabberItem();
event->clearGrabbers();
- sendUngrabEvent(q->mouseGrabberItem(), false);
+ sendUngrabEvent(oldGrabber, false);
}
} else if (event->asPointerTouchEvent()) {
deliverTouchEvent(event->asPointerTouchEvent());
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index cd3486f95f..042908bf0c 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -179,6 +179,7 @@ public:
bool acceptTouchEvents;
bool acceptMouseEvents;
+ bool grabOnRelease = false;
TouchEventData lastEvent;
int mousePressCount;
int mouseMoveCount;
@@ -248,6 +249,10 @@ public:
case QEvent::MouseButtonPress:
mousePressCount = ++mousePressNum;
break;
+ case QEvent::MouseButtonRelease:
+ if (grabOnRelease)
+ grabMouse();
+ break;
case QEvent::MouseMove:
mouseMoveCount = ++mouseMoveNum;
break;
@@ -468,6 +473,7 @@ private slots:
void testChildMouseEventFilter();
void testChildMouseEventFilter_data();
+ void cleanupGrabsOnRelease();
private:
QTouchDevice *touchDevice;
@@ -3514,6 +3520,41 @@ void tst_qquickwindow::testChildMouseEventFilter()
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, mousePos);
}
+void tst_qquickwindow::cleanupGrabsOnRelease()
+{
+ 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 *parent = new TestTouchItem(window->contentItem());
+ parent->setObjectName("parent");
+ parent->setSize(QSizeF(150, 150));
+ parent->acceptMouseEvents = true;
+ parent->grabOnRelease = true;
+
+ TestTouchItem *child = new TestTouchItem(parent);
+ child->setObjectName("child");
+ child->setSize(QSizeF(100, 100));
+ child->acceptMouseEvents = true;
+
+ QPoint pos(80, 80);
+
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos);
+ // There is an explicit parent->grabMouse on release(!). This means grab changes from child
+ // to parent:
+ // This will emit two ungrab events:
+ // 1. One for the child (due to the explicit call to parent->grabMouse())
+ // 2. One for the parent (since the mouse button was finally released)
+ QCOMPARE(child->mouseUngrabEventCount, 1);
+ QCOMPARE(parent->mouseUngrabEventCount, 1);
+}
QTEST_MAIN(tst_qquickwindow)