Commit ea28187cd5edf7b49fc9b9e866c6497a161b1da2

Sebastian Krzyszkowiak 2021-08-02T08:07:23

wayland: Hack surface resize into compliance with set_window_geometry We have issues with correct resize sequence and happen to commit old-sized buffers even after configure event for the new size has been already acknowledged. While the reason for that stays unknown, let's at least workaround the problem by faking window geometry into expected size. This does not fix visual glitch on e.g. fullscreen toggling, but having a split-second glitch is still a much better outcome than being terminated by the compositor for protocol violation.

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index e74d43b..eb1e78a 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -1204,6 +1204,7 @@ static void
 Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
 {
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_VideoData *viddata = data->waylandData;
 
     struct wl_region *region;
     window->w = 0;
@@ -1226,6 +1227,15 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
     wl_region_add(region, 0, 0, window->w, window->h);
     wl_surface_set_opaque_region(data->surface, region);
     wl_region_destroy(region);
+
+    /* XXX: This workarounds issues with commiting buffers with old size after
+     * already acknowledging the new size, which can cause protocol violations.
+     * It doesn't fix the first frames after resize being glitched visually,
+     * but at least lets us not be terminated by the compositor.
+     * Can be removed once SDL's resize logic becomes compliant. */
+    if (viddata->shell.xdg && data->shell_surface.xdg.surface) {
+       xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, window->w, window->h);
+    }
 }
 
 void
@@ -1284,6 +1294,11 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
     wl_region_add(region, 0, 0, window->w, window->h);
     wl_surface_set_opaque_region(wind->surface, region);
     wl_region_destroy(region);
+
+    /* Update the geometry which may have been set by a hack in Wayland_HandleResize */
+    if (data->shell.xdg && wind->shell_surface.xdg.surface) {
+       xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, window->w, window->h);
+    }
 }
 
 void Wayland_SetWindowTitle(_THIS, SDL_Window * window)