Commit 42452f8ca50034be370296719c7e552192d5bfb0

Christian Rauch 2021-08-01T13:51:30

wayland: store and restore floating states Some Wayland compositors send (0,0) as "suggested" configure event sizes to indicate that the client has to decide on its own which sizes to used. This is commonly done when restoring from maximised, fullscreen or tiles states to fullscreen. We now store the last known floating states in a new set of variables and restore them when we receive such a (0,0) configure event.

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index e47d343..2f8784a 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -214,11 +214,23 @@ handle_configure_xdg_toplevel(void *data,
     enum xdg_toplevel_state *state;
     SDL_bool fullscreen = SDL_FALSE;
     SDL_bool maximized = SDL_FALSE;
+    SDL_bool floating = SDL_TRUE;
     wl_array_for_each(state, states) {
-        if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
+        switch (*state) {
+        case XDG_TOPLEVEL_STATE_FULLSCREEN:
             fullscreen = SDL_TRUE;
-        } else if (*state == XDG_TOPLEVEL_STATE_MAXIMIZED) {
+            floating = SDL_FALSE;
+            break;
+        case XDG_TOPLEVEL_STATE_MAXIMIZED:
             maximized = SDL_TRUE;
+            floating = SDL_FALSE;
+            break;
+        case XDG_TOPLEVEL_STATE_TILED_LEFT:
+        case XDG_TOPLEVEL_STATE_TILED_RIGHT:
+        case XDG_TOPLEVEL_STATE_TILED_TOP:
+        case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
+            floating = SDL_FALSE;
+            break;
         }
     }
 
@@ -231,8 +243,8 @@ handle_configure_xdg_toplevel(void *data,
         }
 
         if (width == 0 || height == 0) {
-            width = window->windowed.w;
-            height = window->windowed.h;
+            width = wind->floating_width;
+            height = wind->floating_height;
         }
 
         /* xdg_toplevel spec states that this is a suggestion.
@@ -274,6 +286,12 @@ handle_configure_xdg_toplevel(void *data,
         return;
     }
 
+    if (floating) {
+        /* store current floating dimensions for restoring */
+        wind->floating_width = width;
+        wind->floating_height = height;
+    }
+
     wind->resize.width = width;
     wind->resize.height = height;
 }
@@ -1303,6 +1321,11 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
     }
 #endif
 
+    if (!(window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED))) {
+        wind->floating_width = window->w;
+        wind->floating_height = window->h;
+    }
+
     region = wl_compositor_create_region(data->compositor);
     wl_region_add(region, 0, 0, window->w, window->h);
     wl_surface_set_opaque_region(wind->surface, region);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 90405fe..8cc4d03 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -68,6 +68,9 @@ typedef struct {
     struct zwp_idle_inhibitor_v1 *idle_inhibitor;
     struct xdg_activation_token_v1 *activation_token;
 
+    /* floating dimensions for restoring from maximized and fullscreen */
+    int floating_width, floating_height;
+
     SDL_atomic_t swap_interval_ready;
 
 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH