Allow programmatic closing of windows that are modally blocked

In Qt 6, after changes such as 121fddcf5a,
we go through the QPA layer to close widget windows properly. Closing
and hiding of windows is now done in when we receive and handle the
window system's CloseEvent.

Such an event to a modally blocked window should be blocked, so that
users can't close a modally blocked window. However, if the event is the
result of a call to QWindow::close, then it should not be blocked.
Luckily, we know that the event is the result of such a call, so let
such events through. This restores compatibility with Qt 5, where it was
possible to first open a new dialog, and then close the previous dialog.

Add a test case.

Fixes: QTBUG-107188
Pick-to: 6.4 6.2
Change-Id: Id812c1fc36aa0e1a10dfb8d3a16a11d387289b05
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2022-10-10 14:25:45 +02:00
parent aa37e67ef7
commit cdadd1bdb3
2 changed files with 20 additions and 2 deletions

View File

@ -2645,8 +2645,9 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
{
if (e->window.isNull())
return;
if (e->window.data()->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow close events through
if (e->window.data()->d_func()->blockedByModalWindow && !e->window.data()->d_func()->inClose) {
// a modal window is blocking this window, don't allow close events through, unless they
// originate from a call to QWindow::close.
return;
}

View File

@ -70,6 +70,7 @@ private slots:
void modalWithChildWindow();
void modalWindowModallity();
void modalWindowPosition();
void modalCloseWhileBlocked();
#ifndef QT_NO_CURSOR
void modalWindowEnterEventOnHide_QTBUG35109();
void spuriousMouseMove();
@ -2267,6 +2268,22 @@ void tst_QWindow::modalWindowPosition()
QCOMPARE(window.geometry(), origGeo);
}
void tst_QWindow::modalCloseWhileBlocked()
{
QWindow first;
first.setModality(Qt::ApplicationModal);
first.show();
QVERIFY(QTest::qWaitForWindowExposed(&first));
QWindow second;
second.setModality(Qt::ApplicationModal);
second.show();
QVERIFY(QTest::qWaitForWindowExposed(&first));
first.close();
QTRY_VERIFY(!first.isVisible());
}
#ifndef QT_NO_CURSOR
void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109()
{