Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X11: use sourceid instead of deviceid for input events #3501

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 24 additions & 13 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,12 +979,15 @@ impl EventProcessor {
F: FnMut(&RootELW, Event<T>),
{
let wt = Self::window_target(&self.target);
let window_id = mkwid(event.event as xproto::Window);
let device_id = mkdid(event.deviceid as xinput::DeviceId);

// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);

let window_id = mkwid(event.event as xproto::Window);
// Use sourceid instead of deviceid, as deviceid is typically the device's class id.
// Note that this requires XInput 2.1.
let device_id = mkdid(event.sourceid as xinput::DeviceId);

// Deliver multi-touch events instead of emulated mouse events.
if (event.flags & xinput2::XIPointerEmulated) != 0 {
return;
Expand Down Expand Up @@ -1053,9 +1056,9 @@ impl EventProcessor {
// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);

let device_id = mkdid(event.deviceid as xinput::DeviceId);
let window = event.event as xproto::Window;
let window_id = mkwid(window);
let device_id = mkdid(event.sourceid as xinput::DeviceId);
let new_cursor_pos = (event.event_x, event.event_y);

let cursor_moved = self.with_window(window, |window| {
Expand Down Expand Up @@ -1096,6 +1099,9 @@ impl EventProcessor {
}

let x = unsafe { *value };
if x == 0.0 {
continue;
}

let event = if let Some(&mut (_, ref mut info)) = physical_device
.scroll_axes
Expand All @@ -1121,7 +1127,7 @@ impl EventProcessor {
WindowEvent::AxisMotion {
device_id,
axis: i as u32,
value: unsafe { *value },
value: x,
}
};

Expand All @@ -1146,7 +1152,7 @@ impl EventProcessor {

let window = event.event as xproto::Window;
let window_id = mkwid(window);
let device_id = mkdid(event.deviceid as xinput::DeviceId);
let device_id = mkdid(event.sourceid as xinput::DeviceId);

if let Some(all_info) = DeviceInfo::get(&wt.xconn, super::ALL_DEVICES.into()) {
let mut devices = self.devices.borrow_mut();
Expand Down Expand Up @@ -1202,7 +1208,7 @@ impl EventProcessor {
let event = Event::WindowEvent {
window_id: mkwid(window),
event: WindowEvent::CursorLeft {
device_id: mkdid(event.deviceid as xinput::DeviceId),
device_id: mkdid(event.sourceid as xinput::DeviceId),
},
};
callback(&self.target, event);
Expand Down Expand Up @@ -1265,7 +1271,7 @@ impl EventProcessor {
let pointer_id = self
.devices
.borrow()
.get(&DeviceId(xev.deviceid as xinput::DeviceId))
.get(&DeviceId(xev.sourceid as xinput::DeviceId))
.map(|device| device.attachment)
.unwrap_or(2);

Expand Down Expand Up @@ -1366,7 +1372,7 @@ impl EventProcessor {
let event = Event::WindowEvent {
window_id,
event: WindowEvent::Touch(Touch {
device_id: mkdid(xev.deviceid as xinput::DeviceId),
device_id: mkdid(xev.sourceid as xinput::DeviceId),
phase,
location,
force: None, // TODO
Expand All @@ -1392,7 +1398,7 @@ impl EventProcessor {

if xev.flags & xinput2::XIPointerEmulated == 0 {
let event = Event::DeviceEvent {
device_id: mkdid(xev.deviceid as xinput::DeviceId),
device_id: mkdid(xev.sourceid as xinput::DeviceId),
event: DeviceEvent::Button {
state,
button: xev.detail as u32,
Expand All @@ -1411,7 +1417,7 @@ impl EventProcessor {
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);

let did = mkdid(xev.deviceid as xinput::DeviceId);
let device_id = mkdid(xev.sourceid as xinput::DeviceId);

let mask =
unsafe { slice::from_raw_parts(xev.valuators.mask, xev.valuators.mask_len as usize) };
Expand All @@ -1422,7 +1428,11 @@ impl EventProcessor {
if !xinput2::XIMaskIsSet(mask, i) {
continue;
}

let x = unsafe { *value };
if x == 0.0 {
continue;
}

// We assume that every XInput2 device with analog axes is a pointing device emitting
// relative coordinates.
Expand All @@ -1435,7 +1445,7 @@ impl EventProcessor {
}

let event = Event::DeviceEvent {
device_id: did,
device_id,
event: DeviceEvent::Motion {
axis: i as u32,
value: x,
Expand All @@ -1448,15 +1458,15 @@ impl EventProcessor {

if mouse_delta != (0.0, 0.0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if mouse_delta != (0.0, 0.0) {
if mouse_delta.0.abs() > 0.0001 || mouse_delta.1.abs() > 0.0001 {

Part of the issue might be that floating point comparisons like this are imprecise. So this should filter out any "garbage" values.

let event = Event::DeviceEvent {
device_id: did,
device_id,
event: DeviceEvent::MouseMotion { delta: mouse_delta },
};
callback(&self.target, event);
}

if scroll_delta != (0.0, 0.0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if scroll_delta != (0.0, 0.0) {
if scroll_delta.0.abs() > 0.0001 || scroll_delta.1.abs() > 0.0001 {

Ditto.

let event = Event::DeviceEvent {
device_id: did,
device_id,
event: DeviceEvent::MouseWheel {
delta: MouseScrollDelta::LineDelta(scroll_delta.0, scroll_delta.1),
},
Expand All @@ -1479,6 +1489,7 @@ impl EventProcessor {
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);

let device_id = mkdid(xev.sourceid as xinput::DeviceId);

let keycode = xev.detail as u32;
if keycode < KEYCODE_OFFSET as u32 {
return;
Expand Down