From 3001c61de096d14fc741d636ecbd21108f3763b6 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Wed, 18 Dec 2024 12:08:28 -0500
Subject: [PATCH] x11: Use the master pointer device for absolute motion
Slave pointer devices can seemingly lag behind the master for some reason, so use the master pointer coordinates for absolute motion.
Master events are now only filtered out on the pen path.
---
src/video/x11/SDL_x11video.h | 1 +
src/video/x11/SDL_x11xinput2.c | 17 ++++++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h
index cfb864a2f3b43..f801981e8067b 100644
--- a/src/video/x11/SDL_x11video.h
+++ b/src/video/x11/SDL_x11video.h
@@ -137,6 +137,7 @@ struct SDL_VideoData
Uint32 global_mouse_buttons;
SDL_XInput2DeviceInfo *mouse_device_info;
+ int xinput_master_pointer_device;
bool xinput_hierarchy_changed;
int xrandr_event_base;
diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c
index 1bdead8511eb5..5cccb220def6e 100644
--- a/src/video/x11/SDL_x11xinput2.c
+++ b/src/video/x11/SDL_x11xinput2.c
@@ -448,13 +448,13 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
videodata->global_mouse_changed = true;
- if (xev->deviceid != xev->sourceid) {
- // Discard events from "Master" devices to avoid duplicates.
- break;
- }
-
X11_PenHandle *pen = X11_FindPenByDeviceID(xev->deviceid);
if (pen) {
+ if (xev->deviceid != xev->sourceid) {
+ // Discard events from "Master" devices to avoid duplicates.
+ break;
+ }
+
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
SDL_SendPenMotion(0, pen->pen, window, (float) xev->event_x, (float) xev->event_y);
@@ -466,13 +466,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
SDL_SendPenAxis(0, pen->pen, window, (SDL_PenAxis) i, axes[i]);
}
}
- } else if (!pointer_emulated) {
+ } else if (!pointer_emulated && xev->deviceid == videodata->xinput_master_pointer_device) {
+ // Use the master device for non-relative motion, as the slave devices can seemingly lag behind.
SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse->relative_mode || mouse->relative_mode_warp) {
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
if (window) {
X11_ProcessHitTest(_this, window->internal, (float)xev->event_x, (float)xev->event_y, false);
- SDL_SendMouseMotion(0, window, (SDL_MouseID)xev->sourceid, false, (float)xev->event_x, (float)xev->event_y);
+ SDL_SendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, false, (float)xev->event_x, (float)xev->event_y);
}
}
}
@@ -753,6 +754,8 @@ void X11_Xinput2UpdateDevices(SDL_VideoDevice *_this, bool initial_check)
}
break;
case XIMasterPointer:
+ data->xinput_master_pointer_device = dev->deviceid;
+ SDL_FALLTHROUGH;
case XISlavePointer:
{
SDL_MouseID mouseID = (SDL_MouseID)dev->deviceid;