diff options
-rw-r--r-- | src/templates/qquickstackview.cpp | 16 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_stackview.qml | 39 |
2 files changed, 51 insertions, 4 deletions
diff --git a/src/templates/qquickstackview.cpp b/src/templates/qquickstackview.cpp index 415e8700..d5e2aee3 100644 --- a/src/templates/qquickstackview.cpp +++ b/src/templates/qquickstackview.cpp @@ -879,10 +879,18 @@ void QQuickStackView::geometryChanged(const QRectF &newGeometry, const QRectF &o } } -bool QQuickStackView::childMouseEventFilter(QQuickItem *, QEvent *) -{ - // busy should be true if this function gets called - return true; +bool QQuickStackView::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + // in order to block accidental user interaction while busy/transitioning, + // StackView filters out childrens' mouse events. therefore we block all + // press events. however, since push() may be called from signal handlers + // such as onPressed or onDoubleClicked, we must let the current mouse + // grabber item receive the respective mouse release event to avoid + // breaking its state (QTBUG-50305). + if (event->type() == QEvent::MouseButtonPress) + return true; + QQuickWindow *window = item->window(); + return window && !window->mouseGrabberItem(); } void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml index 2eb802bf..762be4cc 100644 --- a/tests/auto/controls/data/tst_stackview.qml +++ b/tests/auto/controls/data/tst_stackview.qml @@ -761,6 +761,45 @@ TestCase { control.destroy() } + Component { + id: mouseArea + MouseArea { + property int presses: 0 + property int releases: 0 + property int clicks: 0 + property int doubleClicks: 0 + property int cancels: 0 + onPressed: ++presses + onReleased: ++releases + onClicked: ++clicks + onDoubleClicked: ++doubleClicks + onCanceled: ++cancels + } + } + + // QTBUG-50305 + function test_events() { + var control = stackView.createObject(testCase, {initialItem: mouseArea, width: testCase.width, height: testCase.height}) + verify(control) + + var testItem = control.currentItem + verify(testItem) + + testItem.doubleClicked.connect(function() { + control.push(mouseArea) // ungrab -> cancel + }) + + mouseDoubleClickSequence(testItem) + compare(testItem.presses, 2) + compare(testItem.releases, 2) + compare(testItem.clicks, 1) + compare(testItem.doubleClicks, 1) + compare(testItem.pressed, false) + compare(testItem.cancels, 0) + + control.destroy() + } + function test_failures() { var control = stackView.createObject(testCase, {initialItem: component}) verify(control) |