wayland: handle axis_value120 scroll events

This can be tested with the `application` example, looking at the events
shown for mouse wheel movement.

`wl_pointer::axis_discrete` isn't sent in version 8 or higher of
`wl_pointer`. And `sctk` doesn't convert the `value120` events, so
on compositors advertising version 8, only pixel scroll events were
being sent.

This sends `MouseScrollDelta::LineDelta` with a fractional value,
without doing any accumulation. Given `LineDelta` contains `f32` values,
this presumably is expected?

Though it might be good to change the definition of `MouseScrollDelta`
to include both discrete and pixel values, when the compositor sends
both. I'm not familiar with how this works on non-Wayland backends
though.
This commit is contained in:
Ian Douglas Scott 2025-10-07 19:53:57 -07:00 committed by GitHub
parent f046e778aa
commit 2ede84ab2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 10 additions and 2 deletions

View file

@ -195,6 +195,7 @@ impl PointerHandler for WinitState {
// Get the current phase.
let mut pointer_data = pointer.winit_data().inner.lock().unwrap();
let has_value120_scroll = horizontal.value120 != 0 || vertical.value120 != 0;
let has_discrete_scroll = horizontal.discrete != 0 || vertical.discrete != 0;
// Figure out what to do about start/ended phases here.
@ -206,7 +207,7 @@ impl PointerHandler for WinitState {
} else {
match pointer_data.phase {
// Discrete scroll only results in moved events.
_ if has_discrete_scroll => TouchPhase::Moved,
_ if has_value120_scroll || has_discrete_scroll => TouchPhase::Moved,
TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved,
_ => TouchPhase::Started,
}
@ -217,7 +218,13 @@ impl PointerHandler for WinitState {
// Mice events have both pixel and discrete delta's at the same time. So prefer
// the discrete values if they are present.
let delta = if has_discrete_scroll {
let delta = if has_value120_scroll {
// NOTE: Wayland sign convention is the inverse of winit.
MouseScrollDelta::LineDelta(
(-horizontal.value120) as f32 / 120.,
(-vertical.value120) as f32 / 120.,
)
} else if has_discrete_scroll {
// NOTE: Wayland sign convention is the inverse of winit.
MouseScrollDelta::LineDelta(
(-horizontal.discrete) as f32,

View file

@ -268,3 +268,4 @@ changelog entry.
- On Windows, `Window::set_theme` will change the title bar color immediately now.
- On Windows 11, prevent incorrect shifting when dragging window onto a monitor with different DPI.
- On Web, device events are emitted regardless of cursor type.
- On Wayland, `axis_value120` scroll events now generate `MouseScrollDelta::LineDelta`