From 7ac9a66110b5a336bb602111a5bd3bd21631d70d Mon Sep 17 00:00:00 2001 From: Misaki Date: Sat, 28 Mar 2026 17:23:49 +0900 Subject: [PATCH] fix(dock): complete TabTearOffService migration and restore transactional integrity --- .../Controls/Internal/Docking/TabTearOffService.cs | 1 - src/Editor/Ghost.Editor/View/Controls/DockLayout.cs | 7 ++++++- .../Ghost.Editor/View/Windows/DockWindow.xaml.cs | 11 +---------- .../View/Windows/EngineEditorWindow.xaml.cs | 1 + 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Editor/Ghost.Editor.Core/Controls/Internal/Docking/TabTearOffService.cs b/src/Editor/Ghost.Editor.Core/Controls/Internal/Docking/TabTearOffService.cs index ce3b5de..ef86d27 100644 --- a/src/Editor/Ghost.Editor.Core/Controls/Internal/Docking/TabTearOffService.cs +++ b/src/Editor/Ghost.Editor.Core/Controls/Internal/Docking/TabTearOffService.cs @@ -72,7 +72,6 @@ internal static class TabTearOffService private static void RestoreSelection(object? container, object? selection) { - if (selection == null) return; if (container is DockPanelNode panel) panel.SelectedItem = selection; else if (container is TabView tabView) tabView.SelectedItem = selection; } diff --git a/src/Editor/Ghost.Editor/View/Controls/DockLayout.cs b/src/Editor/Ghost.Editor/View/Controls/DockLayout.cs index 83bbaf0..3546cc6 100644 --- a/src/Editor/Ghost.Editor/View/Controls/DockLayout.cs +++ b/src/Editor/Ghost.Editor/View/Controls/DockLayout.cs @@ -436,8 +436,13 @@ public sealed partial class DockLayout : Control { var result = TabTearOffService.TryTearOffTab(sourceNode.Items, args.Item, (tab) => { + if (TabTornOff == null) + { + throw new InvalidOperationException("No tear-off handler attached."); + } + // Raise event to let the host handle window creation - TabTornOff?.Invoke(this, new TabTornOffEventArgs(tab, sourceNode)); + TabTornOff.Invoke(this, new TabTornOffEventArgs(tab, sourceNode)); }, sourceNode); if (result.IsSuccess) diff --git a/src/Editor/Ghost.Editor/View/Windows/DockWindow.xaml.cs b/src/Editor/Ghost.Editor/View/Windows/DockWindow.xaml.cs index d2c36d9..ae73433 100644 --- a/src/Editor/Ghost.Editor/View/Windows/DockWindow.xaml.cs +++ b/src/Editor/Ghost.Editor/View/Windows/DockWindow.xaml.cs @@ -23,15 +23,6 @@ internal sealed partial class DockWindow : WindowEx private void OnTabTornOff(object? sender, TabTornOffEventArgs e) { - try - { - App.CreateAndShowDockWindow(e.TabContent); - } - catch (Exception ex) - { - Logger.LogError(ex); - // The service handles rollback if this was called from TryTearOffTab - throw; - } + App.CreateAndShowDockWindow(e.TabContent); } } diff --git a/src/Editor/Ghost.Editor/View/Windows/EngineEditorWindow.xaml.cs b/src/Editor/Ghost.Editor/View/Windows/EngineEditorWindow.xaml.cs index 77fb606..6192c45 100644 --- a/src/Editor/Ghost.Editor/View/Windows/EngineEditorWindow.xaml.cs +++ b/src/Editor/Ghost.Editor/View/Windows/EngineEditorWindow.xaml.cs @@ -2,6 +2,7 @@ using Ghost.Core; using Ghost.Editor.Core; using Ghost.Editor.Core.Contracts; using Ghost.Editor.Core.Services; +using Ghost.Editor.Core.Controls.Internal.Docking; using Ghost.Editor.View.Controls; using Ghost.Editor.ViewModels.Windows; using Windows.ApplicationModel;