fix(dock): decouple DockLayout from App and fix multi-window shutdown

This commit is contained in:
2026-03-28 15:56:53 +09:00
parent e83555498a
commit 8c136709ff
2 changed files with 23 additions and 5 deletions

View File

@@ -47,6 +47,10 @@ public partial class App : Application
app._secondaryWindows.Add(window); app._secondaryWindows.Add(window);
window.Closed += (s, e) => app._secondaryWindows.Remove(window); window.Closed += (s, e) => app._secondaryWindows.Remove(window);
} }
else
{
throw new InvalidOperationException("App instance is not available.");
}
} }
internal IHost Host internal IHost Host
@@ -151,6 +155,14 @@ public partial class App : Application
{ {
try try
{ {
// Close all secondary windows when the primary window closes
var secondaryWindows = _secondaryWindows.ToArray();
foreach (var window in secondaryWindows)
{
window.Close();
}
_secondaryWindows.Clear();
Host.StopAsync().GetAwaiter().GetResult(); Host.StopAsync().GetAwaiter().GetResult();
Host.Dispose(); Host.Dispose();
@@ -169,4 +181,4 @@ public partial class App : Application
Debugger.BreakForUserUnhandledException(e.Exception); Debugger.BreakForUserUnhandledException(e.Exception);
#endif #endif
} }
} }

View File

@@ -295,6 +295,8 @@ public sealed partial class DockLayout : Control
return tabView; return tabView;
} }
public event EventHandler<TabTornOffEventArgs>? TabTornOff;
private void TabView_TabDroppedOutside(Microsoft.UI.Xaml.Controls.TabView sender, Microsoft.UI.Xaml.Controls.TabViewTabDroppedOutsideEventArgs args) private void TabView_TabDroppedOutside(Microsoft.UI.Xaml.Controls.TabView sender, Microsoft.UI.Xaml.Controls.TabViewTabDroppedOutsideEventArgs args)
{ {
if (_sourceNode != null && _draggedItem != null) if (_sourceNode != null && _draggedItem != null)
@@ -304,16 +306,20 @@ public sealed partial class DockLayout : Control
{ {
DockMutationEngine.CleanupEmptyNodes(_sourceNode); DockMutationEngine.CleanupEmptyNodes(_sourceNode);
// Create new window and register it with App to prevent GC // Raise event to let the host handle window creation
var newWindow = new Ghost.Editor.View.Windows.DockWindow(_draggedItem); TabTornOff?.Invoke(this, new TabTornOffEventArgs(_draggedItem));
App.AddSecondaryWindow(newWindow);
newWindow.Activate();
} }
ClearDragOperationState(); ClearDragOperationState();
} }
} }
public class TabTornOffEventArgs : EventArgs
{
public object TabContent { get; }
public TabTornOffEventArgs(object tabContent) => TabContent = tabContent;
}
private object? _draggedItem; private object? _draggedItem;
private DockPanelNode? _sourceNode; private DockPanelNode? _sourceNode;
private DockPosition _currentDropPosition = DockPosition.None; private DockPosition _currentDropPosition = DockPosition.None;