Skip to content

Fix four Avalonia UI regressions: mouse navigation, derived types, Enter activation, Delete - #4039

Open
christophwille wants to merge 4 commits into
masterfrom
fix/ui-regressions-4027-4028-4030
Open

Fix four Avalonia UI regressions: mouse navigation, derived types, Enter activation, Delete#4039
christophwille wants to merge 4 commits into
masterfrom
fix/ui-regressions-4027-4028-4030

Conversation

@christophwille

@christophwille christophwille commented Aug 20, 2026

Copy link
Copy Markdown
Member

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/BrowseForward commands by itself; 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 XButton1/XButton2 to the existing DockWorkspace.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.Filter reported FilterResult.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. Reporting Match (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 ListBoxItem as selection input and mark the KeyDown handled before it bubbles, so the activation handling in SharpTreeView.OnKeyDown (navigate to the member from an analyzer row, toggle a checkable row) never saw those keys. SharpTreeView now overrides ShouldTriggerSelection — the Avalonia 12 extension point for exactly this — to suppress the selection trigger precisely 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.

Delete does nothing on a selected analyzer row (#4030, follow-up report)

The WPF SharpTreeView bound ApplicationCommands.Delete at class level, so Delete removed the top-level selection of any tree whose nodes opt in through 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. The gesture now lives in SharpTreeView.OnKeyDown again (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.Tests suite 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.

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
@christophwille christophwille changed the title Fix three Avalonia UI regressions: mouse navigation, derived types, Enter activation Fix four Avalonia UI regressions: mouse navigation, derived types, Enter activation, Delete Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Enter" key now does nothing in Analyzer pane Derived types do not shown in tree. Mouse4 and Mouse5 no longer work as back and forward.

1 participant