summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qmainwindowlayout.cpp
diff options
context:
space:
mode:
authorAxel Spoerl <axel.spoerl@qt.io>2024-02-27 16:42:24 +0100
committerAxel Spoerl <axel.spoerl@qt.io>2024-02-29 21:14:40 +0000
commitcd2a3e970aaeb8f5f92d9c6e52ede7a82f953150 (patch)
tree56ec630d42c6164cc0dbee810ac592c23aba1451 /src/widgets/widgets/qmainwindowlayout.cpp
parent08dde3ac0c5005ee48848a6fac9d03fe1fe2f184 (diff)
Refactor and fix QMainWindow::tabifiedDockWidgets()
The method traversed QDockAreaLayoutInfo::item_list, to identify dock widgets tabbed with the QDockWidget argument in a tab bar It relied on bool QDockAreLayoutInfo::tabbed, which is set to true, when a QMainWindowTabBar is to be added to a QDockAreaLayoutInfo. This flag isn't cleared, when the second last dock widget is removed from the tab bar. It can't be replaced by QMainWindowLayout::isDockWidgetTabbed, because the flag also represents intermediate states, where e.g. a dock widget is hovered over, prepares to become a floating tab and then rolls back, because hovering doesn't result in a drop. In that case, tabbed must become true, which the dock widget isn't actually tabbed. Furthermore, the way to traverse item_list didn't find dock widgets in a floating tab. In that case, tabifiedDockWidgets() wrongly returned an empty list. To fix both issues, refactor QMainWindow::tabifiedDockWidgets() to read the list of dock widgets directly from the QMainWindowTabBar. Add tests in tst_QDockWidget::floatingTabs() and updateTabBarOnVisibilityChanged() Fixes: QTBUG-122001 Pick-to: 6.7 6.6 6.5 Change-Id: Ia9eb3711be642101261f34ee447521cc6accc20c Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout.cpp')
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp52
1 files changed, 39 insertions, 13 deletions
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 3933f2a7cd..e17fa28b83 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1885,6 +1885,7 @@ public:
~QMainWindowTabBar();
QDockWidget *dockAt(int index) const;
QList<QDockWidget *> dockWidgets() const;
+ bool contains(const QDockWidget *dockWidget) const;
protected:
bool event(QEvent *e) override;
void mouseReleaseEvent(QMouseEvent*) override;
@@ -1892,6 +1893,17 @@ protected:
};
+QMainWindowTabBar *QMainWindowLayout::findTabBar(const QDockWidget *dockWidget) const
+{
+ for (auto *bar : usedTabBars) {
+ Q_ASSERT(qobject_cast<QMainWindowTabBar *>(bar));
+ auto *tabBar = static_cast<QMainWindowTabBar *>(bar);
+ if (tabBar->contains(dockWidget))
+ return tabBar;
+ }
+ return nullptr;
+}
+
QMainWindowTabBar::QMainWindowTabBar(QMainWindow *parent)
: QTabBar(parent), mainWindow(parent)
{
@@ -1908,6 +1920,15 @@ QList<QDockWidget *> QMainWindowTabBar::dockWidgets() const
return docks;
}
+bool QMainWindowTabBar::contains(const QDockWidget *dockWidget) const
+{
+ for (int i = 0; i < count(); ++i) {
+ if (dockAt(i) == dockWidget)
+ return true;
+ }
+ return false;
+}
+
QDockWidget *QMainWindowTabBar::dockAt(int index) const
{
QMainWindowTabBar *that = const_cast<QMainWindowTabBar *>(this);
@@ -2011,21 +2032,26 @@ bool QMainWindowTabBar::event(QEvent *e)
return true;
}
+QList<QDockWidget *> QMainWindowLayout::tabifiedDockWidgets(const QDockWidget *dockWidget) const
+{
+ const auto *bar = findTabBar(dockWidget);
+ if (!bar)
+ return {};
+
+ QList<QDockWidget *> buddies = bar->dockWidgets();
+ // Return only other dock widgets associated with dockWidget in a tab bar.
+ // If dockWidget is alone in a tab bar, return an empty list.
+ buddies.removeOne(dockWidget);
+ return buddies;
+}
+
bool QMainWindowLayout::isDockWidgetTabbed(const QDockWidget *dockWidget) const
{
- for (auto *bar : std::as_const(usedTabBars)) {
- // A single dock widget in a tab bar is not considered to be tabbed.
- // This is to make sure, we don't drag an empty QDockWidgetGroupWindow around.
- // => only consider tab bars with two or more tabs.
- if (bar->count() <= 1)
- continue;
- auto *tabBar = qobject_cast<QMainWindowTabBar *>(bar);
- Q_ASSERT(tabBar);
- const auto dockWidgets = tabBar->dockWidgets();
- if (std::find(dockWidgets.begin(), dockWidgets.end(), dockWidget) != dockWidgets.end())
- return true;
- }
- return false;
+ // A single dock widget in a tab bar is not considered to be tabbed.
+ // This is to make sure, we don't drag an empty QDockWidgetGroupWindow around.
+ // => only consider tab bars with two or more tabs.
+ const auto *bar = findTabBar(dockWidget);
+ return bar && bar->count() > 1;
}
QTabBar *QMainWindowLayout::getTabBar()