Browse Source

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.
Frank Praznik 4 months ago
parent
commit
3001c61de0
2 changed files with 11 additions and 7 deletions
  1. 1 0
      src/video/x11/SDL_x11video.h
  2. 10 7
      src/video/x11/SDL_x11xinput2.c

+ 1 - 0
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;

+ 10 - 7
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;