Skip to content

fix(NumericUpDownAssist) & fix(SmoothScrollController)#89

Open
Huntk23 wants to merge 2 commits into
accntech:mainfrom
Huntk23:fix/numericupdown-scroll-value-change
Open

fix(NumericUpDownAssist) & fix(SmoothScrollController)#89
Huntk23 wants to merge 2 commits into
accntech:mainfrom
Huntk23:fix/numericupdown-scroll-value-change

Conversation

@Huntk23
Copy link
Copy Markdown
Contributor

@Huntk23 Huntk23 commented May 28, 2026

I think I found three undocumented behaviors I traced through the Avalonia 12 source on GitHub. None are flagged in the breaking-changes doc:

  1. TextBox.OnKeyDown consumes Up/Down arrows (the keyboard arrow keys bug)

src/Avalonia.Controls/TextBox.cs - search for case Key.Up: and case Key.Down: Both call MoveVertical() and set a local movement flag, then at the end:

if (handled || movement)
    e.Handled = true;

For a single-line TextBox, Up now moves the caret to position 0 and Down moves it to end -- the caret position changes, movement = true, and the event gets swallowed before bubbling to the ButtonSpinner. In Avalonia 11, MoveVertical was effectively a no-op for single-line TextBoxes.

  1. NumericUpDown.OnSpinnerSpin rejects wheel-originated spins (the mouse-wheel bug)

src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs - find OnSpinnerSpin:

var spin = !e.UsingMouseWheel;
spin |= ((TextBox != null) && TextBox.IsFocused);
if (spin) { e.Handled = true; OnSpin(e); }

For wheel events (UsingMouseWheel=true), spin only happens when TextBox.IsFocused returns true. In Avalonia 12, focus appears to land on a child element of the TextBox (likely the TextPresenter) rather than the TextBox itself, so TextBox.IsFocused is false even when the caret is visible. The IsFocused check passes in Avalonia 11 but not 12. This is why our keyboard fix works (it raises Spin without UsingMouseWheel, taking the !e.UsingMouseWheel = true branch and skipping the focus check entirely).

  1. ButtonSpinner.OnPointerWheelChanged raises with UsingMouseWheel=true

src/Avalonia.Controls/ButtonSpinner.cs - find OnPointerWheelChanged:

  var spinnerEventArgs = new SpinEventArgs(SpinEvent,
      (e.Delta.Y < 0) ? SpinDirection.Decrease : SpinDirection.Increase, true);
  //                                                                     ^^^^
  //                                                          UsingMouseWheel

This is the producer side of bug # 2 - the ButtonSpinner always tags wheel-originated spins, which feeds into the broken IsFocused check above.


Root cause summary: bugs # 1 and # 2 both stem from the same underlying Avalonia 12 change - focus and key handling shifted to inner template elements (TextPresenter, MoveVertical caret movement). Neither was called out as a breaking change because, in isolation, they look like correctness improvements. The regression only surfaces when you compose them via the TextBox/ButtonSpinner/NumericUpDown chain.

This might be worth filing a ticket on AvaloniaUI's GitHub as a regression type bug

Fixes #88


Tested

  • Windows 10 22H2
  • Windows 11 25H2
  • Fedora Linux 44 - KDE Plasma 6.6.4
  • macOS Sequoia 15
  • macOS Tahoe 26

Currently working on setting up two macOS environments

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.

NumericUpDown scrolling via mouse scroll wheel does not work

1 participant