Skip to content

fix(windows): reverse horizontal scroll direction for synthetic wheel input - #17

Merged
Y-PLONI merged 1 commit into
Otzaria:masterfrom
palmoni5:fix/windows-horizontal-scroll-direction
Aug 31, 2026
Merged

fix(windows): reverse horizontal scroll direction for synthetic wheel input#17
Y-PLONI merged 1 commit into
Otzaria:masterfrom
palmoni5:fix/windows-horizontal-scroll-direction

Conversation

@palmoni5

Copy link
Copy Markdown
Member

Problem

Two-finger horizontal trackpad pans (and mouse tilt-wheel scrolls) move the page content in the opposite direction inside the WebView. Reported against the Kidush HaChodesh plugin in Otzaria: the same plugin scrolls correctly in a regular browser and in other hosts, so the reversal is on the host side. It was misattributed to RTL documents — it is actually document-independent (deltaX is physical), but horizontal-scrolling plugin content happens to be RTL, which is where it was noticed.

Root cause

The synthetic wheel injection treats both axes with the same sign, but the WM conventions are asymmetric:

Message Positive data means
WM_MOUSEWHEEL scroll up (browser deltaY negative)
WM_MOUSEHWHEEL scroll right (browser deltaX positive)

The Flutter engine mirrors this asymmetry when producing PointerScrollEvent (it negates only the vertical axis on Windows), so the round trip back into WebView2 via SendMouseInput must too. Both horizontal paths were inverted:

  • Trackpad (PointerPanZoomUpdate): fingers right produced a positive hwheel → content moved left, opposite the fingers.
  • Mouse tilt wheel (PointerScrollEvent): scrollDelta.dx was negated like dy, re-reversing the engine's already-correct sign.

Fix

Sign-only change in the Dart conversion layer (custom_platform_view.dart); the native side keeps passing raw wheel data through:

  • _sendTrackpadScrollDelta negates dx so the content follows the fingers — this also covers the synthetic fling, which shares the path.
  • The PointerScrollEvent path forwards dx unnegated, reproducing the original native delta.

Tests

Updated the two tests that pinned the reversed sign and added an explicit direction test per input path (trackpad + wheel), documenting the WM_MOUSEHWHEEL asymmetry so it cannot regress. flutter test test/custom_platform_view_scroll_test.dart: 17/17 pass; flutter analyze clean.

… input

Two-finger horizontal trackpad pans (and mouse tilt-wheel scrolls) moved the page content in the opposite direction inside the WebView. Plugins that scroll horizontally had to work around it on their side, and the reversal was misattributed to RTL documents - it is actually document-independent, but only RTL horizontal-scrolling content made it visible in practice.

The synthetic wheel injection treated both axes with the same sign, but the WM conventions are asymmetric: positive WM_MOUSEWHEEL data scrolls up, while positive WM_MOUSEHWHEEL data scrolls right. The Flutter engine mirrors this asymmetry when producing PointerScrollEvent (it negates only the vertical axis), so the round trip back to WebView2 must too. The trackpad path now negates dx so the content follows the fingers (this also covers the synthetic fling, which shares the path), and the wheel path forwards dx unnegated to reproduce the original native delta.

Updates the two tests that pinned the reversed sign and adds an explicit direction test per input path.
@Y-PLONI
Y-PLONI merged commit 5e4404e into Otzaria:master Aug 31, 2026
1 check passed
@palmoni5
palmoni5 deleted the fix/windows-horizontal-scroll-direction branch August 31, 2026 23:52
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.

2 participants