Fix x11 mouse scroll wheel

This commit is contained in:
Rukai 2017-07-09 17:47:52 +10:00 committed by Lucas Kent
parent aad82eb987
commit 117beed0b5
2 changed files with 36 additions and 17 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "winit" name = "winit"
version = "0.7.2" version = "0.7.3"
authors = ["The winit contributors, Pierre Krieger <pierre.krieger1708@gmail.com>"] authors = ["The winit contributors, Pierre Krieger <pierre.krieger1708@gmail.com>"]
description = "Cross-platform window creation library." description = "Cross-platform window creation library."
keywords = ["windowing"] keywords = ["windowing"]

View file

@ -434,6 +434,15 @@ impl EventsLoop {
ffi::XI_Enter => { ffi::XI_Enter => {
let xev: &ffi::XIEnterEvent = unsafe { &*(xev.data as *const _) }; let xev: &ffi::XIEnterEvent = unsafe { &*(xev.data as *const _) };
let mut devices = self.devices.lock().unwrap();
let physical_device = devices.get_mut(&DeviceId(xev.sourceid)).unwrap();
for info in DeviceInfo::get(&self.display, ffi::XIAllDevices).iter() {
if info.deviceid == xev.sourceid {
physical_device.reset_scroll_position(info);
}
}
callback(Event::WindowEvent { window_id: mkwid(xev.event), event: MouseEntered { device_id: mkdid(xev.deviceid) } }) callback(Event::WindowEvent { window_id: mkwid(xev.event), event: MouseEntered { device_id: mkdid(xev.deviceid) } })
} }
ffi::XI_Leave => { ffi::XI_Leave => {
@ -799,9 +808,9 @@ impl Device {
fn new(el: &EventsLoop, info: &ffi::XIDeviceInfo) -> Self fn new(el: &EventsLoop, info: &ffi::XIDeviceInfo) -> Self
{ {
let name = unsafe { CStr::from_ptr(info.name).to_string_lossy() }; let name = unsafe { CStr::from_ptr(info.name).to_string_lossy() };
let mut scroll_axes = Vec::new();
let physical_device = info._use == ffi::XISlaveKeyboard || info._use == ffi::XISlavePointer || info._use == ffi::XIFloatingSlave; if Device::physical_device(info) {
if physical_device {
// Register for global raw events // Register for global raw events
let mask = ffi::XI_RawMotionMask let mask = ffi::XI_RawMotionMask
| ffi::XI_RawButtonPressMask | ffi::XI_RawButtonReleaseMask | ffi::XI_RawButtonPressMask | ffi::XI_RawButtonReleaseMask
@ -814,15 +823,9 @@ impl Device {
}; };
(el.display.xinput2.XISelectEvents)(el.display.display, el.root, &mut event_mask as *mut ffi::XIEventMask, 1); (el.display.xinput2.XISelectEvents)(el.display.display, el.root, &mut event_mask as *mut ffi::XIEventMask, 1);
} }
}
let mut scroll_axes = Vec::new();
if physical_device {
let classes : &[*const ffi::XIAnyClassInfo] =
unsafe { slice::from_raw_parts(info.classes as *const *const ffi::XIAnyClassInfo, info.num_classes as usize) };
// Identify scroll axes // Identify scroll axes
for class_ptr in classes { for class_ptr in Device::classes(info) {
let class = unsafe { &**class_ptr }; let class = unsafe { &**class_ptr };
match class._type { match class._type {
ffi::XIScrollClass => { ffi::XIScrollClass => {
@ -840,13 +843,24 @@ impl Device {
_ => {} _ => {}
} }
} }
// Fix up initial scroll positions }
for class_ptr in classes {
let mut device = Device {
name: name.into_owned(),
scroll_axes: scroll_axes,
};
device.reset_scroll_position(info);
device
}
fn reset_scroll_position(&mut self, info: &ffi::XIDeviceInfo) {
if Device::physical_device(info) {
for class_ptr in Device::classes(info) {
let class = unsafe { &**class_ptr }; let class = unsafe { &**class_ptr };
match class._type { match class._type {
ffi::XIValuatorClass => { ffi::XIValuatorClass => {
let info = unsafe { mem::transmute::<&ffi::XIAnyClassInfo, &ffi::XIValuatorClassInfo>(class) }; let info = unsafe { mem::transmute::<&ffi::XIAnyClassInfo, &ffi::XIValuatorClassInfo>(class) };
if let Some(&mut (_, ref mut axis)) = scroll_axes.iter_mut().find(|&&mut (axis, _)| axis == info.number) { if let Some(&mut (_, ref mut axis)) = self.scroll_axes.iter_mut().find(|&&mut (axis, _)| axis == info.number) {
axis.position = info.value; axis.position = info.value;
} }
} }
@ -854,10 +868,15 @@ impl Device {
} }
} }
} }
Device {
name: name.into_owned(),
scroll_axes: scroll_axes,
} }
#[inline]
fn physical_device(info: &ffi::XIDeviceInfo) -> bool {
info._use == ffi::XISlaveKeyboard || info._use == ffi::XISlavePointer || info._use == ffi::XIFloatingSlave
}
#[inline]
fn classes(info: &ffi::XIDeviceInfo) -> &[*const ffi::XIAnyClassInfo] {
unsafe { slice::from_raw_parts(info.classes as *const *const ffi::XIAnyClassInfo, info.num_classes as usize) }
} }
} }