From f2a28891532cfb4fb27fae263750d6853fa93f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 2 Jun 2023 00:23:51 +0200 Subject: [PATCH] x11: Trap XRandr errors when getting outputs during init and update We may try to update the XRR outputs and Crtcs when they're changing in the server, and so we may get BadRROutput that we're currently not handling properly. As per this, use traps and check whether we got errors, and if we did let's ignore the current output. It's not required to call init_randr13() again because if we got errors it's very likely that there's a change coming that will be notified at next iteration during which we'll repeat the init actions. --- gdk/x11/gdkscreen-x11.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index 6013265151..2456f14b29 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -685,8 +685,13 @@ init_randr13 (GdkX11Screen *x11_screen) for (i = 0; i < resources->noutput; ++i) { RROutput output = resources->outputs[i]; - XRROutputInfo *output_info = - XRRGetOutputInfo (x11_screen->xdisplay, resources, output); + XRROutputInfo *output_info; + + gdk_x11_display_error_trap_push (display); + output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output); + + if (gdk_x11_display_error_trap_pop (display)) + continue; if (output_info->connection == RR_Disconnected) { @@ -697,13 +702,22 @@ init_randr13 (GdkX11Screen *x11_screen) if (output_info->crtc) { GdkX11Monitor *monitor; - XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc); + XRRCrtcInfo *crtc; char *name; GdkRectangle geometry; GdkRectangle newgeo; int j; int refresh_rate = 0; + gdk_x11_display_error_trap_push (display); + crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc); + + if (gdk_x11_display_error_trap_pop (display)) + { + XRRFreeOutputInfo (output_info); + continue; + } + for (j = 0; j < resources->nmode; j++) { XRRModeInfo *xmode = &resources->modes[j]; @@ -775,8 +789,10 @@ init_randr13 (GdkX11Screen *x11_screen) } x11_display->primary_monitor = 0; + gdk_x11_display_error_trap_push (display); primary_output = XRRGetOutputPrimary (x11_screen->xdisplay, x11_screen->xroot_window); + gdk_x11_display_error_trap_pop_ignored (display); for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (x11_display->monitors)); i++) {