aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/templates/qquickstackview.cpp16
-rw-r--r--tests/auto/controls/data/tst_stackview.qml39
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)