SDL: wayland: Prevent popup configure events from overwriting the current size with old data

From 5acd7fe208d332a6a546be65042dc3112dd84cac Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 28 Dec 2024 14:15:40 -0500
Subject: [PATCH] wayland: Prevent popup configure events from overwriting the
 current size with old data

Don't apply the supplied dimensions if they haven't changed from the last configuration event, or a newer size set programmatically can be overwritten by old data.

This check is already being done for toplevel windows, but was never added to the popup configure event.
---
 src/video/wayland/SDL_waylandwindow.c | 30 ++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 69dccf693889d..9a93c706ef25a 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -1026,16 +1026,32 @@ static void handle_configure_xdg_popup(void *data,
     x -= offset_x;
     y -= offset_y;
 
-    wind->requested.logical_width = width;
-    wind->requested.logical_height = height;
+    /* This happens when the compositor indicates that the size is
+     * up to the client, so use the cached window size here.
+     */
+    if (width == 0 || height == 0) {
+        width = wind->sdlwindow->floating.w;
+        height = wind->sdlwindow->floating.h;
+    }
 
-    if (wind->scale_to_display) {
-        x = PointToPixel(wind->sdlwindow->parent, x);
-        y = PointToPixel(wind->sdlwindow->parent, y);
-        wind->requested.pixel_width = PointToPixel(wind->sdlwindow, width);
-        wind->requested.pixel_height = PointToPixel(wind->sdlwindow, height);
+    /* Don't apply the supplied dimensions if they haven't changed from the last configuration
+     * event, or a newer size set programmatically can be overwritten by old data.
+     */
+    if (width != wind->last_configure.width || height != wind->last_configure.height) {
+        wind->requested.logical_width = width;
+        wind->requested.logical_height = height;
+
+        if (wind->scale_to_display) {
+            x = PointToPixel(wind->sdlwindow->parent, x);
+            y = PointToPixel(wind->sdlwindow->parent, y);
+            wind->requested.pixel_width = PointToPixel(wind->sdlwindow, width);
+            wind->requested.pixel_height = PointToPixel(wind->sdlwindow, height);
+        }
     }
 
+    wind->last_configure.width = width;
+    wind->last_configure.height = height;
+
     SDL_SendWindowEvent(wind->sdlwindow, SDL_EVENT_WINDOW_MOVED, x, y);
 
     if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) {