linux: Various X11 scroll improvements (#18484)

Closes  #14089, #14416, #15970, #17230, #18485

Release Notes:

- Fixed some cases where Linux X11 mouse scrolling doesn't work at all
(#14089, ##15970, #17230)
- Fixed handling of switching between Linux X11 devices used for
scrolling (#14416, #18485)

Change details:

Also includes the commit from PR #18317 so I don't have to deal with
merge conflicts.

* Now uses valuator info from slave pointers rather than master. This
hopefully fixes remaining cases where scrolling is fully
broken. https://github.com/zed-industries/zed/issues/14089,
https://github.com/zed-industries/zed/issues/15970,
https://github.com/zed-industries/zed/issues/17230

* Per-device recording of "last scroll position" used to calculate
deltas. This meant that swithing scroll devices would cause a sudden
jump of scroll position, often to the beginning or end of the
file (https://github.com/zed-industries/zed/issues/14416).

* Re-queries device metadata when devices change, so that newly
plugged in devices will work, and re-use of device-ids don't use old
metadata with a new device.

* xinput 2 documentation describes support for multiple master
devices. I believe this implementation will support that, since now it
just uses `DeviceInfo` from slave devices. The concept of master
devices is only used in registering for events.

* Uses popcount+bit masking to resolve axis indexes, instead of
iterating bit indices.

---------

Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
This commit is contained in:
Michael Sloan 2024-10-01 01:14:40 -06:00 committed by GitHub
parent 72be8c5d14
commit 527c9097f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 407 additions and 142 deletions

View file

@ -29,7 +29,7 @@ use std::{
sync::Arc,
};
use super::{X11Display, XINPUT_MASTER_DEVICE};
use super::{X11Display, XINPUT_ALL_DEVICES, XINPUT_ALL_DEVICE_GROUPS};
x11rb::atom_manager! {
pub XcbAtoms: AtomsCookie {
XA_ATOM,
@ -475,7 +475,7 @@ impl X11WindowState {
.xinput_xi_select_events(
x_window,
&[xinput::EventMask {
deviceid: XINPUT_MASTER_DEVICE,
deviceid: XINPUT_ALL_DEVICE_GROUPS,
mask: vec![
xinput::XIEventMask::MOTION
| xinput::XIEventMask::BUTTON_PRESS
@ -487,6 +487,19 @@ impl X11WindowState {
)
.unwrap();
xcb_connection
.xinput_xi_select_events(
x_window,
&[xinput::EventMask {
deviceid: XINPUT_ALL_DEVICES,
mask: vec![
xinput::XIEventMask::HIERARCHY,
xinput::XIEventMask::DEVICE_CHANGED,
],
}],
)
.unwrap();
xcb_connection.flush().unwrap();
let raw = RawWindow {
@ -1253,7 +1266,7 @@ impl PlatformWindow for X11Window {
self.0.x_window,
state.atoms._GTK_SHOW_WINDOW_MENU,
[
XINPUT_MASTER_DEVICE as u32,
XINPUT_ALL_DEVICE_GROUPS as u32,
coords.dst_x as u32,
coords.dst_y as u32,
0,