Fix four Avalonia UI regressions: mouse navigation, derived types, Enter activation, Delete - #4039
Open
christophwille wants to merge 4 commits into
Open
Fix four Avalonia UI regressions: mouse navigation, derived types, Enter activation, Delete#4039christophwille wants to merge 4 commits into
christophwille wants to merge 4 commits into
Conversation
DerivedTypesEntryNode.Filter reported Recurse, but the cascade's Recurse handling force-loads the entry's lazy children and hides the entry when all of them are hidden. A leaf derived type has no children, so every entry under "Derived Types" ended up hidden, and the hiding propagated up the whole derived chain. The WPF tree showed these entries as matches; Match restores that and also keeps the entries' children lazy instead of eagerly scanning the assembly list for each level of the chain. Assisted-by: Claude:claude-fable-5:Claude Code
Avalonia 12 treats plain Enter/Space on a ListBoxItem as selection input: the container marks the KeyDown handled before it bubbles, so SharpTreeView.OnKeyDown never saw the keys and its activation handling (navigate to the member from an analyzer row, toggle a checkable row) was dead. Override ShouldTriggerSelection -- the extension point added for this in Avalonia 12 -- to suppress the selection trigger exactly for the case OnKeyDown activates instead: a single selected row that is the row the key landed on. Multi-row selections keep the default collapse-to-focused-row behaviour. Assisted-by: Claude:claude-fable-5:Claude Code
WPF translated XButton1/XButton2 into BrowseBack/BrowseForward commands by itself, so the WPF frontend got the behaviour for free. Avalonia has no such translation and KeyBinding cannot express pointer buttons, so only Alt+Left / Alt+Right survived the migration. MainWindow now listens window-wide for PointerReleased and routes the X buttons to the existing DockWorkspace navigation commands (handledEventsToo, because inner controls handle pointer events for their own gestures without ever using the X buttons). Assisted-by: Claude:claude-fable-5:Claude Code
The WPF SharpTreeView bound ApplicationCommands.Delete at class level, so Delete deleted the top-level selection of any tree whose nodes opt in via CanDelete/Delete -- which is how a top-level analyzer entry was removed from the Analyzer pane. The Avalonia tree never received that binding; only the assembly list pane carried a hand-rolled Delete handler for assemblies, so the analyzer pane lost the key entirely even though its nodes still implement the deletion overrides. Moving the gesture back into SharpTreeView restores it for every tree and lets the pane-specific handler (with its own reselect logic) go. Assisted-by: Claude:claude-fable-5:Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four UI regressions from the Avalonia migration (the fourth, Delete in the Analyzer pane, was reported in the #4030 thread), one commit each, each with a headless regression test that was shown red before the fix.
Fixes #4027
Fixes #4028
Fixes #4030
Mouse4 / Mouse5 no longer navigate back / forward (#4027)
WPF translated the extra mouse buttons into
BrowseBack/BrowseForwardcommands by itself; Avalonia has no such translation andKeyBindingcannot express pointer buttons, so only Alt+Left / Alt+Right survived the migration.MainWindownow listens window-wide forPointerReleasedand routesXButton1/XButton2to the existingDockWorkspace.NavigateBackCommand/NavigateForwardCommand(handledEventsToo, since inner controls handle pointer events for their own gestures without ever using the X buttons).Derived types not shown in tree (#4028)
DerivedTypesEntryNode.FilterreportedFilterResult.Recurse, but the filter cascade's Recurse handling force-loads the node's lazy children and hides the node when all of them are hidden. A leaf derived type has no children, so every entry under "Derived Types" ended up hidden, and the hiding propagated up the whole chain. ReportingMatch(what the WPF tree effectively did, since the tree ignores the search term) restores the entries and also keeps derived chains lazy instead of eagerly scanning the assembly list for every level.Enter does nothing on a selected tree row (#4030)
Avalonia 12's default key selection triggers treat plain Enter/Space on a
ListBoxItemas selection input and mark theKeyDownhandled before it bubbles, so the activation handling inSharpTreeView.OnKeyDown(navigate to the member from an analyzer row, toggle a checkable row) never saw those keys.SharpTreeViewnow overridesShouldTriggerSelection— the Avalonia 12 extension point for exactly this — to suppress the selection trigger precisely for the caseOnKeyDownactivates instead: a single selected row that is the row the key landed on. Multi-row selections keep the default collapse-to-focused-row behaviour.Delete does nothing on a selected analyzer row (#4030, follow-up report)
The WPF
SharpTreeViewboundApplicationCommands.Deleteat class level, so Delete removed the top-level selection of any tree whose nodes opt in throughCanDelete/Delete-- which is how a top-level analyzer entry was removed from the Analyzer pane. The Avalonia tree never received that binding; only the assembly list pane carried a hand-rolled Delete handler for assemblies. The gesture now lives inSharpTreeView.OnKeyDownagain (delete the top-level selection when every node in it is deletable, then reselect the nearest survivor), which restores it for the analyzer pane and lets the pane-specific handler go.Verification
Full
ILSpy.Testssuite green locally, including the four new regression tests (Mouse_Back_And_Forward_Buttons_Navigate_The_History,Derived_Type_Entries_Stay_Visible_When_The_DerivedTypes_Node_Is_Expanded,Enter_Activates_The_Selected_Analyzer_Node,Delete_Removes_The_Selected_Top_Level_Analyzer_Node).Written by an AI agent (Claude) on Christoph's behalf.