Commit a92cca1ab845f99fa660b9a8a279db02523e961b

Ethan Lee 2021-04-07T16:44:10

wayland: Use the window's display to get wl_output rather than fullscreen_mode. Because Wayland only supports FULLSCREEN_DESKTOP, fullscreen_mode never gets assigned at all, meaning driverdata is always NULL! Depending on what the compositor does this can lead to dramatically different results. GNOME was fine without this, but Plasma would trip an event that unintentionally unset the fullscreen mode and caused the game to fire a configure event _every frame_, and of course the configure would send the fullscreen_mode output which was still empty. The fix is to just use the SDL_VideoDisplay directly, which will always have a valid wl_output.

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 4550feb..e92aa44 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -250,8 +250,8 @@ handle_configure_zxdg_toplevel(void *data,
     if (!fullscreen) {
         if (window->flags & SDL_WINDOW_FULLSCREEN) {
             /* We might need to re-enter fullscreen after being restored from minimized */
-            struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata;
-            SetFullscreen(window, output);
+            SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
+            SetFullscreen(window, driverdata->output);
         }
 
         if (width == 0 || height == 0) {
@@ -366,8 +366,8 @@ handle_configure_xdg_toplevel(void *data,
     if (!fullscreen) {
         if (window->flags & SDL_WINDOW_FULLSCREEN) {
             /* We might need to re-enter fullscreen after being restored from minimized */
-            struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata;
-            SetFullscreen(window, output);
+            SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
+            SetFullscreen(window, driverdata->output);
         }
 
         if (width == 0 || height == 0) {
@@ -461,8 +461,8 @@ update_scale_factor(SDL_WindowData *window) {
        new_factor = old_factor;
    }
 
-   if (FULLSCREEN_VISIBLE(window->sdlwindow) && window->sdlwindow->fullscreen_mode.driverdata) {
-       SDL_VideoDisplay *display = wl_output_get_user_data(window->sdlwindow->fullscreen_mode.driverdata);
+   if (FULLSCREEN_VISIBLE(window->sdlwindow)) {
+       SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow);
        SDL_WaylandOutputData* driverdata = display->driverdata;
        new_factor = driverdata->scale_factor;
    }
@@ -572,8 +572,8 @@ Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
 
 void Wayland_ShowWindow(_THIS, SDL_Window *window)
 {
-    struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata;
-    SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL);
+    SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
+    SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? driverdata->output : NULL);
 }
 
 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH