fix(windows): reverse horizontal scroll direction for synthetic wheel input - #17
Merged
Y-PLONI merged 1 commit intoAug 31, 2026
Conversation
… 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.
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.
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 (
deltaXis 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:
WM_MOUSEWHEELdeltaYnegative)WM_MOUSEHWHEELdeltaXpositive)The Flutter engine mirrors this asymmetry when producing
PointerScrollEvent(it negates only the vertical axis on Windows), so the round trip back into WebView2 viaSendMouseInputmust too. Both horizontal paths were inverted:PointerPanZoomUpdate): fingers right produced a positive hwheel → content moved left, opposite the fingers.PointerScrollEvent):scrollDelta.dxwas negated likedy, 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:_sendTrackpadScrollDeltanegatesdxso the content follows the fingers — this also covers the synthetic fling, which shares the path.PointerScrollEventpath forwardsdxunnegated, 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_MOUSEHWHEELasymmetry so it cannot regress.flutter test test/custom_platform_view_scroll_test.dart: 17/17 pass;flutter analyzeclean.