aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-10-24 13:35:39 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2022-10-27 16:14:28 +0200
commit3c761b5bb0e099f4b875ecf363820e4c756e9e58 (patch)
treedf0a8d9d56e64e4a1ecae0dcd033e6a095c688c8
parent932c5a864626a24b5c69c819a8d2d6bbb9797b70 (diff)
QQuickPopup: forget touchId when closed on press outside
QQuickPopupPrivate::touchId became dangling state when a popup is closed by pressing a touchpoint outside (closePolicy CloseOnPressOutside). The menu doesn't receive the release event, and the overlay filters the release after the menu is already closed, so we need to reset the stored touchId immediately. Fixes: QTBUG-103268 Change-Id: I99ff065b707b4b5f123021368e9d71f2c4b2ca70 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 75990e754bf18501583ea38cb0270a52bc2860cf) Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/quicktemplates2/qquickpopup.cpp1
-rw-r--r--tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp152
2 files changed, 89 insertions, 64 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 596eb7103e..89ba76b2fb 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -283,6 +283,7 @@ void QQuickPopupPrivate::closeOrReject()
dialog->reject();
else
q->close();
+ touchId = -1;
}
bool QQuickPopupPrivate::tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags)
diff --git a/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
index 16e2ff2ac2..ab20bd71b4 100644
--- a/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
+++ b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp
@@ -1,3 +1,4 @@
+
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@@ -11,6 +12,7 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/private/qquickpalette_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/viewtestutils_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
#include <QtQuickTemplates2/private/qquickcombobox_p.h>
@@ -90,6 +92,7 @@ private slots:
private:
static bool hasWindowActivation();
+ QScopedPointer<QPointingDevice> touchScreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
};
tst_QQuickPopup::tst_QQuickPopup()
@@ -213,7 +216,6 @@ void tst_QQuickPopup::overlay()
QFETCH(bool, modal);
QFETCH(bool, dim);
- QScopedPointer<QPointingDevice> device(QTest::createTouchDevice());
QQuickControlsApplicationHelper helper(this, source);
QVERIFY2(helper.ready, helper.failureMessage());
@@ -304,13 +306,13 @@ void tst_QQuickPopup::overlay()
QVERIFY(overlay->isVisible());
QTRY_VERIFY(popup->isOpened());
- QTest::touchEvent(window, device.data()).press(0, QPoint(1, 1));
+ QTest::touchEvent(window, touchScreen.data()).press(0, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
- QTest::touchEvent(window, device.data()).release(0, QPoint(1, 1));
+ QTest::touchEvent(window, touchScreen.data()).release(0, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount);
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
@@ -326,28 +328,28 @@ void tst_QQuickPopup::overlay()
QVERIFY(!button->isPressed());
QTRY_VERIFY(popup->isOpened());
- QTest::touchEvent(window, device.data()).press(0, button->mapToScene(QPointF(1, 1)).toPoint());
+ QTest::touchEvent(window, touchScreen.data()).press(0, button->mapToScene(QPointF(1, 1)).toPoint());
QVERIFY(popup->isVisible());
QVERIFY(overlay->isVisible());
QCOMPARE(button->isPressed(), !modal);
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
- QTest::touchEvent(window, device.data()).stationary(0).press(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
+ QTest::touchEvent(window, touchScreen.data()).stationary(0).press(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
QVERIFY(popup->isVisible());
QVERIFY(overlay->isVisible());
QCOMPARE(button->isPressed(), !modal);
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
- QTest::touchEvent(window, device.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1);
+ QTest::touchEvent(window, touchScreen.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1);
QTRY_VERIFY(!popup->isVisible());
QVERIFY(!overlay->isVisible());
QVERIFY(!button->isPressed());
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount);
- QTest::touchEvent(window, device.data()).release(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
+ QTest::touchEvent(window, touchScreen.data()).release(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
QVERIFY(!popup->isVisible());
QVERIFY(!overlay->isVisible());
QVERIFY(!button->isPressed());
@@ -448,25 +450,44 @@ Q_DECLARE_METATYPE(QQuickPopup::ClosePolicy)
void tst_QQuickPopup::closePolicy_data()
{
qRegisterMetaType<QQuickPopup::ClosePolicy>();
+ const auto *mouse = QPointingDevice::primaryPointingDevice();
+ const auto *touch = touchScreen.data();
QTest::addColumn<QString>("source");
+ QTest::addColumn<const QPointingDevice *>("device");
QTest::addColumn<QQuickPopup::ClosePolicy>("closePolicy");
- QTest::newRow("Window:NoAutoClose") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
- QTest::newRow("Window:CloseOnPressOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
- QTest::newRow("Window:CloseOnPressOutsideParent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("Window:CloseOnPressOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("Window:CloseOnReleaseOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
- QTest::newRow("Window:CloseOnReleaseOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
- QTest::newRow("Window:CloseOnEscape") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
-
- QTest::newRow("ApplicationWindow:NoAutoClose") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
- QTest::newRow("ApplicationWindow:CloseOnPressOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
- QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("ApplicationWindow:CloseOnReleaseOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
- QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
- QTest::newRow("ApplicationWindow:CloseOnEscape") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+ QTest::newRow("Window:NoAutoClose mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("Window:CloseOnPressOutside mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("Window:CloseOnPressOutsideParent mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnPressOutside|Parent mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnReleaseOutside mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("Window:CloseOnReleaseOutside|Parent mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("Window:CloseOnEscape mouse") << "window.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+
+ QTest::newRow("ApplicationWindow:NoAutoClose mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnEscape mouse") << "applicationwindow.qml" << mouse << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+
+ QTest::newRow("Window:NoAutoClose touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("Window:CloseOnPressOutside touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("Window:CloseOnPressOutsideParent touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnPressOutside|Parent touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnReleaseOutside touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("Window:CloseOnReleaseOutside|Parent touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("Window:CloseOnEscape touch") << "window.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+
+ QTest::newRow("ApplicationWindow:NoAutoClose touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnEscape touch") << "applicationwindow.qml" << touch << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
}
void tst_QQuickPopup::closePolicy()
@@ -475,6 +496,7 @@ void tst_QQuickPopup::closePolicy()
QSKIP("Window activation is not supported");
QFETCH(QString, source);
+ QFETCH(const QPointingDevice *, device);
QFETCH(QQuickPopup::ClosePolicy, closePolicy);
QQuickControlsApplicationHelper helper(this, source);
@@ -502,56 +524,58 @@ void tst_QQuickPopup::closePolicy()
// wait for dimmer
QTest::qWait(50);
- // press outside popup and its parent
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
- if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) || closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
- QTRY_VERIFY(!popup->isVisible());
- else
- QVERIFY(popup->isOpened());
+ for (int i = 0; i < 2; ++i) {
+ // press outside popup and its parent
+ QQuickTest::pointerPress(device, window, 0, {1, 1});
+ if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) || closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
+ QTRY_VERIFY(!popup->isVisible());
+ else
+ QVERIFY(popup->isOpened());
- popup->open();
- QVERIFY(popup->isVisible());
- QTRY_VERIFY(popup->isOpened());
+ popup->open();
+ QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
- // release outside popup and its parent
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
- if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) || closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent))
- QTRY_VERIFY(!popup->isVisible());
- else
- QVERIFY(popup->isOpened());
+ // release outside popup and its parent
+ QQuickTest::pointerRelease(device, window, 0, {1, 1});
+ if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) || closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent))
+ QTRY_VERIFY(!popup->isVisible());
+ else
+ QVERIFY(popup->isOpened());
- popup->open();
- QVERIFY(popup->isVisible());
- QTRY_VERIFY(popup->isOpened());
+ popup->open();
+ QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
- // press outside popup but inside its parent
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + 1, button->y() + 1));
- if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
- QTRY_VERIFY(!popup->isVisible());
- else
- QVERIFY(popup->isOpened());
+ // press outside popup but inside its parent
+ QQuickTest::pointerPress(device, window, 0, QPoint(button->x() + 1, button->y() + 1));
+ if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
+ QTRY_VERIFY(!popup->isVisible());
+ else
+ QVERIFY(popup->isOpened());
- popup->open();
- QVERIFY(popup->isVisible());
- QTRY_VERIFY(popup->isOpened());
+ popup->open();
+ QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
- // release outside popup but inside its parent
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + 1, button->y() + 1));
- if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent))
- QTRY_VERIFY(!popup->isVisible());
- else
- QVERIFY(popup->isOpened());
+ // release outside popup but inside its parent
+ QQuickTest::pointerRelease(device, window, 0, QPoint(button->x() + 1, button->y() + 1));
+ if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent))
+ QTRY_VERIFY(!popup->isVisible());
+ else
+ QVERIFY(popup->isOpened());
- popup->open();
- QVERIFY(popup->isVisible());
- QTRY_VERIFY(popup->isOpened());
+ popup->open();
+ QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
- // press inside and release outside
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + popup->x() + 1,
- button->y() + popup->y() + 1));
- QVERIFY(popup->isOpened());
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
- QVERIFY(popup->isOpened());
+ // press inside and release outside
+ QQuickTest::pointerPress(device, window, 0, QPoint(button->x() + popup->x() + 1,
+ button->y() + popup->y() + 1));
+ QVERIFY(popup->isOpened());
+ QQuickTest::pointerRelease(device, window, 0, {1, 1});
+ QVERIFY(popup->isOpened());
+ }
// escape
QTest::keyClick(window, Qt::Key_Escape);