diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-10-26 14:03:30 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-11-01 09:18:09 +0000 |
commit | eca92bea571cf691423b627d4d6270f7c2807bd9 (patch) | |
tree | 70541098ba712942836f07d21386fc166e344bda /src/quick/handlers/qquickhoverhandler.cpp | |
parent | e27b91e4cc277698c62191ce3c349afc988a2a2b (diff) |
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.
Change-Id: I52f3cd16d6bbfbbe2e4c3c019efdc7f06c5f2c31
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 7db67e59d45b47e45a2723808f23e8cdadf5065c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quick/handlers/qquickhoverhandler.cpp')
-rw-r--r-- | src/quick/handlers/qquickhoverhandler.cpp | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp index 2a2208c567..072ca626a6 100644 --- a/src/quick/handlers/qquickhoverhandler.cpp +++ b/src/quick/handlers/qquickhoverhandler.cpp @@ -40,35 +40,58 @@ class QQuickHoverHandlerPrivate : public QQuickSinglePointHandlerPrivate public: void onEnabledChanged() override; + void onParentChanged(QQuickItem *oldParent, QQuickItem *newParent) override; + + void updateHasHoverInChild(QQuickItem *item, bool hasHover); }; void QQuickHoverHandlerPrivate::onEnabledChanged() { Q_Q(QQuickHoverHandler); - if (auto parent = q->parentItem()) { - QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); - itemPriv->setHasHoverInChild(enabled); - // The DA needs to resolve which items and handlers should now be hovered or unhovered. - // Marking the parent item dirty ensures that flushFrameSynchronousEvents() will be called from the render loop, - // even if this change is not in response to a mouse event and no item has already marked itself dirty. - itemPriv->dirty(QQuickItemPrivate::Content); - } + if (auto parent = q->parentItem()) + updateHasHoverInChild(parent, enabled); if (!enabled) q->setHovered(false); + + QQuickSinglePointHandlerPrivate::onEnabledChanged(); +} + +void QQuickHoverHandlerPrivate::onParentChanged(QQuickItem *oldParent, QQuickItem *newParent) +{ + if (oldParent) + updateHasHoverInChild(oldParent, false); + if (newParent) + updateHasHoverInChild(newParent, true); + + QQuickSinglePointHandlerPrivate::onParentChanged(oldParent, newParent); +} + +void QQuickHoverHandlerPrivate::updateHasHoverInChild(QQuickItem *item, bool hasHover) +{ + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item); + itemPriv->setHasHoverInChild(hasHover); + // The DA needs to resolve which items and handlers should now be hovered or unhovered. + // Marking the parent item dirty ensures that flushFrameSynchronousEvents() will be called from the render loop, + // even if this change is not in response to a mouse event and no item has already marked itself dirty. + itemPriv->dirty(QQuickItemPrivate::Content); } QQuickHoverHandler::QQuickHoverHandler(QQuickItem *parent) : QQuickSinglePointHandler(*(new QQuickHoverHandlerPrivate), parent) { + Q_D(QQuickHoverHandler); // Tell QQuickPointerDeviceHandler::wantsPointerEvent() to ignore button state - d_func()->acceptedButtons = Qt::NoButton; + d->acceptedButtons = Qt::NoButton; + if (parent) + d->updateHasHoverInChild(parent, true); } QQuickHoverHandler::~QQuickHoverHandler() { + Q_D(QQuickHoverHandler); if (auto parent = parentItem()) - QQuickItemPrivate::get(parent)->setHasHoverInChild(false); + d->updateHasHoverInChild(parent, false); } /*! @@ -105,9 +128,13 @@ bool QQuickHoverHandler::event(QEvent *event) void QQuickHoverHandler::componentComplete() { + Q_D(QQuickHoverHandler); QQuickSinglePointHandler::componentComplete(); - if (auto par = parentItem()) - QQuickItemPrivate::get(par)->setHasHoverInChild(true); + + if (d->enabled) { + if (auto parent = parentItem()) + d->updateHasHoverInChild(parent, true); + } } bool QQuickHoverHandler::wantsPointerEvent(QPointerEvent *event) |