diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2019-11-07 12:42:12 +0100 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2019-12-04 12:26:10 +0100 |
commit | 75b6ef710cddbf9395df35650438f0feb57ec076 (patch) | |
tree | a9efb9180d8eb86f2badc138b58fe62b9c7e7bdc | |
parent | 463898f0765b83f6c391f6802a0ee06796f9f6d2 (diff) |
SplitView: fix hoverable child items breaking handle hover state
Detect HoverEnter events by filtering the mouse events of child items,
and respond by clearing any hovered handle.
Change-Id: Ice7e7fe3cc4c9224064c2384cd832e4a7d91c4da
Fixes: QTBUG-79846
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-rw-r--r-- | src/quicktemplates2/qquicksplitview.cpp | 19 | ||||
-rw-r--r-- | src/quicktemplates2/qquicksplitview_p.h | 1 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_splitview.qml | 51 |
3 files changed, 71 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp index 45efdc75..219a6b08 100644 --- a/src/quicktemplates2/qquicksplitview.cpp +++ b/src/quicktemplates2/qquicksplitview.cpp @@ -80,6 +80,9 @@ QT_BEGIN_NAMESPACE \li \l{SplitHandle::pressed}{SplitHandle.pressed} \endlist + \note Handles should be purely visual and not handle events, as it can + interfere with their hovered and pressed states. + The preferred size of items in a SplitView can be specified via \l{Item::}{implicitWidth} and \l{Item::}{implicitHeight} or \c SplitView.preferredWidth and \c SplitView.preferredHeight: @@ -1091,6 +1094,7 @@ QQuickSplitView::QQuickSplitView(QQuickItem *parent) d->changeTypes |= QQuickItemPrivate::Visibility; setAcceptedMouseButtons(Qt::LeftButton); + setFiltersChildMouseEvents(true); } QQuickSplitView::QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent) @@ -1100,6 +1104,7 @@ QQuickSplitView::QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent) d->changeTypes |= QQuickItemPrivate::Visibility; setAcceptedMouseButtons(Qt::LeftButton); + setFiltersChildMouseEvents(true); } QQuickSplitView::~QQuickSplitView() @@ -1364,6 +1369,20 @@ void QQuickSplitView::hoverMoveEvent(QHoverEvent *event) d->updateHoveredHandle(hoveredItem); } +bool QQuickSplitView::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickSplitView); + qCDebug(qlcQQuickSplitViewMouse) << "childMouseEventFilter called with" << item << event; + if (event->type() != QEvent::HoverEnter) + return false; + + // If a child item received a hover enter event, then it means our handle is no longer hovered. + // Handles should be purely visual and not accept hover events, + // so we should never get hover events for them here. + d->updateHoveredHandle(nullptr); + return false; +} + void QQuickSplitView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickSplitView); diff --git a/src/quicktemplates2/qquicksplitview_p.h b/src/quicktemplates2/qquicksplitview_p.h index 99001615..2fa15588 100644 --- a/src/quicktemplates2/qquicksplitview_p.h +++ b/src/quicktemplates2/qquicksplitview_p.h @@ -99,6 +99,7 @@ protected: void componentComplete() override; void hoverMoveEvent(QHoverEvent *event) override; + bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; void itemAdded(int index, QQuickItem *item) override; diff --git a/tests/auto/controls/data/tst_splitview.qml b/tests/auto/controls/data/tst_splitview.qml index c125b99e..74e4c68e 100644 --- a/tests/auto/controls/data/tst_splitview.qml +++ b/tests/auto/controls/data/tst_splitview.qml @@ -2026,4 +2026,55 @@ TestCase { compare(control.repeater.count, 3) compare(control.contentChildren.length, 3) } + + Component { + id: hoverableChildrenSplitViewComponent + + SplitView { + handle: handleComponent + anchors.fill: parent + + MouseArea { + objectName: "mouseArea1" + hoverEnabled: true + + SplitView.preferredWidth: 200 + } + MouseArea { + objectName: "mouseArea2" + hoverEnabled: true + } + } + } + + function test_hoverableChilden() { + if (Qt.platform.pluginName === "offscreen" || Qt.platform.pluginName === "minimal") + skip("Mouse hovering not functional on offscreen/minimal platforms") + + var control = createTemporaryObject(hoverableChildrenSplitViewComponent, testCase) + verify(control) + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + + // Move the mouse over the handle. + var handles = findHandles(control) + var targetHandle = handles[0] + // Test fails if we don't do two moves for some reason... + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + verify(targetHandle.SplitHandle.hovered) + + // Move the mouse to the MouseArea on the left. The handle should no longer be hovered. + mouseMove(control, 100, control.height / 2) + verify(!targetHandle.SplitHandle.hovered) + + // Move the mouse back over the handle. + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + verify(targetHandle.SplitHandle.hovered) + + // Move the mouse to the MouseArea on the right. The handle should no longer be hovered. + mouseMove(control, control.width - 100, control.height / 2) + verify(!targetHandle.SplitHandle.hovered) + } } |