summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qwidget.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-09-02 13:21:46 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-09-02 20:34:48 +0200
commit7ba75d088c3eba81a1d2bb708119442991d9f30b (patch)
treeef80a127f9d8d9d6c3ee40a4dacae2f9b2ddf0fb /src/widgets/kernel/qwidget.cpp
parentf10ec04a6c9249ec7fad1d661bbb85610dd6d6f1 (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.cpp25
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);
}