Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion crates/gpui_linux/src/linux/x11/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ pub struct X11ClientState {

pointer_device_states: BTreeMap<xinput::DeviceId, PointerDeviceState>,

pub(crate) supports_xinput_gestures: bool,

pub(crate) common: LinuxCommon,
pub(crate) clipboard: Clipboard,
pub(crate) clipboard_item: Option<ClipboardItem>,
Expand Down Expand Up @@ -345,7 +347,8 @@ impl X11Client {

// Announce to X server that XInput up to 2.4 is supported.
// Version 2.4 is needed for gesture events (GesturePinchBegin/Update/End).
// If the server only supports an older version, gesture events simply won't be delivered.
// The server responds with the highest version it supports; if < 2.4,
// we must not request gesture event masks in XISelectEvents.
let xinput_version = get_reply(
|| "XInput XiQueryVersion failed",
xcb_connection.xinput_xi_query_version(2, 4),
Expand All @@ -354,6 +357,14 @@ impl X11Client {
xinput_version.major_version >= 2,
"XInput version >= 2 required."
);
let supports_xinput_gestures = xinput_version.major_version > 2
|| (xinput_version.major_version == 2 && xinput_version.minor_version >= 4);
log::info!(
"XInput version: {}.{}, gesture support: {}",
xinput_version.major_version,
xinput_version.minor_version,
supports_xinput_gestures,
);

let pointer_device_states =
current_pointer_device_states(&xcb_connection, &BTreeMap::new()).unwrap_or_default();
Expand Down Expand Up @@ -535,6 +546,8 @@ impl X11Client {

pointer_device_states,

supports_xinput_gestures,

clipboard,
clipboard_item: None,
xdnd_state: Xdnd::default(),
Expand Down Expand Up @@ -1593,6 +1606,7 @@ impl LinuxClient for X11Client {
let scale_factor = state.scale_factor;
let appearance = state.common.appearance;
let compositor_gpu = state.compositor_gpu.take();
let supports_xinput_gestures = state.supports_xinput_gestures;
let window = X11Window::new(
handle,
X11ClientStatePtr(Rc::downgrade(&self.0)),
Expand All @@ -1608,6 +1622,7 @@ impl LinuxClient for X11Client {
scale_factor,
appearance,
parent_window,
supports_xinput_gestures,
)?;
check_reply(
|| "Failed to set XdndAware property",
Expand Down
31 changes: 18 additions & 13 deletions crates/gpui_linux/src/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ impl X11WindowState {
scale_factor: f32,
appearance: WindowAppearance,
parent_window: Option<X11WindowStatePtr>,
supports_xinput_gestures: bool,
) -> anyhow::Result<Self> {
let x_screen_index = params
.display_id
Expand Down Expand Up @@ -660,25 +661,27 @@ impl X11WindowState {
),
)?;

let mut xi_event_mask = xinput::XIEventMask::MOTION
| xinput::XIEventMask::BUTTON_PRESS
| xinput::XIEventMask::BUTTON_RELEASE
| xinput::XIEventMask::ENTER
| xinput::XIEventMask::LEAVE;
if supports_xinput_gestures {
// x11rb 0.13 doesn't define XIEventMask constants for gesture
// events, so we construct them from the event opcodes (each
// XInput event type N maps to mask bit N).
xi_event_mask |=
xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_BEGIN_EVENT)
| xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_UPDATE_EVENT)
| xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_END_EVENT);
}
check_reply(
|| "X11 XiSelectEvents failed.",
xcb.xinput_xi_select_events(
x_window,
&[xinput::EventMask {
deviceid: XINPUT_ALL_DEVICE_GROUPS,
mask: vec![
xinput::XIEventMask::MOTION
| xinput::XIEventMask::BUTTON_PRESS
| xinput::XIEventMask::BUTTON_RELEASE
| xinput::XIEventMask::ENTER
| xinput::XIEventMask::LEAVE
// x11rb 0.13 doesn't define XIEventMask constants for gesture
// events, so we construct them from the event opcodes (each
// XInput event type N maps to mask bit N).
| xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_BEGIN_EVENT)
| xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_UPDATE_EVENT)
| xinput::XIEventMask::from(1u32 << xinput::GESTURE_PINCH_END_EVENT),
],
mask: vec![xi_event_mask],
}],
),
)?;
Expand Down Expand Up @@ -855,6 +858,7 @@ impl X11Window {
scale_factor: f32,
appearance: WindowAppearance,
parent_window: Option<X11WindowStatePtr>,
supports_xinput_gestures: bool,
) -> anyhow::Result<Self> {
let ptr = X11WindowStatePtr {
state: Rc::new(RefCell::new(X11WindowState::new(
Expand All @@ -872,6 +876,7 @@ impl X11Window {
scale_factor,
appearance,
parent_window,
supports_xinput_gestures,
)?)),
callbacks: Rc::new(RefCell::new(Callbacks::default())),
xcb: xcb.clone(),
Expand Down
Loading