From 7db67e59d45b47e45a2723808f23e8cdadf5065c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 26 Oct 2022 14:03:30 +0200 Subject: QQuickHoverHandler: listen for parent changes, and update hasHoverInChild A QQuickHoverHandler is normally created by the QML engine, but can sometimes also be created directly from C++. And for the latter case, QQuickHoverHandler::componentComplete() will not be called. This causes a problem, since it takes care of subscribing for hover events on the parent item. To support creating hover handlers from c++, we therefore need to also subscribe to hover events from the constructor. Moreover, since the parentItem can change at runtime, we also need a virtual function that informs it when the parent item changes, so that we can remove hover subscription from the old parent, and subscribe for it on the new parent. Pick-to: 6.4 Change-Id: I52f3cd16d6bbfbbe2e4c3c019efdc7f06c5f2c31 Reviewed-by: Shawn Rutledge --- .../qquickhoverhandler/tst_qquickhoverhandler.cpp | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp') diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp index be1930b6ba..35819a2567 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp @@ -46,6 +46,7 @@ private slots: void window(); void deviceCursor_data(); void deviceCursor(); + void addHandlerFromCpp(); private: void createView(QScopedPointer &window, const char *fileName); @@ -567,6 +568,69 @@ void tst_HoverHandler::deviceCursor() QCOMPARE(airbrushEraserHandler->isHovered(), true); // there was no fresh QTabletEvent to tell it not to be hovered } +void tst_HoverHandler::addHandlerFromCpp() +{ + // Check that you can create a hover handler from c++, and add it + // as a child of an existing item. Continue to check that you can + // also change the parent item at runtime. + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("nohandler.qml")); + QScopedPointer window(qobject_cast(component.create())); + QVERIFY(!window.isNull()); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickItem *childItem = window->findChild("childItem"); + QVERIFY(childItem); + + // Move mouse outside child + const QPoint outside(200, 200); + const QPoint inside(50, 50); + QTest::mouseMove(window.data(), outside); + + QQuickHoverHandler *handler = new QQuickHoverHandler(childItem); + QSignalSpy spy(handler, &QQuickHoverHandler::hoveredChanged); + + // Move mouse inside child + QTest::mouseMove(window.data(), inside); + QVERIFY(handler->isHovered()); + QCOMPARE(spy.count(), 1); + + // Move mouse outside child + QTest::mouseMove(window.data(), outside); + QVERIFY(!handler->isHovered()); + QCOMPARE(spy.count(), 2); + + // Remove the parent item from the handler + spy.clear(); + handler->setParentItem(nullptr); + + // Move mouse inside child + QTest::mouseMove(window.data(), inside); + QVERIFY(!handler->isHovered()); + QCOMPARE(spy.count(), 0); + + // Move mouse outside child + QTest::mouseMove(window.data(), outside); + QVERIFY(!handler->isHovered()); + QCOMPARE(spy.count(), 0); + + // Reparent back the item to the handler + spy.clear(); + handler->setParentItem(childItem); + + // Move mouse inside child + QTest::mouseMove(window.data(), inside); + QVERIFY(handler->isHovered()); + QCOMPARE(spy.count(), 1); + + // Move mouse outside child + QTest::mouseMove(window.data(), outside); + QVERIFY(!handler->isHovered()); + QCOMPARE(spy.count(), 2); +} + QTEST_MAIN(tst_HoverHandler) #include "tst_qquickhoverhandler.moc" -- cgit v1.2.3