diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index a62a0ce0f3..1c6903a552 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -44,15 +44,15 @@ using ICSharpCode.Decompiler.Documentation; using ICSharpCode.Decompiler.TypeSystem.Implementation; using System.Reflection.Metadata; +using System.Text; +using System.Windows.Navigation; using ICSharpCode.ILSpy.AppEnv; using ICSharpCode.ILSpy.Search; using ICSharpCode.Decompiler; -using System.Text; using TomsToolbox.Essentials; using TomsToolbox.Wpf; -using System.Windows.Navigation; namespace ICSharpCode.ILSpy.AssemblyTree { @@ -67,6 +67,7 @@ public class AssemblyTreeModel : ToolPaneModel AssemblyListTreeNode assemblyListTreeNode; readonly NavigationHistory history = new(); + private bool isNavigatingHistory; public AssemblyTreeModel() { @@ -78,7 +79,7 @@ public AssemblyTreeModel() MessageBus.Subscribers += JumpToReference; MessageBus.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e); - var selectionChangeThrottle = new DispatcherThrottle(DispatcherPriority.Background, TreeView_SelectionChanged); + var selectionChangeThrottle = new DispatcherThrottle(DispatcherPriority.Input, TreeView_SelectionChanged); SelectedItems.CollectionChanged += (_, _) => selectionChangeThrottle.Tick(); } @@ -94,8 +95,7 @@ private void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e) case nameof(SessionSettings.Theme): // update syntax highlighting and force reload (AvalonEdit does not automatically refresh on highlighting change) DecompilerTextView.RegisterHighlighting(); - DecompileSelectedNodes( - DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState); + DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState); break; case nameof(SessionSettings.CurrentCulture): MessageBox.Show(Properties.Resources.SettingsChangeRestartRequired, "ILSpy"); @@ -107,7 +107,7 @@ private void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e) switch (e.PropertyName) { case nameof(LanguageSettings.Language) or nameof(LanguageSettings.LanguageVersion): - DecompileSelectedNodes(recordHistory: false); + DecompileSelectedNodes(); break; } } @@ -502,36 +502,26 @@ public void SelectNode(SharpTreeNode node, bool inNewTabPage = false) } } - internal void SelectNodes(IEnumerable nodes, bool ignoreCompilationRequests = false) + internal void SelectNodes(IEnumerable nodes) { - this.ignoreDecompilationRequests = ignoreCompilationRequests; + // Ensure nodes exist + var nodesList = nodes.Select(n => FindNodeByPath(GetPathForNode(n), true)) + .Where(n => n != null) + .ToArray(); - try + if (!nodesList.Any() || nodesList.Any(n => n.AncestorsAndSelf().Any(a => a.IsHidden))) { - // Ensure nodes exist - var nodesList = nodes.Select(n => FindNodeByPath(GetPathForNode(n), true)) - .Where(n => n != null) - .ToArray(); - - if (!nodesList.Any() || nodesList.Any(n => n.AncestorsAndSelf().Any(a => a.IsHidden))) - { - return; - } - - if (SelectedItems.SequenceEqual(nodesList)) - { - Dispatcher.BeginInvoke(RefreshDecompiledView); - return; - } - - SelectedItems.Clear(); - SelectedItems.AddRange(nodesList); + return; } - finally + + if (SelectedItems.SequenceEqual(nodesList)) { - this.ignoreDecompilationRequests = false; + Dispatcher.BeginInvoke(RefreshDecompiledView); + return; } + SelectedItems.Clear(); + SelectedItems.AddRange(nodesList); } /// @@ -700,15 +690,27 @@ public void LoadAssemblies(IEnumerable fileNames, List l void TreeView_SelectionChanged() { - var delayDecompilationRequestDueToContextMenu = Mouse.RightButton == MouseButtonState.Pressed; - - if (!delayDecompilationRequestDueToContextMenu) - { - DecompileSelectedNodes(); - } - else + if (SelectedItems.Count > 0) { - ContextMenuProvider.ContextMenuClosed += ContextMenuClosed; + if (!isNavigatingHistory) + { + var activeTabPage = DockWorkspace.Instance.ActiveTabPage; + var currentState = activeTabPage.GetState(); + if (currentState != null) + history.UpdateCurrent(new NavigationState(activeTabPage, currentState)); + history.Record(new NavigationState(activeTabPage, SelectedItems)); + } + + var delayDecompilationRequestDueToContextMenu = Mouse.RightButton == MouseButtonState.Pressed; + + if (!delayDecompilationRequestDueToContextMenu) + { + DecompileSelectedNodes(); + } + else + { + ContextMenuProvider.ContextMenuClosed += ContextMenuClosed; + } } MessageBus.Send(this, new AssemblyTreeSelectionChangedEventArgs()); @@ -728,23 +730,10 @@ void ContextMenuClosed(object sender, EventArgs e) } } - private bool ignoreDecompilationRequests; - - public void DecompileSelectedNodes(DecompilerTextViewState newState = null, bool recordHistory = true) + private void DecompileSelectedNodes(DecompilerTextViewState newState = null) { - if (ignoreDecompilationRequests) - return; - var activeTabPage = DockWorkspace.Instance.ActiveTabPage; - if (recordHistory) - { - var currentState = activeTabPage.GetState(); - if (currentState != null) - history.UpdateCurrent(new NavigationState(activeTabPage, currentState)); - history.Record(new NavigationState(activeTabPage, SelectedItems)); - } - activeTabPage.SupportsLanguageSwitching = true; if (SelectedItems.Count == 1) @@ -754,7 +743,7 @@ public void DecompileSelectedNodes(DecompilerTextViewState newState = null, bool } if (newState?.ViewedUri != null) { - MainWindow.Instance.AssemblyTreeModel.NavigateTo(new(newState.ViewedUri, null), recordHistory: false); + NavigateTo(new(newState.ViewedUri, null), recordHistory: false); return; } @@ -782,6 +771,9 @@ public IEnumerable SelectedNodes { public void NavigateHistory(bool forward) { + isNavigatingHistory = true; + this.Dispatcher.BeginInvoke(DispatcherPriority.Background, () => isNavigatingHistory = false); + TabPageModel tabPage = DockWorkspace.Instance.ActiveTabPage; var state = tabPage.GetState(); if (state != null) @@ -790,8 +782,7 @@ public void NavigateHistory(bool forward) DockWorkspace.Instance.ActiveTabPage = newState.TabPage; - SelectNodes(newState.TreeNodes, ignoreCompilationRequests: true); - DecompileSelectedNodes(newState.ViewState as DecompilerTextViewState, false); + SelectNodes(newState.TreeNodes); } public bool CanNavigateBack => history.CanNavigateBack; @@ -814,6 +805,7 @@ internal void NavigateTo(RequestNavigateEventArgs e, bool recordHistory = true, e.Handled = true; return; } + AvalonEditTextOutput output = new AvalonEditTextOutput { Address = e.Uri, Title = e.Uri.AbsolutePath, @@ -845,7 +837,7 @@ void RecordHistory() if (currentState != null) history.UpdateCurrent(new NavigationState(tabPage, currentState)); - UnselectAll(ignoreCompilationRequests: true); + UnselectAll(); history.Record(new NavigationState(tabPage, new ViewState { ViewedUri = e.Uri })); } @@ -861,11 +853,9 @@ public void Refresh() } } - public void UnselectAll(bool ignoreCompilationRequests = false) + private void UnselectAll() { - this.ignoreDecompilationRequests = ignoreCompilationRequests; SelectedItems.Clear(); - this.ignoreDecompilationRequests = false; } public IEnumerable GetTopLevelSelection() diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml index 6979e2e8c4..dcc13af3b0 100644 --- a/ILSpy/MainWindow.xaml +++ b/ILSpy/MainWindow.xaml @@ -37,6 +37,7 @@ +