From f360e4a0563187bd88ddbd5f18e7cd56abd0b21d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 9 Jun 2026 13:35:59 +0200 Subject: [PATCH] Pair dockable activation and focus in ActivateAndFocus SetActiveDockable + SetFocusedDockable were always called together at five sites across the factory and the workspace. Fold the pair into one factory method so the invariant (a surfaced dockable is also focused) is expressed once; the per-site "add to the dock first" step, which varies (unconditional / only-if-absent / none), stays at the call site. Assisted-by: Claude:claude-opus-4-8:Claude Code --- ILSpy/Docking/DockWorkspace.cs | 9 +++------ ILSpy/Docking/ILSpyDockFactory.cs | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ILSpy/Docking/DockWorkspace.cs b/ILSpy/Docking/DockWorkspace.cs index 3731dfe84..1c9160f84 100644 --- a/ILSpy/Docking/DockWorkspace.cs +++ b/ILSpy/Docking/DockWorkspace.cs @@ -1137,8 +1137,7 @@ namespace ILSpy.Docking if (factory.Documents != null) { factory.AddDockable(factory.Documents, tab); - factory.SetActiveDockable(tab); - factory.SetFocusedDockable(factory.Documents, tab); + factory.ActivateAndFocus(factory.Documents, tab); } return tab; } @@ -1169,8 +1168,7 @@ namespace ILSpy.Docking return; if (docs.VisibleDockables?.Contains(tab) != true) factory.AddDockable(docs, tab); - factory.SetActiveDockable(tab); - factory.SetFocusedDockable(docs, tab); + factory.ActivateAndFocus(docs, tab); } /// @@ -1221,8 +1219,7 @@ namespace ILSpy.Docking { if (docs.VisibleDockables?.Contains(main) != true) return false; - factory.SetActiveDockable(main); - factory.SetFocusedDockable(docs, main); + factory.ActivateAndFocus(docs, main); } return true; } diff --git a/ILSpy/Docking/ILSpyDockFactory.cs b/ILSpy/Docking/ILSpyDockFactory.cs index 379eaf0ec..141a09e51 100644 --- a/ILSpy/Docking/ILSpyDockFactory.cs +++ b/ILSpy/Docking/ILSpyDockFactory.cs @@ -460,6 +460,18 @@ namespace ILSpy.Docking _ => ("BottomTools", Alignment.Bottom, 0.2), }; + /// + /// Makes both the active and the focused dockable within + /// . The two always go together -- surfacing a dockable without + /// focusing it (or vice versa) is a half-done activation -- so they're paired here and + /// callers do the (varying) "add it to the dock first" step themselves. + /// + public void ActivateAndFocus(IDock owner, IDockable dockable) + { + SetActiveDockable(dockable); + SetFocusedDockable(owner, dockable); + } + /// /// Brings a tool pane into view: activates it if it is already shown, otherwise /// materialises it -- (re)creating its home at the pane's @@ -477,8 +489,7 @@ namespace ILSpy.Docking // Already live in the layout -> just activate it where it sits. if (pane.Owner is IDock current && current.VisibleDockables?.Contains(pane) == true) { - SetActiveDockable(pane); - SetFocusedDockable(current, pane); + ActivateAndFocus(current, pane); return pane; } @@ -486,8 +497,7 @@ namespace ILSpy.Docking if (dock is null) return pane; AddDockable(dock, pane); - SetActiveDockable(pane); - SetFocusedDockable(dock, pane); + ActivateAndFocus(dock, pane); return pane; }