SDL: wayland: Hack surface resize into compliance with set_window_geometry

From ea28187cd5edf7b49fc9b9e866c6497a161b1da2 Mon Sep 17 00:00:00 2001
From: Sebastian Krzyszkowiak <[EMAIL REDACTED]>
Date: Mon, 2 Aug 2021 08:07:23 +0200
Subject: [PATCH] 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.
---
 src/video/wayland/SDL_waylandwindow.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index e74d43b81..eb1e78a0a 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)