[mutter/wayland] Fix input and bounding shapes



commit 9f5087e97d7903a02a1326f0cf75ab806f40cf2c
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Feb 25 01:22:36 2014 +0100

    Fix input and bounding shapes
    
    For decorated windows, we don't want to apply any input
    shape, because the frame is always rectangular and eats
    all the input.
    The real check is in meta-window-actor, where we consider
    if we need to apply the bounding shape and the input shape
    (or the intersection of the two) to the surface-actor,
    but as an optimization we avoid querying the server in
    meta-window.
    Additionally, for undecorated windows, the "has input shape"
    check is wrong if the window has a bounding shape but not an
    input shape.

 src/compositor/meta-window-actor.c |   22 ++++++++++-----
 src/core/window-x11.c              |   51 +++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 23 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index fe29a79..c4bf879 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1760,21 +1760,27 @@ meta_window_actor_update_input_region (MetaWindowActor       *self,
   MetaWindowActorPrivate *priv = self->priv;
   cairo_region_t *region = NULL;
 
-  if (priv->window->frame != NULL && priv->window->input_region != NULL)
+  if (priv->window->frame != NULL)
     {
       region = meta_frame_get_frame_bounds (priv->window->frame);
-
-      cairo_region_subtract_rectangle (region, client_area);
-
-      /* input_region is in client window coordinates, so translate the
+      /* client area is in client window coordinates, so translate the
        * input region into that coordinate system and back */
       cairo_region_translate (region, -client_area->x, -client_area->y);
-      cairo_region_union (region, priv->window->input_region);
+      cairo_region_union_rectangle (region, client_area);
       cairo_region_translate (region, client_area->x, client_area->y);
     }
-  else if (priv->window->input_region != NULL)
+  else if (priv->window->shape_region != NULL ||
+           priv->window->input_region != NULL)
     {
-      region = cairo_region_reference (priv->window->input_region);
+      if (priv->window->shape_region != NULL)
+        {
+          region = cairo_region_copy (priv->window->shape_region);
+
+          if (priv->window->input_region != NULL)
+            cairo_region_intersect (region, priv->window->input_region);
+        }
+      else
+        region = cairo_region_reference (priv->window->input_region);
     }
   else
     {
diff --git a/src/core/window-x11.c b/src/core/window-x11.c
index e43f4c0..8939f51 100644
--- a/src/core/window-x11.c
+++ b/src/core/window-x11.c
@@ -350,11 +350,43 @@ meta_window_set_input_region (MetaWindow     *window,
     meta_compositor_window_shape_changed (window->display->compositor, window);
 }
 
+#if 0
+/* Print out a region; useful for debugging */
+static void
+print_region (cairo_region_t *region)
+{
+  int n_rects;
+  int i;
+
+  n_rects = cairo_region_num_rectangles (region);
+  g_print ("[");
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_rectangle_int_t rect;
+      cairo_region_get_rectangle (region, i, &rect);
+      g_print ("+%d+%dx%dx%d ",
+               rect.x, rect.y, rect.width, rect.height);
+    }
+  g_print ("]\n");
+}
+#endif
+
 void
 meta_window_x11_update_input_region (MetaWindow *window)
 {
   cairo_region_t *region = NULL;
 
+  /* Decorated windows don't have an input region, because
+     we don't shape the frame to match the client windows
+     (so the events are blocked by the frame anyway)
+  */
+  if (window->decorated)
+    {
+      if (window->input_region)
+        meta_window_set_input_region (window, NULL);
+      return;
+    }
+
 #ifdef HAVE_SHAPE
   if (META_DISPLAY_HAS_SHAPE (window->display))
     {
@@ -363,17 +395,6 @@ meta_window_x11_update_input_region (MetaWindow *window)
       XRectangle *rects = NULL;
       int n_rects, ordering;
 
-      int x_bounding, y_bounding, x_clip, y_clip;
-      unsigned w_bounding, h_bounding, w_clip, h_clip;
-      int bounding_shaped, clip_shaped;
-
-      meta_error_trap_push (window->display);
-      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
-                          &bounding_shaped, &x_bounding, &y_bounding,
-                          &w_bounding, &h_bounding,
-                          &clip_shaped, &x_clip, &y_clip,
-                          &w_clip, &h_clip);
-
       rects = XShapeGetRectangles (window->display->xdisplay,
                                    window->xwindow,
                                    ShapeInput,
@@ -388,10 +409,10 @@ meta_window_x11_update_input_region (MetaWindow *window)
         {
           if (n_rects > 1 ||
               (n_rects == 1 &&
-               (rects[0].x != x_bounding ||
-                rects[0].y != y_bounding ||
-                rects[0].width != w_bounding ||
-                rects[0].height != h_bounding)))
+               (rects[0].x != 0 ||
+                rects[0].y != 0 ||
+                rects[0].width != window->rect.width ||
+                rects[0].height != window->rect.height)))
             region = region_create_from_x_rectangles (rects, n_rects);
 
           XFree (rects);


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