SDL: x11: Ignore border extents when the border hint is unset

From 199f7cc3b119bfe5184703054dd1814eaac6898e Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Fri, 22 Dec 2023 12:17:06 -0500
Subject: [PATCH] x11: Ignore border extents when the border hint is unset

Old extent events can arrive after the border hint has been unset. Ignore the reported values in this case to avoid reporting bogus border sizes.
---
 src/video/x11/SDL_x11events.c | 33 +++++++++++++++++++--------------
 src/video/x11/SDL_x11window.c |  6 +-----
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index c5072eab6dcc..7906c12dfd5f 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -884,18 +884,24 @@ void X11_GetBorderValues(SDL_WindowData *data)
     int format;
     unsigned long nitems, bytes_after;
     unsigned char *property;
-    if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) {
-        if (type != None && nitems == 4) {
-            data->border_left = (int)((long *)property)[0];
-            data->border_right = (int)((long *)property)[1];
-            data->border_top = (int)((long *)property)[2];
-            data->border_bottom = (int)((long *)property)[3];
-        }
-        X11_XFree(property);
+
+    /* Some compositors will send extents even when the border hint is turned off. Ignore them in this case. */
+    if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) {
+        if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) {
+            if (type != None && nitems == 4) {
+                data->border_left = (int)((long *)property)[0];
+                data->border_right = (int)((long *)property)[1];
+                data->border_top = (int)((long *)property)[2];
+                data->border_bottom = (int)((long *)property)[3];
+            }
+            X11_XFree(property);
 
 #ifdef DEBUG_XEVENTS
-        printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom);
+            printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom);
 #endif
+        }
+    } else {
+        data->border_left = data->border_top = data->border_right = data->border_bottom = 0;
     }
 }
 
@@ -1745,11 +1751,10 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
                     X11_XMoveWindow(display, data->xwindow, data->window->floating.x - data->border_left, data->window->floating.y - data->border_top);
                     X11_XResizeWindow(display, data->xwindow, data->window->floating.w, data->window->floating.h);
                 }
-
-                if (!(data->window->flags & SDL_WINDOW_FULLSCREEN) && data->toggle_borders) {
-                    data->toggle_borders = SDL_FALSE;
-                    X11_SetWindowBordered(_this, data->window, !(data->window->flags & SDL_WINDOW_BORDERLESS));
-                }
+            }
+            if (!(data->window->flags & SDL_WINDOW_FULLSCREEN) && data->toggle_borders) {
+                data->toggle_borders = SDL_FALSE;
+                X11_SetWindowBordered(_this, data->window, !(data->window->flags & SDL_WINDOW_BORDERLESS));
             }
         }
     } break;
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 3ca21df70e3c..ddb8f26aa6ea 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -1233,11 +1233,7 @@ void X11_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool
         X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
 
         /* Turning the borders off doesn't send an extent event, so they must be cleared here. */
-        if (bordered) {
-            X11_GetBorderValues(data);
-        } else {
-            data->border_top = data->border_left = data->border_bottom = data->border_right = 0;
-        }
+        X11_GetBorderValues(data);
 
         /* Make sure the window manager didn't resize our window for the difference. */
         X11_XResizeWindow(display, data->xwindow, window->floating.w, window->floating.h);