Commit 25cd749adba77e1a6f3f31f80f8768c0aaaad5b0

Simon McVittie 2021-08-12T15:12:04

x11: Don't change mode if we are already in the correct mode If we are already in the desired mode, changing it is a no-op at best, and harmful at worst: on Xwayland, it sometimes happens that we disable the crtc and cannot re-enable it. Resolves: https://github.com/libsdl-org/SDL/issues/4630 Signed-off-by: Simon McVittie <smcv@collabora.com>

diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c
index 8a9cf56..da520e3 100644
--- a/src/video/x11/SDL_x11modes.c
+++ b/src/video/x11/SDL_x11modes.c
@@ -1040,11 +1040,20 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
             return SDL_SetError("Couldn't get XRandR crtc info");
         }
 
+        if (crtc->mode == modedata->xrandr_mode) {
+#ifdef X11MODES_DEBUG
+            printf("already in desired mode 0x%lx (%ux%u), nothing to do\n",
+                   crtc->mode, crtc->width, crtc->height);
+#endif
+            status = Success;
+            goto freeInfo;
+        }
+
         X11_XGrabServer(display);
         status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime,
           0, 0, None, crtc->rotation, NULL, 0);
         if (status != Success) {
-            goto setCrtcError;
+            goto ungrabServer;
         }
 
         mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen);
@@ -1067,8 +1076,9 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
           crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
           &data->xrandr_output, 1);
 
-setCrtcError:
+ungrabServer:
         X11_XUngrabServer(display);
+freeInfo:
         X11_XRRFreeCrtcInfo(crtc);
         X11_XRRFreeOutputInfo(output_info);
         X11_XRRFreeScreenResources(res);