Skip to content

Commit

Permalink
Reverse horizontal scroll direction (rust-windowing#2105)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk authored Mar 13, 2022
1 parent 1c68be0 commit 85baf79
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ And please only add new entries to the top of this list, right below the `# Unre
- On X11, add mappings for numpad comma, numpad enter, numlock and pause.
- On macOS, fix Pinyin IME input by reverting a change that intended to improve IME.
- On Windows, fix a crash with transparent windows on Windows 11.
- **Breaking:**: Reverse horizontal scrolling sign in `MouseScrollDelta` to match the direction of vertical scrolling. A positive X value now means moving the content to the right. The meaning of vertical scrolling stays the same: a positive Y value means moving the content down.

# 0.26.0 (2021-12-01)

Expand Down
30 changes: 21 additions & 9 deletions examples/mouse_wheel.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use simple_logger::SimpleLogger;
use winit::{
event::{DeviceEvent, Event, WindowEvent},
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
Expand All @@ -14,29 +14,41 @@ fn main() {
.build(&event_loop)
.unwrap();

println!(
r"
When using so called 'natural scrolling' (scrolling that acts like on a touch screen), this is what to expect:
Moving your finger downwards on a scroll wheel should make the window move down, and you should see a positive Y scroll value.
When moving fingers on a trackpad down and to the right, you should see positive X and Y deltas, and the window should move down and to the right.
With reverse scrolling, you should see the inverse behavior.
In both cases the example window should move like the content of a scroll area in any other application.
In other words, the deltas indicate the direction in which to move the content (in this case the window)."
);

event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;

match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
_ => (),
},
Event::DeviceEvent { event, .. } => match event {
DeviceEvent::MouseWheel { delta } => match delta {
WindowEvent::MouseWheel { delta, .. } => match delta {
winit::event::MouseScrollDelta::LineDelta(x, y) => {
println!("mouse wheel Line Delta: ({},{})", x, y);
let pixels_per_line = 120.0;
let mut pos = window.outer_position().unwrap();
pos.x -= (x * pixels_per_line) as i32;
pos.y -= (y * pixels_per_line) as i32;
pos.x += (x * pixels_per_line) as i32;
pos.y += (y * pixels_per_line) as i32;
window.set_outer_position(pos)
}
winit::event::MouseScrollDelta::PixelDelta(p) => {
println!("mouse wheel Pixel Delta: ({},{})", p.x, p.y);
let mut pos = window.outer_position().unwrap();
pos.x -= p.x as i32;
pos.y -= p.y as i32;
pos.x += p.x as i32;
pos.y += p.y as i32;
window.set_outer_position(pos)
}
},
Expand Down
12 changes: 10 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,15 +759,23 @@ pub enum MouseScrollDelta {
/// Amount in lines or rows to scroll in the horizontal
/// and vertical directions.
///
/// Positive values indicate movement forward
/// (away from the user) or rightwards.
/// Positive values indicate that the content that is being scrolled should move
/// right and down (revealing more content left and up).
LineDelta(f32, f32),

/// Amount in pixels to scroll in the horizontal and
/// vertical direction.
///
/// Scroll events are expressed as a PixelDelta if
/// supported by the device (eg. a touchpad) and
/// platform.
///
/// Positive values indicate that the content being scrolled should
/// move right/down.
///
/// For a 'natural scrolling' touch pad (that acts like a touch screen)
/// this means moving your fingers right and down should give positive values,
/// and move the content right and down (to reveal more things left and up).
PixelDelta(PhysicalPosition<f64>),
}

Expand Down
12 changes: 6 additions & 6 deletions src/platform_impl/linux/wayland/seat/pointer/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ pub(super) fn handle_pointer(

// Old seat compatibility.
match axis {
// Wayland vertical sign convention is the inverse of winit.
// Wayland sign convention is the inverse of winit.
wl_pointer::Axis::VerticalScroll => y -= value as f32,
wl_pointer::Axis::HorizontalScroll => x += value as f32,
wl_pointer::Axis::HorizontalScroll => x -= value as f32,
_ => unreachable!(),
}

Expand All @@ -216,9 +216,9 @@ pub(super) fn handle_pointer(
} else {
let (mut x, mut y) = pointer_data.axis_data.axis_buffer.unwrap_or((0.0, 0.0));
match axis {
// Wayland vertical sign convention is the inverse of winit.
// Wayland sign convention is the inverse of winit.
wl_pointer::Axis::VerticalScroll => y -= value as f32,
wl_pointer::Axis::HorizontalScroll => x += value as f32,
wl_pointer::Axis::HorizontalScroll => x -= value as f32,
_ => unreachable!(),
}

Expand All @@ -237,9 +237,9 @@ pub(super) fn handle_pointer(
.unwrap_or((0., 0.));

match axis {
// Wayland vertical sign convention is the inverse of winit.
// Wayland sign convention is the inverse of winit.
wl_pointer::Axis::VerticalScroll => y -= discrete as f32,
wl_pointer::Axis::HorizontalScroll => x += discrete as f32,
wl_pointer::Axis::HorizontalScroll => x -= discrete as f32,
_ => unreachable!(),
}

Expand Down
8 changes: 4 additions & 4 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ impl<T: 'static> EventProcessor<T> {
delta: match xev.detail {
4 => LineDelta(0.0, 1.0),
5 => LineDelta(0.0, -1.0),
6 => LineDelta(-1.0, 0.0),
7 => LineDelta(1.0, 0.0),
6 => LineDelta(1.0, 0.0),
7 => LineDelta(-1.0, 0.0),
_ => unreachable!(),
},
phase: TouchPhase::Moved,
Expand Down Expand Up @@ -774,10 +774,10 @@ impl<T: 'static> EventProcessor<T> {
event: MouseWheel {
device_id,
delta: match info.orientation {
// X11 vertical scroll coordinates are opposite to winit's
ScrollOrientation::Horizontal => {
LineDelta(delta as f32, 0.0)
LineDelta(-delta as f32, 0.0)
}
// X11 vertical scroll coordinates are opposite to winit's
ScrollOrientation::Vertical => {
LineDelta(0.0, -delta as f32)
}
Expand Down
3 changes: 1 addition & 2 deletions src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,8 +1000,7 @@ extern "C" fn scroll_wheel(this: &Object, _sel: Sel, event: id) {
let state = &mut *(state_ptr as *mut ViewState);

let delta = {
// macOS horizontal sign convention is the inverse of winit.
let (x, y) = (event.scrollingDeltaX() * -1.0, event.scrollingDeltaY());
let (x, y) = (event.scrollingDeltaX(), event.scrollingDeltaY());
if event.hasPreciseScrollingDeltas() == YES {
let delta = LogicalPosition::new(x, y).to_physical(state.get_scale_factor());
MouseScrollDelta::PixelDelta(delta)
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/web/web_sys/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn mouse_position_by_client(
}

pub fn mouse_scroll_delta(event: &WheelEvent) -> Option<MouseScrollDelta> {
let x = event.delta_x();
let x = -event.delta_x();
let y = -event.delta_y();

match event.delta_mode() {
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ unsafe fn public_window_callback_inner<T: 'static>(

let value = (wparam >> 16) as i16;
let value = value as i32;
let value = value as f32 / WHEEL_DELTA as f32;
let value = -value as f32 / WHEEL_DELTA as f32; // NOTE: inverted! See https://github.com/rust-windowing/winit/pull/2105/

update_modifiers(window, userdata);

Expand Down

0 comments on commit 85baf79

Please sign in to comment.