Skip to content

Fix the Avalonia follow-ups from #4042 - #4218

Merged
siegfriedpammer merged 8 commits into
masterfrom
christophwille/avalonia-followups-4042
Oct 8, 2026
Merged

siegfriedpammer merged 8 commits into
masterfrom
christophwille/avalonia-followups-4042

Conversation

@christophwille

Copy link
Copy Markdown
Member

Works through the follow-ups collected in #4042 (plus the Tab-key comment on it), one commit per item.

# Item Outcome
1 Ctrl+R inside the Analyzer pane Fixed. The pane now carries its own KeyBinding; Avalonia walks KeyBindings from the focused element up to the window, so it wins while the focus is in the pane and falls through to the window binding otherwise. AnalyzeCommand takes the selection as its parameter so both bindings share one implementation.
2 Assembly-tree Ctrl+R bypasses the "Analyze" entry Already fixed by #4192; nothing to do.
3 Analyzer pane context menu targets the selection only Fixed. The right-click target / highlight / keyboard-menu focus restore moved out of AssemblyListPane into a TreeContextMenuController shared by both SharpTreeView panes; the .contextTarget style moved into the tree item theme.
4 "Remove" header not localised Fixed via nameof(Resources.Remove) (the string already existed).
5 IsVisible / IsEnabled asymmetry Fixed; IsEnabled now uses the same All shape.
6 Programmatic tree selection always focuses the row Fixed. TreeSelectionBinder only focuses the row when the tree already owns the keyboard focus (or nothing does yet); Back/Forward, search jumps, go-to-definition, tab activation and omnibar picks leave the focus alone. The Analyzer pane opts into always focusing, as its WPF counterpart did.
7 Dock re-focus on same-value SetActiveDockable Fixed centrally: ILSpyDockFactory.SetActiveDockable is a no-op for the already-active dockable, and the two caller-side guards are gone. ActivateAndFocus keeps its explicit SetFocusedDockable.
8 Middle button over the editor Scoped down: since #4175 a middle click on a reference opens it in a new tab, so the text area must keep seeing middle presses. Only the gutter margins (line numbers, fold markers, bookmarks) now ignore non-left presses, matching the WPF margins.
9 Tab cannot leave the code pane (comment) Fixed with AcceptsTab = false on the read-only editor, the equivalent of WPF ILSpy removing the TabForward/TabBackward commands.

Each item has a headless test that was red before its commit.

Tested with build.ps1 --no-restore and dotnet test --project ILSpy.Tests/ILSpy.Tests.csproj --report-trx (full run green; 4 pre-existing skips).

Assisted-by: Claude:claude-fable-5-1:Claude Code

🤖 Generated with Claude Code

AvaloniaEdit marks Tab handled while AcceptsTab is on, so the keyboard
focus could never leave the read-only editor. WPF ILSpy removed the
TabForward/TabBackward editing commands for the same reason.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
Every other context-menu entry names its header by resource key so the
menu builder can localise it; this one shipped the raw string, which
WPF ILSpy did as well. The "Remove" string already exists in the resx.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
IsVisible required every selected node to be a member node while
IsEnabled filtered to the member subset first, so a mixed selection
reported itself enabled-but-hidden. Hidden won, so nothing was visible
to the user, but the two predicates disagreed about the same selection.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
The assembly tree had Thunderbird-style context targeting (right-click a
row outside the selection without moving the selection, highlight the
target, re-focus the row after a keyboard-invoked menu); the Analyzer
pane only rebuilt the menu from its selection, so a right-click on
another row opened the menu for the previous selection. Hosting the
behaviour in one controller keyed on SharpTreeView gives both panes the
same gestures and keeps the assembly pane down to its middle-click
open-in-new-tab handler.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
The only Ctrl+R binding sat on the window and always analyzed the
assembly tree's selection, so pressing it on a result row in the
Analyzer pane promoted the wrong entity, or nothing. WPF ILSpy bound the
key on the pane as well. Avalonia walks KeyBindings from the focused
element up to the window, so a pane-level binding takes precedence while
the focus is in the pane and falls through when it has nothing to
analyze. The command takes the selection as its parameter so both
bindings share one implementation.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
The tree selection binder focused the selected row on every model-driven
change, so Back/Forward, search-result jumps, go-to-definition, tab
activation and omnibar picks all pulled the keyboard focus into the
assembly tree. WPF's SelectNodes only scrolled the row into view; the
row took the focus when the pane itself was activated. The binder now
checks where the keyboard focus sits when the selection changes and
leaves it alone unless the tree already holds it. The Analyzer pane
keeps focusing its row, as its WPF counterpart did on every selection
change, so an Analyze request still lands the user in the pane.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
Dock's ActiveDockable setter re-runs InitActiveDockable, and with it
SetFocusedDockable, even when the value does not change, so activating
the already-active document moved the active-pane highlight to the
documents dock. Two callers guarded against that individually; the
factory override does it for every caller, and ActivateAndFocus keeps
its explicit SetFocusedDockable for the callers that do want the focus.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
AvaloniaEdit's line-number margin moves the caret and selects the line,
and a fold marker toggles its fold, on any pointer button; the WPF
margins only reacted to the left button. A middle click opens a
reference in a new tab over the text, so one that lands on the gutter
should do nothing instead of folding code or moving the caret. The text
area itself still sees every button.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
@siegfriedpammer
siegfriedpammer merged commit b379738 into master Oct 8, 2026
15 checks passed
@siegfriedpammer
siegfriedpammer deleted the christophwille/avalonia-followups-4042 branch October 8, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants