[mutter] window-x11: Fix windows that set empty input shapes



commit c408cf7aacf152e672dd2741d4aa6658250a255d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Nov 26 12:45:26 2014 -0800

    window-x11: Fix windows that set empty input shapes
    
    Windows that set empty input shapes get n_rects of 0 when querying them
    later, which makes sense, but the code that interpreted the result
    translated it into a NULL input shape, which meant it was the same as
    the bounding region. As such, an empty input shape would actually get
    interpreted as a full input shape!
    
    We, ourselves, set an empty input shape on tray icon windows in
    gnome-shell since we would handle the picking ourselves. This meant that
    we'd actually get the MetaSurfaceActorX11 when hovering over the tray
    icon, instead of the ShellGTKEmbed that we capture events on and react
    to.
    
    This fixes weird tray icon behavior in gnome-shell.

 src/x11/window-x11.c |   53 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 39 insertions(+), 14 deletions(-)
---
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 1dca3e3..0d6d142 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -1684,7 +1684,7 @@ meta_window_x11_update_input_region (MetaWindow *window)
       /* Translate the set of XShape rectangles that we
        * get from the X server to a cairo_region. */
       XRectangle *rects = NULL;
-      int n_rects, ordering;
+      int n_rects = -1, ordering;
 
       meta_error_trap_push (window->display);
       rects = XShapeGetRectangles (window->display->xdisplay,
@@ -1694,21 +1694,46 @@ meta_window_x11_update_input_region (MetaWindow *window)
                                    &ordering);
       meta_error_trap_pop (window->display);
 
-      /* XXX: The x shape extension doesn't provide a way to only test if an
-       * input shape has been specified, so we have to query and throw away the
-       * rectangles. */
-      if (rects)
-        {
-          if (n_rects > 1 ||
-              (n_rects == 1 &&
-               (rects[0].x != 0 ||
-                rects[0].y != 0 ||
-                rects[0].width != priv->client_rect.width ||
-                rects[0].height != priv->client_rect.height)))
-            region = region_create_from_x_rectangles (rects, n_rects);
+      /* XXX: The X Shape specification is quite unfortunately specified.
+       *
+       * By default, the window has a shape the same as its bounding region,
+       * which we consider "NULL".
+       *
+       * If the window sets an empty region, then we'll get n_rects as 0
+       * and rects as NULL, which we need to transform back into an empty
+       * region.
+       *
+       * It would be great to have a less-broken extension for this, but
+       * hey, it's X11!
+       */
 
-          XFree (rects);
+      if (n_rects == -1)
+        {
+          /* We had an error. */
+          region = NULL;
+        }
+      else if (n_rects == 0)
+        {
+          /* Client set an empty region. */
+          region = cairo_region_create ();
         }
+      else if (n_rects == 1 &&
+               (rects[0].x == 0 ||
+                rects[0].y == 0 ||
+                rects[0].width == priv->client_rect.width ||
+                rects[0].height == priv->client_rect.height))
+        {
+          /* This is the bounding region case. Keep the
+           * region as NULL. */
+          region = NULL;
+        }
+      else
+        {
+          /* Window has a custom shape. */
+          region = region_create_from_x_rectangles (rects, n_rects);
+        }
+
+      meta_XFree (rects);
     }
 
   if (region != NULL)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]