Browse Source

Count document tabs globally for closable splits

UpdateLastDocumentCanClose was counting only factory.Documents.VisibleDockables
to decide CanClose. After the user drags a tab out into a side-by-side
split, Dock creates a second IDocumentDock that holds the dragged tab.
factory.Documents still points at the ORIGINAL dock (now with one tab),
so the handler updates CanClose=false on its remaining tab — but the
new sibling dock's tab keeps the CanClose=true it had before the drag.
Result: one tab closable, the other not, even though the user has two
documents open.

Assisted-by: Claude:claude-opus-4-7:Claude Code
pull/3755/head
Siegfried Pammer 2 months ago
parent
commit
a8f6522e91
  1. 31
      ILSpy/Docking/DockWorkspace.cs

31
ILSpy/Docking/DockWorkspace.cs

@ -267,19 +267,38 @@ namespace ILSpy.Docking
} }
} }
// When only one document is open, make it un-closeable so the user can't end up with an // When only one document is open across the entire workspace, make it un-closeable so
// empty document area. // the user can't end up with an empty document area. Counts across ALL IDocumentDocks
// in the layout tree — not just factory.Documents — so a split into side-by-side
// document docks (each with one tab) still lets the user close either one.
void UpdateLastDocumentCanClose() void UpdateLastDocumentCanClose()
{ {
var docs = factory.Documents?.VisibleDockables; if (Layout is not IDockable root)
if (docs == null)
return; return;
bool canClose = docs.Count > 1; var allDocs = FlattenDocumentDocks(root).ToList();
foreach (var d in docs) int totalTabs = allDocs.Sum(d => d.VisibleDockables?.Count ?? 0);
bool canClose = totalTabs > 1;
foreach (var dock in allDocs)
{
if (dock.VisibleDockables is { } kids)
{ {
foreach (var d in kids)
d.CanClose = canClose; d.CanClose = canClose;
} }
} }
}
static IEnumerable<IDocumentDock> FlattenDocumentDocks(IDockable root)
{
if (root is IDocumentDock doc)
yield return doc;
if (root is IDock dock && dock.VisibleDockables is { } kids)
{
foreach (var k in kids)
foreach (var d in FlattenDocumentDocks(k))
yield return d;
}
}
// Set true while syncing the tree's selection FROM the active tab so the // Set true while syncing the tree's selection FROM the active tab so the
// SelectionChanged handler doesn't bounce back into ShowSelectedNode and overwrite // SelectionChanged handler doesn't bounce back into ShowSelectedNode and overwrite

Loading…
Cancel
Save