Repository navigation
[web] Let the browser handle Control+wheel zoom outside of macOS - #193362
Open
diegolopezrm wants to merge 1 commit into
Open
diegolopezrm wants to merge 1 commit into
diegolopezrm wants to merge 1 commit into
Conversation
Browsers report trackpad pinch gestures as wheel events with ctrlKey set, and since flutter-team-archive/engine#36348 every such event is turned into a scale signal and cancelled. That also swallows the user holding the Control key and turning the mouse wheel, which is the browser's zoom shortcut on Windows, Linux and ChromeOS, so those pages could no longer be zoomed. Tell the two apart the same way the macOS code path already does: a pinch never involves a physical Control key press. When the key is held, leave the event to the browser instead of forwarding or cancelling it. Fixes flutter#129933
Contributor
There was a problem hiding this comment.
Code Review
This pull request updates the web engine's pointer binding to identify browser zoom shortcuts (Control+wheel) on platforms outside of macOS and iOS, allowing the browser to handle the zoom instead of forwarding the event to the framework. A test is added to verify this behavior. The review feedback suggests resetting ui.PlatformDispatcher.instance.onPointerDataPacket to null at the end of the new test to prevent test pollution.
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.
The problem
On Windows and Linux, holding Control and turning the mouse wheel zooms the page in every browser. In a Flutter web app it does nothing: the page does not zoom and the app does not react either. Control+Plus and Control+Minus still work, as the reporter noted, which makes the wheel feel broken rather than deliberately disabled.
Issue: #129933
Root cause
Browsers report a trackpad pinch as a
wheelevent withctrlKeyset. Since flutter-team-archive/engine#36348 (Flutter 3.10) the web engine turns everywheelevent withctrlKeyinto aPointerSignalKind.scaleand callspreventDefault()on it, so thatInteractiveViewerand friends can zoom on pinch. That is right for a pinch. But a user holding the Control key and turning the wheel produces exactly the same event, and gets swallowed with it.Before that change
_handleWheelEventhad this:The macOS path already knows how to tell the two apart: it asks the keyboard converter whether a physical Control key is held, because a pinch never involves a key press. Windows and Linux never got that check, which is how they lost browser zoom.
The fix
_isBrowserZoomShortcutapplies the same physical-key check on every platform except macOS and iOS. When the user is holding Control and turning the wheel,_handleWheelEventreturns before forwarding the event to the framework and without cancelling it, so the browser zooms the page the way it does on any other site. A pinch still reaches the framework as a scale signal and is still cancelled, so nothing changes forInteractiveViewer.macOS keeps its current behaviour on purpose: Control+wheel does not zoom the browser there, and the existing code already reports it as a plain scroll.
ctrlKey, no key held)The one behavioural change is for an app that relied on getting a
PointerScaleEventfrom a mouse wheel with Control held on Windows or Linux. That never worked on macOS, did not work before 3.10, and it competes with the browser's own shortcut, so restoring the pre-3.10 behaviour looks like the right call to me. If the team would rather keep delivering the event and only skippreventDefault(), I am happy to change it.Testing
leaves Control+wheel to the browser outside of macOSinpointer_binding_test.dartcovers Windows and Linux: a pinch is delivered as a scale and cancelled, a wheel with Control physically held is neither delivered nor cancelled, and releasing the key brings scrolling back.felt test --gcs-prod --compiler dart2js test/engine/pointer_binding_test.dartpasses (73 tests), and I checked that the new test fails without the fix.does choose scroll vs scale based on ctrlKeytest still passes, so the macOS path is unchanged.Pre-launch Checklist
///).Notes on the checklist: the only behaviour that changes is described in the table above, and it restores what the engine did before 3.10. There is no API change, so no Data Driven Fixes apply.