From c310f7bb803dda17467a353edf903d68c82fcfe4 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 24 Aug 2015 14:32:31 -0700 Subject: [PATCH 1/2] Take XIScrollClassInfo::increment into account From the "Smooth Scrolling" section of [XI2Proto.txt][1]: > One unit of scrolling in either direction is considered to be equivalent to > one button event, e.g. for a unit size of 1.0, -2.0 on an valuator type > Vertical sends two button press/release events for button 4. Likewise, a > button press event for button 7 generates an event on the Horizontal > valuator with a value of +1.0. The server may accumulate deltas of less than > one unit of scrolling. From [What's new in XI 2.1 - smooth scrolling][2]: > The increment defines what delta the driver considers to be one scroll > event. For an increment of +5, each delta of 5 should be regarded as one > scroll unit down. For an increment of -3, each delta of 3 should be regarded > as one scroll unit up (i.e. inverted). [1]: http://www.x.org/releases/X11R7.7/doc/inputproto/XI2proto.txt [2]: http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-smooth-scrolling.html This fixes scrolling with my Microsoft mouse in X11 on Debian 8.1. --- src/api/x11/input.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/api/x11/input.rs b/src/api/x11/input.rs index 7387ab00..75939e9e 100644 --- a/src/api/x11/input.rs +++ b/src/api/x11/input.rs @@ -21,7 +21,8 @@ struct Axis { id: i32, device_id: i32, axis_number: i32, - axis_type: AxisType + axis_type: AxisType, + scroll_increment: f64, } #[derive(Debug)] @@ -167,7 +168,7 @@ impl XInputEventHandler { use events::Event::{Focused, MouseInput, MouseMoved, MouseWheel}; use events::ElementState::{Pressed, Released}; use events::MouseButton::{Left, Right, Middle}; - use events::MouseScrollDelta::{PixelDelta, LineDelta}; + use events::MouseScrollDelta::LineDelta; use events::{Touch, TouchPhase}; match cookie.evtype { @@ -221,7 +222,7 @@ impl XInputEventHandler { } if scroll_delta.0.abs() > 0.0 || scroll_delta.1.abs() > 0.0 { - Some(MouseWheel(PixelDelta(scroll_delta.0 as f32, scroll_delta.1 as f32))) + Some(MouseWheel(LineDelta(scroll_delta.0 as f32, scroll_delta.1 as f32))) } else { let new_cursor_pos = (event_data.event_x, event_data.event_y); if new_cursor_pos != self.current_state.cursor_pos { @@ -290,7 +291,8 @@ fn read_input_axis_info(display: &Arc) -> Vec { ffi::XIScrollTypeHorizontal => AxisType::HorizontalScroll, ffi::XIScrollTypeVertical => AxisType::VerticalScroll, _ => { unreachable!() } - } + }, + scroll_increment: scroll_class.increment, }) }, _ => {} @@ -314,7 +316,7 @@ fn calc_scroll_deltas(event: &ffi::XIDeviceEvent, prev_axis.axis_number == axis_id }); let delta = match prev_value_pos { - Some(idx) => axis_value - prev_axis_values[idx].value, + Some(idx) => prev_axis_values[idx].value - axis_value, None => 0.0 }; @@ -335,8 +337,8 @@ fn calc_scroll_deltas(event: &ffi::XIDeviceEvent, if axis.id == event.sourceid && axis.axis_number == axis_id { match axis.axis_type { - AxisType::HorizontalScroll => scroll_delta.0 = delta, - AxisType::VerticalScroll => scroll_delta.1 = delta + AxisType::HorizontalScroll => scroll_delta.0 = delta / axis.scroll_increment, + AxisType::VerticalScroll => scroll_delta.1 = delta / axis.scroll_increment } } } From 576720fd9767e579d79e7dbf933ef819de8e1a5e Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 24 Aug 2015 15:42:10 -0700 Subject: [PATCH 2/2] Read scroll axis info from all devices When multiple scrolling devices are attached, XIAllMasterDevices does not include the scroll axes for all hardware devices. --- src/api/x11/input.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/api/x11/input.rs b/src/api/x11/input.rs index 75939e9e..388b6514 100644 --- a/src/api/x11/input.rs +++ b/src/api/x11/input.rs @@ -268,10 +268,9 @@ fn read_input_axis_info(display: &Arc) -> Vec { let mut axis_list = Vec::new(); let mut device_count = 0; - // only get events from the master devices which are 'attached' - // to the keyboard or cursor + // Check all input devices for scroll axes. let devices = unsafe{ - (display.xinput2.XIQueryDevice)(display.display, ffi::XIAllMasterDevices, &mut device_count) + (display.xinput2.XIQueryDevice)(display.display, ffi::XIAllDevices, &mut device_count) }; for i in 0..device_count { let device = unsafe { *(devices.offset(i as isize)) };