diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-09-03 15:07:21 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-09-16 14:24:00 +0200 |
commit | 0246bfd40a2cc5ea9cfc035146e6dd865b334c68 (patch) | |
tree | 1a8eb37fc4864d01336b44a3073830cb8f26665b /src | |
parent | 8aa1fc6f12858ad6f786a4a971a5758fa28d3686 (diff) |
Close QDialog via QWidget::close()
By going via QWidget::close() we ensure that if there's a QWidgetWindow
backing the dialog (which is almost always the case), we will plumb down
to QWindow::close(), resulting in QEvent::Close events to the QWindow.
Since we don't want QDialog subclasses to receive a call to a closeEvent
override that they didn't receive before (and which they might interpret
as rejection or cancellation), install a temporary event filter that
eats the QCloseEvent resulting from the call to close().
Task-number: QTBUG-53286
Change-Id: Ie8f6f0cb3160acfd5865dc74f0a7b6d87f838724
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/dialogs/qdialog.cpp | 25 | ||||
-rw-r--r-- | src/widgets/dialogs/qdialog_p.h | 2 | ||||
-rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 8 |
3 files changed, 27 insertions, 8 deletions
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 9e18e2443a..9f4e95d83c 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -146,16 +146,33 @@ bool QDialogPrivate::canBeNativeDialog() const /*! \internal - Properly hides dialog and sets the \a resultCode. + Properly closes dialog and sets the \a resultCode. */ -void QDialogPrivate::hide(int resultCode) +void QDialogPrivate::close(int resultCode) { Q_Q(QDialog); q->setResult(resultCode); q->hide(); + if (!data.is_closing) { + // Until Qt 6.3 we didn't close dialogs, so they didn't receive a QCloseEvent. + // It is likely that subclasses implement closeEvent and handle them as rejection + // (like QMessageBox and QProgressDialog do), so eat those events. + struct CloseEventEater : QObject + { + using QObject::QObject; + protected: + bool eventFilter(QObject *o, QEvent *e) override + { + if (e->type() == QEvent::Close) + return true; + return QObject::eventFilter(o, e); + } + } closeEventEater; + q->installEventFilter(&closeEventEater); + QWidgetPrivate::close(); + } - handleClose(QWidgetPrivate::CloseNoEvent); resetModalitySetByOpen(); } @@ -632,7 +649,7 @@ int QDialog::exec() void QDialog::done(int r) { Q_D(QDialog); - d->hide(r); + d->close(r); d->finalize(r, r); } diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index 0c31593ced..7c7e8f89a7 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -122,7 +122,7 @@ public: QPlatformDialogHelper *platformHelper() const; virtual bool canBeNativeDialog() const; - void hide(int resultCode); + void close(int resultCode); void finalize(int resultCode, int dialogCode); private: diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ac2f8bd2d5..a3093f82c2 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -518,7 +518,7 @@ void QMessageBoxPrivate::setClickedButton(QAbstractButton *button) emit q->buttonClicked(clickedButton); auto resultCode = execReturnCode(button); - hide(resultCode); + close(resultCode); finalize(resultCode, dialogCodeForButton(button)); } @@ -1420,8 +1420,10 @@ void QMessageBox::closeEvent(QCloseEvent *e) return; } QDialog::closeEvent(e); - d->clickedButton = d->detectedEscapeButton; - setResult(d->execReturnCode(d->detectedEscapeButton)); + if (!d->clickedButton) { + d->clickedButton = d->detectedEscapeButton; + setResult(d->execReturnCode(d->detectedEscapeButton)); + } } /*! |