diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-02 13:21:46 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-02 20:34:48 +0200 |
commit | 7ba75d088c3eba81a1d2bb708119442991d9f30b (patch) | |
tree | ef80a127f9d8d9d6c3ee40a4dacae2f9b2ddf0fb /src/widgets/kernel/qwidget.cpp | |
parent | f10ec04a6c9249ec7fad1d661bbb85610dd6d6f1 (diff) |
QWidget: close the QWindow in QWidget::close
We want to close the window, end full screen mode on macOS, and free
platform resources. This is all done by QWindow::close. QWindow::close
closes the platform window, triggering a closeEvent to QWidgetWindow,
which then calls QWidgetPrivate::close_helper.
This way, closing a window via QWidget::close, QWindow::close, or
interactively by the user are all equivalent.
The QCloseEvent generated by the widget needs to be spontaneous for
window-system generated events (i.e. the user clicked the close button),
and non-spontaneous if the window closes because of a call to
QWindow::close. To keep track of whether the event originated in an
explicit call to QWindow::close, add a boolean to the QWindowPrivate.
Add a test case that verifies that the window resources is destroyed,
and that events are delivered as they should.
Done-with: Morten Johan Sørvig <morten.sorvig@qt.io>
Fixes: QTBUG-46701
Pick-to: 6.2
Change-Id: Iacb6a2c8d5e880b16b0c8f0c9257ed94bed36f5b
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/widgets/kernel/qwidget.cpp')
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 61a8605d22..c96b422b14 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8360,6 +8360,24 @@ void QWidgetPrivate::hideChildren(bool spontaneous) } } +/*! + \internal + + For windows, this is called from the QWidgetWindow::handleCloseEvent implementation, + which QWidget::close indirectly calls by closing the QWindow. \a mode will be + CloseWithEvent if QWidgetWindow::handleCloseEvent is called indirectly by + QWindow::close, and CloseWithSpontaneousEvent if the close event originates from the + system (i.e. the user clicked the close button in the title bar). + + QDialog calls this method directly in its hide() implementation, which might be + called from the QDialog::closeEvent override. \a mode will be set to CloseNoEvent + to prevent recursion. + + For non-windows, this is called directly by QWidget::close, and \a mode will be + CloseWithEvent. + + The function is also called by the QWidget destructor, with \a mode set to CloseNoEvent. +*/ bool QWidgetPrivate::close_helper(CloseMode mode) { if (data.is_closing) @@ -8384,6 +8402,7 @@ bool QWidgetPrivate::close_helper(CloseMode mode) } } + // even for windows, make sure we deliver a hide event and that all children get hidden if (!that.isNull() && !q->isHidden()) q->hide(); @@ -8446,6 +8465,12 @@ bool QWidgetPrivate::close_helper(CloseMode mode) bool QWidget::close() { + // Close native widgets via QWindow::close() in order to run QWindow + // close code. The QWidget-specific close code in close_helper() will + // in this case be called from the Close event handler in QWidgetWindow. + if (QWindow *widgetWindow = windowHandle()) + return widgetWindow->close(); + return d_func()->close_helper(QWidgetPrivate::CloseWithEvent); } |