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).
This commit is contained in:
Lee Jae-Jin
2026-04-05 16:03:15 +09:00
committed by GitHub
parent 4a0b636148
commit 7b30229355
3 changed files with 66 additions and 3 deletions

View File

@@ -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);
}

View File

@@ -96,6 +96,7 @@ struct DockWidgetPrivate
WidgetFactory* Factory = nullptr;
QPointer<CAutoHideTab> 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);
}
}

View File

@@ -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