瀏覽代碼

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 9 月之前
父節點
當前提交
3001c61de0
共有 2 個文件被更改,包括 11 次插入7 次删除
  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;