From e1685deb29851a2e9e65a6a45bb9370b8d3e66c4 Mon Sep 17 00:00:00 2001 From: Owen Law <81528246+someone13574@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:07:13 -0400 Subject: [PATCH] Revert "Use XI2 for Scrolling on X11" (#10818) Reverts zed-industries/zed#10695 Some users are experiencing broken scrolling due to the changes from this PR, so it should be reverted while I investigate what causes the problems. Release Notes: - N/A --- crates/gpui/Cargo.toml | 2 +- crates/gpui/src/platform/linux/x11/client.rs | 126 ++----------------- crates/gpui/src/platform/linux/x11/window.rs | 24 +--- 3 files changed, 17 insertions(+), 135 deletions(-) diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 021b4bcb9a..471e0a7347 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -115,7 +115,7 @@ wayland-protocols = { version = "0.31.2", features = [ ] } oo7 = "0.3.0" open = "5.1.2" -x11rb = { version = "0.13.0", features = ["allow-unsafe-code", "xkb", "randr", "xinput"] } +x11rb = { version = "0.13.0", features = ["allow-unsafe-code", "xkb", "randr"] } xkbcommon = { version = "0.7", features = ["wayland", "x11"] } [target.'cfg(windows)'.dependencies] diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index 74b11c2758..bc1a1b527e 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -12,10 +12,9 @@ use util::ResultExt; use x11rb::connection::{Connection, RequestConnection}; use x11rb::errors::ConnectionError; use x11rb::protocol::randr::ConnectionExt as _; -use x11rb::protocol::xinput::ConnectionExt; use x11rb::protocol::xkb::ConnectionExt as _; use x11rb::protocol::xproto::ConnectionExt as _; -use x11rb::protocol::{randr, xinput, xkb, xproto, Event}; +use x11rb::protocol::{randr, xkb, xproto, Event}; use x11rb::xcb_ffi::XCBConnection; use xkbc::x11::ffi::{XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION}; use xkbcommon::xkb as xkbc; @@ -64,10 +63,6 @@ pub struct X11ClientState { pub(crate) focused_window: Option, pub(crate) xkb: xkbc::State, - pub(crate) scroll_devices: Vec, - pub(crate) scroll_x: Option, - pub(crate) scroll_y: Option, - pub(crate) common: LinuxCommon, pub(crate) clipboard: X11ClipboardContext, pub(crate) primary: X11ClipboardContext, @@ -97,19 +92,6 @@ impl X11Client { xcb_connection .prefetch_extension_information(randr::X11_EXTENSION_NAME) .unwrap(); - xcb_connection - .prefetch_extension_information(xinput::X11_EXTENSION_NAME) - .unwrap(); - - let xinput_version = xcb_connection - .xinput_xi_query_version(2, 0) - .unwrap() - .reply() - .unwrap(); - assert!( - xinput_version.major_version >= 2, - "XInput Extension v2 not supported." - ); let atoms = XcbAtoms::new(&xcb_connection).unwrap(); let xkb = xcb_connection @@ -143,46 +125,6 @@ impl X11Client { xkbc::x11::state_new_from_device(&xkb_keymap, &xcb_connection, xkb_device_id) }; - let device_list = xcb_connection - .xinput_list_input_devices() - .unwrap() - .reply() - .unwrap(); - let scroll_devices = device_list - .devices - .iter() - .scan(0, |class_info_idx, device_info| { - Some(*class_info_idx + device_info.num_class_info as usize) - }) - .zip(device_list.devices.iter()) - .map(|(class_info_idx, device_info)| { - ( - device_info, - device_list.infos - [(class_info_idx - device_info.num_class_info as usize)..(class_info_idx)] - .to_vec(), - ) - }) - .filter(|(device_info, class_info)| { - device_info.device_use == xinput::DeviceUse::IS_X_EXTENSION_POINTER - && class_info.iter().any(|class_info| match class_info.info { - xinput::InputInfoInfo::Valuator(xinput::InputInfoInfoValuator { - mode, - .. - }) => mode == xinput::ValuatorMode::RELATIVE, - _ => false, - }) - }) - .map(|(device_info, _)| *device_info) - .collect::>(); - for device in &scroll_devices { - xcb_connection - .xinput_open_device(device.device_id) - .unwrap() - .reply() - .unwrap(); - } - let clipboard = X11ClipboardContext::::new().unwrap(); let primary = X11ClipboardContext::::new().unwrap(); @@ -224,11 +166,6 @@ impl X11Client { windows: HashMap::default(), focused_window: None, xkb: xkb_state, - - scroll_devices, - scroll_x: None, - scroll_y: None, - clipboard, primary, }))) @@ -377,58 +314,22 @@ impl X11Client { click_count: current_count, first_mouse: false, })); + } else if event.detail >= 4 && event.detail <= 5 { + // https://stackoverflow.com/questions/15510472/scrollwheel-event-in-x11 + let scroll_direction = if event.detail == 4 { 1.0 } else { -1.0 }; + let scroll_y = SCROLL_LINES * scroll_direction; + + drop(state); + window.handle_input(PlatformInput::ScrollWheel(crate::ScrollWheelEvent { + position, + delta: ScrollDelta::Lines(Point::new(0.0, scroll_y as f32)), + modifiers, + touch_phase: TouchPhase::Moved, + })); } else { log::warn!("Unknown button press: {event:?}"); } } - Event::XinputMotion(event) => { - let window = self.get_window(event.event)?; - - let position = Point::new( - (event.event_x as f32 / u16::MAX as f32).into(), - (event.event_y as f32 / u16::MAX as f32).into(), - ); - - let axisvalues = event - .axisvalues - .iter() - .map(|axisvalue| { - axisvalue.integral as f32 + axisvalue.frac as f32 / u32::MAX as f32 - }) - .collect::>(); - - if event.valuator_mask[0] & 4 == 4 { - let new_scroll = axisvalues[0]; - let old_scroll = self.0.borrow().scroll_x; - self.0.borrow_mut().scroll_x = Some(new_scroll); - - if let Some(old_scroll) = old_scroll { - let delta_scroll = (old_scroll - new_scroll).into(); - window.handle_input(PlatformInput::ScrollWheel(crate::ScrollWheelEvent { - position, - delta: ScrollDelta::Pixels(Point::new(delta_scroll, 0.0.into())), - modifiers: crate::Modifiers::none(), - touch_phase: TouchPhase::default(), - })); - } - } - - if event.valuator_mask[0] & 8 == 8 { - let new_scroll = axisvalues[0] / 2.0; - let old_scroll = self.0.borrow().scroll_y; - self.0.borrow_mut().scroll_y = Some(new_scroll); - - if let Some(old_scroll) = old_scroll { - let delta_scroll = (old_scroll - new_scroll).into(); - window.handle_input(PlatformInput::ScrollWheel(crate::ScrollWheelEvent { - position, - delta: ScrollDelta::Pixels(Point::new(0.0.into(), delta_scroll)), - modifiers: crate::Modifiers::none(), - touch_phase: TouchPhase::default(), - })); - } - } - } Event::ButtonRelease(event) => { let window = self.get_window(event.event)?; let state = self.0.borrow(); @@ -528,7 +429,6 @@ impl LinuxClient for X11Client { state.x_root_index, x_window, &state.atoms, - &state.scroll_devices, ); let screen_resources = state diff --git a/crates/gpui/src/platform/linux/x11/window.rs b/crates/gpui/src/platform/linux/x11/window.rs index 12b635d372..884011a376 100644 --- a/crates/gpui/src/platform/linux/x11/window.rs +++ b/crates/gpui/src/platform/linux/x11/window.rs @@ -13,10 +13,7 @@ use raw_window_handle as rwh; use util::ResultExt; use x11rb::{ connection::Connection, - protocol::{ - xinput, - xproto::{self, ConnectionExt as _, CreateWindowAux}, - }, + protocol::xproto::{self, ConnectionExt as _, CreateWindowAux}, wrapper::ConnectionExt, xcb_ffi::XCBConnection, }; @@ -143,7 +140,6 @@ impl X11WindowState { x_main_screen_index: usize, x_window: xproto::Window, atoms: &XcbAtoms, - scroll_devices: &Vec, ) -> Self { let x_screen_index = params .display_id @@ -164,6 +160,8 @@ impl X11WindowState { | xproto::EventMask::BUTTON1_MOTION | xproto::EventMask::BUTTON2_MOTION | xproto::EventMask::BUTTON3_MOTION + | xproto::EventMask::BUTTON4_MOTION + | xproto::EventMask::BUTTON5_MOTION | xproto::EventMask::BUTTON_MOTION, ); @@ -183,20 +181,6 @@ impl X11WindowState { ) .unwrap(); - for device in scroll_devices { - xinput::ConnectionExt::xinput_xi_select_events( - &xcb_connection, - x_window, - &[xinput::EventMask { - deviceid: device.device_id as u16, - mask: vec![xinput::XIEventMask::MOTION], - }], - ) - .unwrap() - .check() - .unwrap(); - } - if let Some(titlebar) = params.titlebar { if let Some(title) = titlebar.title { xcb_connection @@ -278,7 +262,6 @@ impl X11Window { x_main_screen_index: usize, x_window: xproto::Window, atoms: &XcbAtoms, - scroll_devices: &Vec, ) -> Self { X11Window { state: Rc::new(RefCell::new(X11WindowState::new( @@ -287,7 +270,6 @@ impl X11Window { x_main_screen_index, x_window, atoms, - scroll_devices, ))), callbacks: Rc::new(RefCell::new(Callbacks::default())), xcb_connection: xcb_connection.clone(),