SDL icon indicating copy to clipboard operation
SDL copied to clipboard

SDL 3 Cursor freeze when switching Windowed <-> Fullscreen with hidden cursor on Wayland

Open Dragon-Baroque opened this issue 1 year ago • 3 comments

In Exult, the cursor gets a SDL_HideCursor to display the original game pointer instead.

In SDL 3, switching back and forth from Windowed Exult to Fullscreen Exult results in a cursor freeze under Linux over Wayland.

This can be reproduced with the SDL 3 testwm - Linux over Wayland - provided one adds in test/testwm.c, main function the two lines at the bottom of :

    ...
    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) {
        SDLTest_CommonQuit(state);
        return 1;
    }

    SDL_HideCursor(); // Hide the cursor
    SDL_ShowCursor(); // Show the cursor
    ...

With that change, testwm works normally until one switches it to Fullscreen ( Alt-Enter ). Then the cursor is frozen, unless it was outside of the testwm window when the switch occurred. And then at the switch back to Windowed, the cursor is unconditionally frozen.

For what it is worth :

  • When the freeze occurs, SDL does not receive any mouse motion event from Wayland. Unless it has received first a mouse enter event, that is, in the case where the cursor was outside the testwm window prior to the switch to fullscreen.
  • In src/video/wayland/SDL_waylandmouse.c, Wayland_ShowCursor( NULL ) [ coming from SDL_HideCursor ] performs a wl_pointer_set_cursor(pointer, input->pointer_enter_serial, NULL, 0, 0);.
  • Wayland_ShowCursor( aCursor ) [ from SDL_ShowCursor ] does not perform the opposite wl_pointer_set_cursor(pointer, input->pointer_enter_serial, data->surface, data->hot_x / scale, data->hot_y / scale); because it has used the Wayland_SetSystemCursorShape path instead.

Dragon-Baroque avatar May 15 '24 18:05 Dragon-Baroque

Can you provide more details about your system, particularly what desktop you are running? Quickly trying your repro case on my desktop with Fedora 40 + GNOME doesn't reproduce your issue.

Kontrabant avatar May 15 '24 20:05 Kontrabant

Fedora 40 Plasma over Wayland.

With SDL 3 at main commit 60d355eb0 [origin/main] Sync SDL3 wiki -> header. Add two lines to test/testwm.c :

diff --git a/test/testwm.c b/test/testwm.c
index 3e1a75978..c191a8067 100644
--- a/test/testwm.c
+++ b/test/testwm.c
@@ -289,6 +289,8 @@ int main(int argc, char *argv[])
         SDL_RenderClear(renderer);
     }
 
+       SDL_HideCursor();
+       SDL_ShowCursor();
     /* Main render loop */
     done = 0;
 #ifdef SDL_PLATFORM_EMSCRIPTEN

Build SDL 3, run testwm, bring the cursor into the testwm window, switch to fullscreen with Alt-Enter, cursor is frozen.

Dragon-Baroque avatar May 15 '24 20:05 Dragon-Baroque

Perfect, thank you!

Kontrabant avatar May 15 '24 20:05 Kontrabant

Ah, the cursor visibility flag wasn't being set properly when setting the cursor via the cursor shape protocol, which in turn caused the pointer warp emulation to activate when the video core attempted to warp the pointer when toggling fullscreen, which resulted in the pointer being locked and staying locked.

Kontrabant avatar May 16 '24 15:05 Kontrabant

Backported to SDL2 as well.

Kontrabant avatar May 16 '24 16:05 Kontrabant