summaryrefslogtreecommitdiffstats
path: root/src/widgets/dialogs/qfiledialog.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-08-30 16:49:16 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-09-06 23:12:33 +0200
commit505ed52cd4dcef081d9868424057451bd1dce497 (patch)
tree06e5234cb86dcc068d439fecd85d8e5db5be1cf9 /src/widgets/dialogs/qfiledialog.cpp
parent238d8795b1484a0aeff81b2221e76a51b279f595 (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 'src/widgets/dialogs/qfiledialog.cpp')
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp48
1 files changed, 30 insertions, 18 deletions
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index a07cc33711..e985baa3af 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -835,41 +835,53 @@ void QFileDialog::open(QObject *receiver, const char *member)
*/
void QFileDialog::setVisible(bool visible)
{
- Q_D(QFileDialog);
+ // will call QFileDialogPrivate::setVisible override
+ QDialog::setVisible(visible);
+}
+
+/*!
+ \internal
+
+ The logic has to live here so that the call to hide() in ~QDialog calls
+ this function; it wouldn't call an override of QDialog::setVisible().
+*/
+void QFileDialogPrivate::setVisible(bool visible)
+{
+ Q_Q(QFileDialog);
if (visible){
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
+ if (q->testAttribute(Qt::WA_WState_ExplicitShowHide) && !q->testAttribute(Qt::WA_WState_Hidden))
return;
- } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
+ } else if (q->testAttribute(Qt::WA_WState_ExplicitShowHide) && q->testAttribute(Qt::WA_WState_Hidden))
return;
- if (d->canBeNativeDialog()){
- if (d->setNativeDialogVisible(visible)){
- // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+ if (canBeNativeDialog()){
+ if (setNativeDialogVisible(visible)){
+ // Set WA_DontShowOnScreen so that QDialogPrivate::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version:
- setAttribute(Qt::WA_DontShowOnScreen);
+ q->setAttribute(Qt::WA_DontShowOnScreen);
#if QT_CONFIG(fscompleter)
// So the completer doesn't try to complete and therefore show a popup
- if (!d->nativeDialogInUse)
- d->completer->setModel(nullptr);
+ if (!nativeDialogInUse)
+ completer->setModel(nullptr);
#endif
} else {
- d->createWidgets();
- setAttribute(Qt::WA_DontShowOnScreen, false);
+ createWidgets();
+ q->setAttribute(Qt::WA_DontShowOnScreen, false);
#if QT_CONFIG(fscompleter)
- if (!d->nativeDialogInUse) {
- if (d->proxyModel != nullptr)
- d->completer->setModel(d->proxyModel);
+ if (!nativeDialogInUse) {
+ if (proxyModel != nullptr)
+ completer->setModel(proxyModel);
else
- d->completer->setModel(d->model);
+ completer->setModel(model);
}
#endif
}
}
- if (visible && d->usingWidgets())
- d->qFileDialogUi->fileNameEdit->setFocus();
+ if (visible && usingWidgets())
+ qFileDialogUi->fileNameEdit->setFocus();
- QDialog::setVisible(visible);
+ QDialogPrivate::setVisible(visible);
}
/*!