From 95cdc8c1d3cf753f652cab4c7db1c37f92df126d Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Fri, 11 Aug 2023 09:20:44 +0200 Subject: [PATCH] QDockWidgetGroupWindow::adjustFlags() - don't show() empty group window The method calls show() on a dock widget group window, when the window flags have changed. When all of its contained, tabbed dock widgets are programmatically hidden or docked on the main window, an empty group window is shown. This patch implements bool hasVisibleDockWidgets(). It returns true, if at least one of the group window's dockwidget children is not hidden. It replaces show() by setVisible(), passing the return value of hasVisibleChildren(). It adapts tst_QDockWidget::floatingTabs() to test the fix. (Drive-by: remove dead code) Fixes: QTBUG-115058 Change-Id: Ifb8e2450e91a7c78decc06f592e160631ca2faf5 Reviewed-by: Richard Moe Gustavsen (cherry picked from commit e03bc88a80382b68359ba6ea5fc4cb9507ceb85f) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/widgets/qmainwindowlayout.cpp | 21 ++++++++++++++++++- src/widgets/widgets/qmainwindowlayout_p.h | 1 + .../widgets/qdockwidget/tst_qdockwidget.cpp | 15 ++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index e9cfd05007a..f51fc414941 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -432,6 +432,25 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() deleteLater(); } +/*! + \internal + \return \c true if the group window has at least one visible QDockWidget child, + otherwise false. + */ +bool QDockWidgetGroupWindow::hasVisibleDockWidgets() const +{ + const auto &children = findChildren(Qt::FindChildrenRecursively); + for (auto child : children) { + // WA_WState_Visible is set on the dock widget, associated to the active tab + // and unset on all others. + // WA_WState_Hidden is set if the dock widgets have been explicitly hidden. + // This is the relevant information to check (equivalent to !child->isHidden()). + if (!child->testAttribute(Qt::WA_WState_Hidden)) + return true; + } + return false; +} + /*! \internal Sets the flags of this window in accordance to the capabilities of the dock widgets */ @@ -480,7 +499,7 @@ void QDockWidgetGroupWindow::adjustFlags() m_removedFrameSize = QSize(); } - show(); // setWindowFlags hides the window + setVisible(hasVisibleDockWidgets()); } QWidget *titleBarOf = top ? top : parentWidget(); diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index e3d1bb1eeb1..f09c9e82f43 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -316,6 +316,7 @@ public: QDockWidget *activeTabbedDockWidget() const; #endif void destroyOrHideIfEmpty(); + bool hasVisibleDockWidgets() const; void adjustFlags(); bool hasNativeDecos() const; diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index a91ea4a37a6..0de5fadfc53 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -1362,8 +1362,6 @@ void tst_QDockWidget::floatingTabs() // Both dock widgets must no longer be floating // disabled due to flakiness on macOS and Windows - //QTRY_VERIFY(!d1->isFloating()); - //QTRY_VERIFY(!d2->isFloating()); if (d1->isFloating()) qWarning("OS flakiness: D1 is docked and reports being floating"); if (d2->isFloating()) @@ -1371,7 +1369,18 @@ void tst_QDockWidget::floatingTabs() // Now MainWindow has to have a floatingTab child QPointer ftabs; - QTRY_VERIFY(checkFloatingTabs(mainWindow, ftabs, QList() << d1 << d2)); + QTRY_VERIFY(checkFloatingTabs(mainWindow, ftabs, QList() << d1 << d2)); + + // Hide both dock widgets. Verify that the group window is also hidden. + qCDebug(lcTestDockWidget) << "*** Hide and show tabbed dock widgets ***"; + d1->hide(); + d2->hide(); + QTRY_VERIFY(ftabs->isHidden()); + + // Show both dockwidgets again. Verify that the group window is visible. + d1->show(); + d2->show(); + QTRY_VERIFY(ftabs->isVisible()); /* * replug both dock widgets into their initial position