diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-08-30 16:49:16 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-09-06 23:12:33 +0200 |
commit | 505ed52cd4dcef081d9868424057451bd1dce497 (patch) | |
tree | 06e5234cb86dcc068d439fecd85d8e5db5be1cf9 /tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp | |
parent | 238d8795b1484a0aeff81b2221e76a51b279f595 (diff) |
Dialogs: clean up native dialogs when object gets destroyed
QWidget::setVisible is virtual, and called via hide() by both the
QDialog and the QWidget destructor. A dialog that becomes invisible
when getting destroyed will at most execute the QDialog override.
Subclassing QDialog and overriding setVisible() to update the state
of the native platform dialog will not work, unless we explicitly
call hide() in the respective subclass's destructor.
Since e0bb9e81ab1a9d71f2893844ea82, QDialogPrivate::setVisible is
also virtual, and gets called by QDialog::setVisible. So the clean
solution is to move the implementation of the native dialog status
update into an override of QDialogPrivate::setVisible.
Add test that verifies that the transient parent of the dialog
becomes inactive when the (native) dialog shows (and skip if that
fails), and then becomes active again when the (native) dialog is
closed through the destructor of the Q*Dialog class. The test of
QFileDialog has to be skipped on Android for the same reason as the
widgetlessNativeDialog.
Fixes: QTBUG-116277
Pick-to: 6.6 6.5
Change-Id: Ie3f93980d8653b8d933bf70aac3ef90de606f0ef
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp')
-rw-r--r-- | tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 3679a9367d..8985243e36 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -60,6 +60,8 @@ private slots: void overrideDone_data(); void overrideDone(); + void hideNativeByDestruction(); + void cleanup(); }; @@ -798,5 +800,32 @@ void tst_QMessageBox::acceptedRejectedSignals_data() addCustomButtonsData(); } +void tst_QMessageBox::hideNativeByDestruction() +{ + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QMessageBox> dialog = new QMessageBox(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive)); +} + QTEST_MAIN(tst_QMessageBox) #include "tst_qmessagebox.moc" |