diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index 079332ad7..dc4735375 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -318,6 +318,17 @@ static void X11_WarpMouseInternal(Window xwindow, float x, float y) { SDL_VideoData *videodata = SDL_GetVideoDevice()->driverdata; Display *display = videodata->display; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_bool warp_hack = SDL_FALSE; + + /* XWayland will only warp the cursor if it is hidden, so this workaround is required. */ + if (videodata->is_xwayland && mouse && mouse->cursor_shown) { + warp_hack = SDL_TRUE; + } + + if (warp_hack) { + X11_ShowCursor(NULL); + } #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 int deviceid = 0; if (X11_Xinput2IsInitialized()) { @@ -336,6 +347,10 @@ static void X11_WarpMouseInternal(Window xwindow, float x, float y) { X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, (int)x, (int)y); } + + if (warp_hack) { + X11_ShowCursor(SDL_GetCursor()); + } X11_XSync(display, False); videodata->global_mouse_changed = SDL_TRUE; } diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 3aba22386..d1736ecf3 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -289,8 +289,10 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT | VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; - if (X11_IsXWayland(x11_display)) + data->is_xwayland = X11_IsXWayland(x11_display); + if (data->is_xwayland) { device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED; + } return device; } diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 71a2daf9d..cafa035a0 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -133,6 +133,8 @@ struct SDL_VideoData SDL_bool is_steam_deck; SDL_bool steam_keyboard_open; + SDL_bool is_xwayland; + }; extern SDL_bool X11_UseDirectColorVisuals(void);