From 7b3022935506c7a333d6fab63315c638e6dee7ca Mon Sep 17 00:00:00 2001 From: Lee Jae-Jin <35155988+EEager@users.noreply.github.com> Date: Sun, 5 Apr 2026 16:03:15 +0900 Subject: [PATCH] feat: add preferred auto-hide sidebar location per dock widget (#829) Add preferredAutoHideSideBarLocation property to CDockWidget that allows applications to specify where a widget should be pinned, overriding geometry-based detection. When unpinning, widgets with the same preferred location merge as tabs instead of creating new splits. Default is SideBarNone (existing geometry-based behavior preserved). --- src/AutoHideDockContainer.cpp | 26 +++++++++++++++++++++++++- src/DockWidget.cpp | 27 +++++++++++++++++++++++++-- src/DockWidget.h | 16 ++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/AutoHideDockContainer.cpp b/src/AutoHideDockContainer.cpp index b509809..1909ad5 100644 --- a/src/AutoHideDockContainer.cpp +++ b/src/AutoHideDockContainer.cpp @@ -415,7 +415,31 @@ void CAutoHideDockContainer::moveContentsToParent() // to the user and he does not have to search where the widget was inserted. d->DockWidget->setDockArea(nullptr); auto DockContainer = dockContainer(); - DockContainer->addDockWidget(d->getDockWidgetArea(d->SideTabBarArea), d->DockWidget); + auto targetArea = d->getDockWidgetArea(d->SideTabBarArea); + + // If the widget has a preferred auto-hide location, try to find an existing + // opened dock area that contains a widget with the same preferred location + // and merge as a tab instead of creating a new split. + auto preferred = d->DockWidget->preferredAutoHideSideBarLocation(); + if (preferred != SideBarNone) + { + for (auto area : DockContainer->openedDockAreas()) + { + if (!area || area->isAutoHide()) continue; + // Check if any widget in this area has the same preferred location + for (auto dw : area->dockWidgets()) + { + if (dw && dw->preferredAutoHideSideBarLocation() == preferred) + { + DockContainer->addDockWidget(CenterDockWidgetArea, + d->DockWidget, area); + return; + } + } + } + } + + DockContainer->addDockWidget(targetArea, d->DockWidget); } diff --git a/src/DockWidget.cpp b/src/DockWidget.cpp index d0168a8..9701124 100644 --- a/src/DockWidget.cpp +++ b/src/DockWidget.cpp @@ -96,7 +96,8 @@ struct DockWidgetPrivate WidgetFactory* Factory = nullptr; QPointer SideTabWidget; CDockWidget::eToolBarStyleSource ToolBarStyleSource = CDockWidget::ToolBarStyleFromDockManager; - + SideBarLocation PreferredAutoHideSideBarLocation = SideBarNone; + /** * Private data constructor */ @@ -654,6 +655,20 @@ SideBarLocation CDockWidget::autoHideLocation() const } +//============================================================================ +void CDockWidget::setPreferredAutoHideSideBarLocation(SideBarLocation Location) +{ + d->PreferredAutoHideSideBarLocation = Location; +} + + +//============================================================================ +SideBarLocation CDockWidget::preferredAutoHideSideBarLocation() const +{ + return d->PreferredAutoHideSideBarLocation; +} + + //============================================================================ bool CDockWidget::isFloating() const { @@ -1337,7 +1352,15 @@ void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabInde } else { - auto area = (SideBarNone == Location) ? DockArea->calculateSideTabBarArea() : Location; + auto area = Location; + if (SideBarNone == area && d->PreferredAutoHideSideBarLocation != SideBarNone) + { + area = d->PreferredAutoHideSideBarLocation; + } + else if (SideBarNone == area) + { + area = DockArea->calculateSideTabBarArea(); + } dockContainer()->createAndSetupAutoHideContainer(area, this, TabIndex); } } diff --git a/src/DockWidget.h b/src/DockWidget.h index 47c015d..04bec34 100644 --- a/src/DockWidget.h +++ b/src/DockWidget.h @@ -422,6 +422,22 @@ public: */ SideBarLocation autoHideLocation() const; + /** + * Sets the preferred auto-hide sidebar location for this dock widget. + * When set to a value other than SideBarNone, the pin button will place + * this widget in the specified sidebar instead of using geometry-based + * detection. When unpinning, widgets with the same preferred location + * will be merged as tabs in the same dock area. + * Set to SideBarNone (default) to use the original geometry-based behavior. + */ + void setPreferredAutoHideSideBarLocation(SideBarLocation Location); + + /** + * Returns the preferred auto-hide sidebar location, or SideBarNone + * if no preference is set (geometry-based detection will be used). + */ + SideBarLocation preferredAutoHideSideBarLocation() const; + /** * This property holds whether the dock widget is floating. * A dock widget is only floating, if it is the one and only widget inside