From d0effadf68e9b7299fdade38f6bcef3d1a117a12 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 31 Jul 2021 15:56:30 -0400 Subject: [PATCH] x11: Don't let XRRSetScreenSize fire a BadMatch error. This is a workaround and not a proper fix, but this is possibly complicated, and possibly a corner case, so this will do for 2.0.16, if not the foreseeable future. Reference issue #4561 --- src/video/x11/SDL_x11modes.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index 09707a5bc..7dab9ff5a 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -995,6 +995,15 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) } } +/* This catches an error from XRRSetScreenSize, as a workaround for now. */ +/* !!! FIXME: remove this later when we have a better solution. */ +static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; +static int +SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) +{ + return (e->error_code == BadMatch) ? 0 : PreXRRSetScreenSizeErrorHandler(d, e); +} + int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode) { @@ -1040,7 +1049,17 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen); mm_height = mode->h * DisplayHeightMM(display, data->screen) / DisplayHeight(display, data->screen); + + /* !!! FIXME: this can get into a problem scenario when a window is + bigger than a physical monitor in a configuration where one screen + spans multiple physical monitors. A detailed reproduction case is + discussed at https://github.com/libsdl-org/SDL/issues/4561 ... + for now we cheat and just catch the X11 error and carry on, which + is likely to cause subtle issues but is better than outright + crashing */ + PreXRRSetScreenSizeErrorHandler = X11_XSetErrorHandler(SDL_XRRSetScreenSizeErrHandler); X11_XRRSetScreenSize(display, RootWindow(display, data->screen), mode->w, mode->h, mm_width, mm_height); + X11_XSetErrorHandler(PreXRRSetScreenSizeErrorHandler); status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime, crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,