diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp index de110b2660..e2bb83e638 100644 --- a/src/quick/util/qquickdeliveryagent.cpp +++ b/src/quick/util/qquickdeliveryagent.cpp @@ -2092,6 +2092,16 @@ void QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent *event) } if (!relevantPassiveGrabbers.isEmpty()) deliverToPassiveGrabbers(relevantPassiveGrabbers, event); + + // Ensure that HoverHandlers are updated, in case no items got dirty so far and there's no update request + if (event->type() == QEvent::TouchUpdate) { + for (auto hoverItem : hoverItems) { + if (auto item = hoverItem.first) { + deliverHoverEventToItem(item, point.scenePosition(), point.sceneLastPosition(), + event->modifiers(), event->timestamp(), false); + } + } + } } if (done) diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml new file mode 100644 index 0000000000..60dfc53c40 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/hoverHandler.qml @@ -0,0 +1,17 @@ +import QtQuick + +Item { + width: 320 + height: 240 + + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: hh.hovered ? "lightsteelblue" : "beige" + + HoverHandler { + id: hh + } + } +} diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp index 85f1cbda57..ace99daa6a 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp @@ -49,9 +49,12 @@ private slots: void addHandlerFromCpp(); void ensureHoverHandlerWorksWhenItemHasHoverDisabled(); void changeCursor(); + void touchDrag(); private: void createView(QScopedPointer &window, const char *fileName); + + QScopedPointer touchscreen = QScopedPointer(QTest::createTouchDevice()); }; void tst_HoverHandler::createView(QScopedPointer &window, const char *fileName) @@ -700,6 +703,46 @@ void tst_HoverHandler::changeCursor() #endif } +void tst_HoverHandler::touchDrag() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("hoverHandler.qml"))); + const QQuickItem *root = window.rootObject(); + QQuickHoverHandler *handler = root->findChild(); + QVERIFY(handler); + + // polishAndSync() calls flushFrameSynchronousEvents() before emitting afterAnimating() + QSignalSpy frameSyncSpy(&window, &QQuickWindow::afterAnimating); + + const QPoint out(root->width() - 1, root->height() / 2); + QPoint in(root->width() / 2, root->height() / 2); + + QTest::touchEvent(&window, touchscreen.get()).press(0, out, &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(handler->isHovered(), false); + + frameSyncSpy.clear(); + QTest::touchEvent(&window, touchscreen.get()).move(0, in, &window); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE(handler->isHovered(), true); + QCOMPARE(handler->point().scenePosition(), in); + + in += {10, 10}; + QTest::touchEvent(&window, touchscreen.get()).move(0, in, &window); + QQuickTouchUtils::flush(&window); + // ensure that the color change is visible + QTRY_COMPARE_GE(frameSyncSpy.size(), 1); + QCOMPARE(handler->isHovered(), true); + QCOMPARE(handler->point().scenePosition(), in); + + QTest::touchEvent(&window, touchscreen.get()).move(0, out, &window); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE_GE(frameSyncSpy.size(), 2); + QCOMPARE(handler->isHovered(), false); + + QTest::touchEvent(&window, touchscreen.get()).release(0, out, &window); +} + QTEST_MAIN(tst_HoverHandler) #include "tst_qquickhoverhandler.moc"