Browse Source

video: Disable mouse warp on fullscreen transitions for Wayland and XWayland

At best, it simply doesn't work, and if it does, it frequently warps the pointer to the wrong position as the window animates in/out of fullscreen mode.

It can also inadvertently trigger the relative warp mode emulation mode on Wayland if a fullscreen transition occurs while the client has the pointer hidden.
Frank Praznik 11 months ago
parent
commit
b1e01b971b

+ 2 - 1
src/video/SDL_sysvideo.h

@@ -158,7 +158,8 @@ typedef enum
     VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT = 0x02,
     VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS = 0x04,
     VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY = 0x08,
-    VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES = 0x10
+    VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES = 0x10,
+    VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS = 0x20
 } DeviceCaps;
 
 struct SDL_VideoDevice

+ 9 - 2
src/video/SDL_video.c

@@ -190,6 +190,11 @@ static SDL_bool SDL_SendsDisplayChanges(SDL_VideoDevice *_this)
     return !!(_this->device_caps & VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES);
 }
 
+static SDL_bool SDL_DisableMouseWarpOnFullscreenTransitions(SDL_VideoDevice *_this)
+{
+    return !!(_this->device_caps & VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS);
+}
+
 /* Hint to treat all window ops as synchronous */
 static SDL_bool syncHint;
 
@@ -1822,7 +1827,9 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
             }
 
             /* Restore the cursor position */
-            SDL_RestoreMousePosition(window);
+            if (!SDL_DisableMouseWarpOnFullscreenTransitions(_this)) {
+                SDL_RestoreMousePosition(window);
+            }
         }
     } else {
         SDL_bool resized = SDL_FALSE;
@@ -1866,7 +1873,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
             }
 
             /* Restore the cursor position if we've exited fullscreen on a display */
-            if (display) {
+            if (display && !SDL_DisableMouseWarpOnFullscreenTransitions(_this)) {
                 SDL_RestoreMousePosition(window);
             }
         }

+ 2 - 1
src/video/wayland/SDL_waylandvideo.c

@@ -523,7 +523,8 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
     device->device_caps = VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED |
                           VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
                           VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS |
-                          VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES;
+                          VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES |
+                          VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS;
 
     return device;
 }

+ 2 - 1
src/video/x11/SDL_x11video.c

@@ -292,7 +292,8 @@ static SDL_VideoDevice *X11_CreateDevice(void)
 
     data->is_xwayland = X11_IsXWayland(x11_display);
     if (data->is_xwayland) {
-        device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED;
+        device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED |
+                               VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS;
     }
 
     return device;