diff --git a/ILSpy.Tests/Views/DebugStepsTests.cs b/ILSpy.Tests/Views/DebugStepsTests.cs index ca20fab15..cfd26b49b 100644 --- a/ILSpy.Tests/Views/DebugStepsTests.cs +++ b/ILSpy.Tests/Views/DebugStepsTests.cs @@ -133,6 +133,28 @@ public class DebugStepsTests languageService.Languages.Should().Contain(l => l.Name == "Typed IL"); return Task.CompletedTask; } + [AvaloniaTest] + public async Task Window_Menu_Toggle_Surfaces_The_Default_Hidden_Debug_Steps_Pane() + { + // Repro of "Window > Debug Steps does nothing": the menu toggles ToolPaneMenuItem.IsPaneVisible, + // which used factory.RestoreDockable — a no-op for a pane that is hidden by default (never + // placed in the layout, so there's nothing to restore). Toggling it on must actually surface + // the pane (ShowToolPane materialises it and creates its home dock). + var window = AppComposition.Current.GetExport(); + window.Show(); + var vm = (MainWindowViewModel)window.DataContext!; + await vm.AssemblyTreeModel.WaitForAssembliesAsync(minimumCount: 1); + + var menuItem = vm.DockWorkspace.ToolPaneMenuItems + .Single(p => p.Title == "Debug Steps"); + menuItem.IsPaneVisible.Should().BeFalse("Debug Steps is hidden by default"); + + menuItem.IsPaneVisible = true; + + menuItem.IsPaneVisible.Should().BeTrue( + "toggling Window > Debug Steps on must make the pane visible in the layout"); + } + } #endif diff --git a/ILSpy/ViewModels/ToolPaneMenuItem.cs b/ILSpy/ViewModels/ToolPaneMenuItem.cs index 66d1a5791..4f92fbf3c 100644 --- a/ILSpy/ViewModels/ToolPaneMenuItem.cs +++ b/ILSpy/ViewModels/ToolPaneMenuItem.cs @@ -39,12 +39,27 @@ namespace ILSpy.ViewModels public string? Title => pane.Title; public bool IsPaneVisible { - get => pane.Owner is not IRootDock; + // Visible only when the pane currently sits in a real (non-root) dock's visible + // dockables. A pane that is hidden by default and never shown has a null Owner — the + // old `Owner is not IRootDock` test reported that as visible, so the Window-menu toggle + // thought it was already open and "closed" it (a no-op) instead of showing it. + get => pane.Owner is IDock owner + && owner is not IRootDock + && owner.VisibleDockables?.Contains(pane) == true; set { if (value == IsPaneVisible) return; if (value) - factory.RestoreDockable(pane); + { + // RestoreDockable only un-hides a dockable that was previously shown and then + // hidden; a pane that is hidden by default (e.g. Debug Steps) was never placed in + // the layout, so there is nothing to restore. ShowToolPane materialises the pane + // AND (re)creates its home dock, so it works in both cases. + if (factory is Docking.ILSpyDockFactory ilspyFactory) + ilspyFactory.ShowToolPane(pane.Id); + else + factory.RestoreDockable(pane); + } else factory.HideDockable(pane); OnPropertyChanged();