x11: Trap XRandr errors when getting outputs during init and update
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Thu, 1 Jun 2023 22:23:51 +0000 (00:23 +0200)
committerSimon McVittie <smcv@debian.org>
Wed, 8 Nov 2023 16:30:21 +0000 (16:30 +0000)
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.

Forwarded: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6047
Origin: 3.24.39, commit:b938e4e6ac75af57ed5cd844c96738f01d57f24c

Gbp-Pq: Name x11-Trap-XRandr-errors-when-getting-outputs-during-init-a.patch

gdk/x11/gdkscreen-x11.c

index c2b7480c48494756abb55c9431b15ab653f29b81..f79e508a16ba89ee5193043c1648787c3355492b 100644 (file)
@@ -794,8 +794,13 @@ init_randr13 (GdkScreen *screen, gboolean *changed)
   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;
 
       /* Non RandR1.2+ X driver have output name "default" */
       randr12_compat |= !g_strcmp0 (output_info->name, "default");
@@ -809,13 +814,22 @@ init_randr13 (GdkScreen *screen, gboolean *changed)
       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];
@@ -913,8 +927,11 @@ init_randr13 (GdkScreen *screen, gboolean *changed)
 
   old_primary = x11_display->primary_monitor;
   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 < x11_display->monitors->len; ++i)
     {