diff --git a/src/Dock.Model/FactoryBase.Dockable.cs b/src/Dock.Model/FactoryBase.Dockable.cs
index 154d990b4..731321fa7 100644
--- a/src/Dock.Model/FactoryBase.Dockable.cs
+++ b/src/Dock.Model/FactoryBase.Dockable.cs
@@ -47,6 +47,11 @@ public virtual void RemoveDockable(IDockable dockable, bool collapse)
var index = dock.VisibleDockables.IndexOf(dockable);
if (index < 0)
{
+ if (FindRoot(dockable, x => x.IsFocusableRoot) is { } root &&
+ ReferenceEquals(root.FocusedDockable, dockable))
+ {
+ SetFocusedDockable(dock, dock.ActiveDockable);
+ }
return;
}
@@ -69,6 +74,12 @@ public virtual void RemoveDockable(IDockable dockable, bool collapse)
}
}
+ if (FindRoot(dockable, x => x.IsFocusableRoot) is { } rootDock &&
+ ReferenceEquals(rootDock.FocusedDockable, dockable))
+ {
+ SetFocusedDockable(dock, dock.ActiveDockable);
+ }
+
// Clean up orphaned splitters
CleanupOrphanedSplitters(dock);
diff --git a/src/Dock.Model/FactoryBase.Init.cs b/src/Dock.Model/FactoryBase.Init.cs
index e73e47d0b..d43247902 100644
--- a/src/Dock.Model/FactoryBase.Init.cs
+++ b/src/Dock.Model/FactoryBase.Init.cs
@@ -275,47 +275,53 @@ private void SetIsActive(IDockable dockable, bool active)
///
public virtual void SetFocusedDockable(IDock dock, IDockable? dockable)
{
- if (dock.ActiveDockable is not null && FindRoot(dock.ActiveDockable, x => x.IsFocusableRoot) is { } root)
+ if (FindRoot(dock, x => x.IsFocusableRoot) is not { } root)
{
- if (dockable is not null)
- {
- var results = Find(x => x is IRootDock);
+ return;
+ }
- foreach (var result in results)
+ if (dockable is not null)
+ {
+ var results = Find(x => x is IRootDock);
+
+ foreach (var result in results)
+ {
+ if (result is IRootDock rootDock
+ && rootDock.IsFocusableRoot
+ && rootDock != root)
{
- if (result is IRootDock rootDock
- && rootDock.IsFocusableRoot
- && rootDock != root)
+ if (rootDock.FocusedDockable?.Owner is not null)
{
- if (rootDock.FocusedDockable?.Owner is not null)
- {
- SetIsActive(rootDock.FocusedDockable.Owner, false);
- // Trigger deactivation event for the dockable that lost focus
- OnDockableDeactivated(rootDock.FocusedDockable);
- }
+ SetIsActive(rootDock.FocusedDockable.Owner, false);
+ // Trigger deactivation event for the dockable that lost focus
+ OnDockableDeactivated(rootDock.FocusedDockable);
}
}
}
+ }
- if (root.FocusedDockable?.Owner is not null)
- {
- SetIsActive(root.FocusedDockable.Owner, false);
- // Trigger deactivation event for the dockable that lost focus
- OnDockableDeactivated(root.FocusedDockable);
- }
+ if (root.FocusedDockable?.Owner is not null)
+ {
+ SetIsActive(root.FocusedDockable.Owner, false);
+ // Trigger deactivation event for the dockable that lost focus
+ OnDockableDeactivated(root.FocusedDockable);
+ }
- if (dockable is not null)
+ if (dockable is not null)
+ {
+ if (root.FocusedDockable != dockable)
{
- if (root.FocusedDockable != dockable)
- {
- root.FocusedDockable = dockable;
- }
+ root.FocusedDockable = dockable;
}
+ }
+ else
+ {
+ root.FocusedDockable = null;
+ }
- if (root.FocusedDockable?.Owner is not null)
- {
- SetIsActive(root.FocusedDockable.Owner, true);
- }
+ if (root.FocusedDockable?.Owner is not null)
+ {
+ SetIsActive(root.FocusedDockable.Owner, true);
}
}
}
diff --git a/tests/Dock.Avalonia.HeadlessTests/FactoryDockableLifecycleTests.cs b/tests/Dock.Avalonia.HeadlessTests/FactoryDockableLifecycleTests.cs
index c99c7b345..be42e9e16 100644
--- a/tests/Dock.Avalonia.HeadlessTests/FactoryDockableLifecycleTests.cs
+++ b/tests/Dock.Avalonia.HeadlessTests/FactoryDockableLifecycleTests.cs
@@ -104,4 +104,25 @@ public void CloseDockable_Active_Selects_Neighbour()
Assert.Same(doc2, dock.ActiveDockable);
Assert.Single(dock.VisibleDockables!);
}
+
+ [AvaloniaFact]
+ public void CloseDockable_Active_Clears_FocusedDockable()
+ {
+ var factory = new Factory();
+ var root = new RootDock { VisibleDockables = factory.CreateList() };
+ root.Factory = factory;
+
+ var doc = new Document();
+ factory.AddDockable(root, doc);
+
+ root.ActiveDockable = doc;
+
+ Assert.Same(doc, root.FocusedDockable);
+
+ factory.CloseDockable(doc);
+
+ Assert.Null(root.ActiveDockable);
+ Assert.Null(root.FocusedDockable);
+ Assert.Empty(root.VisibleDockables!);
+ }
}