From 36fadb4c130c12847ac53bc588f944494d69603d Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Fri, 17 Nov 2023 11:12:26 +0100 Subject: [PATCH] QMainWindowTabBar: Add destructor QMainWindowLayout re-uses tab bars. A QSet and a QList member are kept, to track used and unused tab bars. Corner cases upon application close down leave dangling pointers in those containers. => Add a destructor to QMainWindowTabBar => remove the tab bar from used and unused tab bar containers, if not directly parented to the main window. => No longer reparent unused tab bars of a QDockWidgetGroupWindow to the main window. Let them be destroyed as a group window child, and its destructor remove it from the used/unused tab bar container. Pick-to: 6.5 Change-Id: If2388cf878553dc89583dbc8585748fad65bbab2 Reviewed-by: Volker Hilsheimer (cherry picked from commit b6b489db6968fbc3b4aab3755d0166ee09712ff0) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/widgets/qmainwindowlayout.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 8f8e60888f3..f07180e8ea5 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -448,11 +448,6 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() if (!wasHidden) dw->show(); } -#if QT_CONFIG(tabbar) - const auto tabBars = findChildren(Qt::FindDirectChildrenOnly); - for (QTabBar *tb : tabBars) - tb->setParent(parentWidget()); -#endif deleteLater(); } @@ -1776,6 +1771,7 @@ class QMainWindowTabBar : public QTabBar { QMainWindow *mainWindow; QPointer draggingDock; // Currently dragging (detached) dock widget + ~QMainWindowTabBar(); public: QMainWindowTabBar(QMainWindow *parent); protected: @@ -1841,6 +1837,21 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e) QTabBar::mouseMoveEvent(e); } +QMainWindowTabBar::~QMainWindowTabBar() +{ + if (!mainWindow || mainWindow == parentWidget()) + return; + + // tab bar is not parented to the main window + // => can only be a dock widget group window + // => remove itself from used and unused tab bar containers + auto *mwLayout = qt_mainwindow_layout(mainWindow); + if (!mwLayout) + return; + mwLayout->unusedTabBars.removeOne(this); + mwLayout->usedTabBars.remove(this); +} + void QMainWindowTabBar::mouseReleaseEvent(QMouseEvent *e) { if (draggingDock && e->button() == Qt::LeftButton) {