Fix scroll modifiers getting stuck when TouchPhase::End never arrives - #8636
Open
SulimanAbdulrazzaq wants to merge 1 commit into
Open
SulimanAbdulrazzaq wants to merge 1 commit into
SulimanAbdulrazzaq wants to merge 1 commit into
Conversation
winit on Wayland sends `TouchPhase::Start` for some mouse wheels, but never `TouchPhase::End`. The `WheelState` then stayed `InTouch` forever, where modifiers only accumulate. After a single ctrl+scroll, every later scroll was a zoom, and `is_scrolling()` never went back to `false`. End an `InTouch` scroll action after the same 150 ms without scroll events that we already use for `Smoothing`. Check this both in `after_events` and when the next scroll event arrives, since an idle app may not run a pass after the timeout.
|
Preview available at https://egui-pr-preview.github.io/pr/8636-fixwheel-missing-touch-end View snapshot changes at kitdiff |
SulimanAbdulrazzaq
marked this pull request as ready for review
September 25, 2026 15:53
Contributor
Author
|
@emilk when you have a moment, could you take a look at this one? Everything is green on the current head except the |
This branch has not been deployed
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.
winit on Wayland sends
TouchPhase::Startfor some mouse wheels, but neverTouchPhase::End(winit's own comment in its Wayland pointer handler: "theEndedis not guaranteed to be sent for mouse wheels"). Since #7678,WheelStatethen staysInTouchfor good, and inInTouchthe modifiers are only ever added to. So after a single ctrl+scroll, every later scroll is a zoom, which is what #8325 bisected to 1b77d70.is_scrolling()also staystrue, and withshow_tooltips_only_when_stillthat keeps tooltips from showing.This ends an
InTouchscroll action after 150 ms without scroll events, the same timeoutSmoothingalready uses. The check runs inafter_events, and also when the next wheel event arrives, because an idle app may not run a pass after the timeout has passed. While events keep coming, the modifiers stay latched as #7678 intended.Tests, in
wheel_state.rs:modifiers_should_not_stick_when_touch_phase_end_never_arrives:Start+Movewith ctrl, then 1 s later aMovewithout ctrl. Before the fix it zoomed (left: 0.9753099,right: 1.0).scroll_action_should_end_when_touch_phase_end_never_arrives:is_scrolling()isfalseafter a second without scroll events. Before the fix it stayedtrue.modifiers_should_stick_until_touch_phase_end: letting go of shift mid-scroll still scrolls horizontally untilEnd(the Improve modifier handling when scrolling #7678 behavior). Passes before and after.cargo test -p egui --all-featurespasses (75 unit tests, 186 doc-tests), and so docargo fmt,./scripts/lint.py,cargo clippy -p egui --all-features --all-targets -- -D warningsandcargo doc -p egui --document-private-items. The whole-workspacecargo test --all-featureson macOS (with the snapshot tests) passes too. I don't have a niri or COSMIC setup, so the tests replay winit's event sequence rather than a real wheel.