[mutter] Track the shape of the client window directly



commit 7e0a56fb8031b3e18abf520f9d2fde4d672a82fc
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Jul 20 00:29:06 2011 -0400

    Track the shape of the client window directly
    
    Since we're not setting the frame's output shape any more, it doesn't
    make sense to calculate the output shape based on the frame window.
    Instead, track the client window directly and calculate the output shape
    based on that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644930

 src/compositor/compositor.c                |   39 +++-------
 src/compositor/meta-window-actor-private.h |    3 +-
 src/compositor/meta-window-actor.c         |  119 +++++++++++-----------------
 src/core/display.c                         |    4 +
 src/meta/compositor.h                      |    3 +
 5 files changed, 66 insertions(+), 102 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 8c03b4a..65e2b01 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -109,28 +109,6 @@ process_damage (MetaCompositor     *compositor,
   meta_window_actor_process_damage (window_actor, event);
 }
 
-#ifdef HAVE_SHAPE
-static void
-process_shape (MetaCompositor *compositor,
-               XShapeEvent    *event,
-               MetaWindow     *window)
-{
-  MetaWindowActor *window_actor;
-
-  if (window == NULL)
-    return;
-
-  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
-  if (window_actor == NULL)
-    return;
-
-  if (event->kind == ShapeBounding)
-    {
-      meta_window_actor_update_shape (window_actor, event->shaped);
-    }
-}
-#endif
-
 static void
 process_property_notify (MetaCompositor	*compositor,
                          XPropertyEvent *event,
@@ -674,6 +652,16 @@ is_grabbed_event (XEvent *event)
 
   return FALSE;
 }
+
+void
+meta_compositor_window_shape_changed (MetaCompositor *compositor,
+                                      MetaWindow     *window)
+{
+  MetaWindowActor *window_actor;
+  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
+  meta_window_actor_update_shape (window_actor);
+}
+
 /**
  * meta_compositor_process_event: (skip)
  *
@@ -753,13 +741,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
 	  DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
           process_damage (compositor, (XDamageNotifyEvent *) event, window);
         }
-#ifdef HAVE_SHAPE
-      else if (event->type == meta_display_get_shape_event_base (compositor->display) + ShapeNotify)
-	{
-	  DEBUG_TRACE ("meta_compositor_process_event (process_shape)\n");
-	  process_shape (compositor, (XShapeEvent *) event, window);
-	}
-#endif /* HAVE_SHAPE */
       break;
     }
 
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 068bfb9..79aafb6 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -33,8 +33,7 @@ void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
 gboolean meta_window_actor_effect_in_progress  (MetaWindowActor *self);
 void     meta_window_actor_sync_actor_position (MetaWindowActor *self);
 void     meta_window_actor_sync_visibility     (MetaWindowActor *self);
-void     meta_window_actor_update_shape        (MetaWindowActor *self,
-                                                gboolean         shaped);
+void     meta_window_actor_update_shape        (MetaWindowActor *self);
 void     meta_window_actor_update_opacity      (MetaWindowActor *self);
 void     meta_window_actor_mapped              (MetaWindowActor *self);
 void     meta_window_actor_unmapped            (MetaWindowActor *self);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index ea6c690..16f227a 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -96,7 +96,6 @@ struct _MetaWindowActorPrivate
 
   guint		    visible                : 1;
   guint		    mapped                 : 1;
-  guint		    shaped                 : 1;
   guint		    argb32                 : 1;
   guint		    disposed               : 1;
   guint             redecorating           : 1;
@@ -156,8 +155,6 @@ static void meta_window_actor_clear_shape_region    (MetaWindowActor *self);
 static void meta_window_actor_clear_bounding_region (MetaWindowActor *self);
 static void meta_window_actor_clear_shadow_clip     (MetaWindowActor *self);
 
-static gboolean is_shaped                (MetaDisplay  *display,
-                                          Window        xwindow);
 /*
  * Register GType wrapper for XWindowAttributes, so we do not have to
  * query window attributes in the MetaWindowActor constructor but can pass
@@ -392,14 +389,6 @@ meta_window_actor_constructed (GObject *object)
   Display                *xdisplay = meta_display_get_xdisplay (display);
   XRenderPictFormat      *format;
 
-#ifdef HAVE_SHAPE
-  /* Listen for ShapeNotify events on the window */
-  if (meta_display_has_shape (display))
-    XShapeSelectInput (xdisplay, xwindow, ShapeNotifyMask);
-#endif
-
-  priv->shaped = is_shaped (display, xwindow);
-
   if (priv->attrs.class == InputOnly)
     priv->damage = None;
   else
@@ -441,7 +430,7 @@ meta_window_actor_constructed (GObject *object)
     }
 
   meta_window_actor_update_opacity (self);
-  meta_window_actor_update_shape (self, priv->shaped);
+  meta_window_actor_update_shape (self);
 }
 
 static void
@@ -671,7 +660,7 @@ meta_window_actor_get_shape_bounds (MetaWindowActor       *self,
    * where getting the shape fails on a window being destroyed
    * and similar.
    */
-  if (priv->shaped && priv->shape_region)
+  if (priv->shape_region)
     cairo_region_get_extents (priv->shape_region, bounds);
   else if (priv->bounding_region)
     cairo_region_get_extents (priv->bounding_region, bounds);
@@ -810,25 +799,6 @@ meta_window_actor_get_paint_volume (ClutterActor       *actor,
 }
 
 static gboolean
-is_shaped (MetaDisplay *display, Window xwindow)
-{
-  Display *xdisplay = meta_display_get_xdisplay (display);
-  gint     xws, yws, xbs, ybs;
-  guint    wws, hws, wbs, hbs;
-  gint     bounding_shaped, clip_shaped;
-
-  if (meta_display_has_shape (display))
-    {
-      XShapeQueryExtents (xdisplay, xwindow, &bounding_shaped,
-                          &xws, &yws, &wws, &hws, &clip_shaped,
-                          &xbs, &ybs, &wbs, &hbs);
-      return (bounding_shaped != 0);
-    }
-
-  return FALSE;
-}
-
-static gboolean
 meta_window_actor_has_shadow (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
@@ -1679,22 +1649,7 @@ meta_window_actor_update_bounding_region (MetaWindowActor *self,
 
   priv->bounding_region = cairo_region_create_rectangle (&bounding_rectangle);
 
-  if (priv->shaped)
-    {
-      /* If we're shaped, the implicit shape region clipping we need to do needs
-       * to be updated.
-       */
-      meta_window_actor_update_shape (self, TRUE);
-    }
-  else
-    {
-      /* When we're shaped, we use the shape region to generate the shadow; the shape
-       * region only changes when we get ShapeNotify event; but for unshaped windows
-       * we generate the shadow from the bounding region, so we need to recompute
-       * the shadow when the size changes.
-       */
-      meta_window_actor_invalidate_shadow (self);
-    }
+  meta_window_actor_update_shape (self);
 
   g_signal_emit (self, signals[SIZE_CHANGED], 0);
 }
@@ -1743,7 +1698,7 @@ meta_window_actor_get_obscured_region (MetaWindowActor *self)
 
   if (!priv->argb32 && priv->opacity == 0xff && priv->back_pixmap)
     {
-      if (priv->shaped)
+      if (priv->shape_region)
         return priv->shape_region;
       else
         return priv->bounding_region;
@@ -1793,16 +1748,10 @@ meta_window_actor_set_visible_region (MetaWindowActor *self,
   /* Get the area of the window texture that would be drawn if
    * we weren't obscured at all
    */
-  if (priv->shaped)
-    {
-      if (priv->shape_region)
-        texture_clip_region = cairo_region_copy (priv->shape_region);
-    }
-  else
-    {
-      if (priv->bounding_region)
-        texture_clip_region = cairo_region_copy (priv->bounding_region);
-    }
+  if (priv->shape_region)
+    texture_clip_region = cairo_region_copy (priv->shape_region);
+  else if (priv->bounding_region)
+    texture_clip_region = cairo_region_copy (priv->bounding_region);
 
   if (!texture_clip_region)
     texture_clip_region = cairo_region_create ();
@@ -2014,7 +1963,7 @@ check_needs_shadow (MetaWindowActor *self)
     {
       if (priv->shadow_shape == NULL)
         {
-          if (priv->shaped && priv->shape_region)
+          if (priv->shape_region)
             priv->shadow_shape = meta_window_shape_new (priv->shape_region);
           else if (priv->bounding_region)
             priv->shadow_shape = meta_window_shape_new (priv->bounding_region);
@@ -2106,18 +2055,51 @@ check_needs_reshape (MetaWindowActor *self)
   if (!priv->needs_reshape)
     return;
 
-  region = NULL;
+  meta_shaped_texture_set_shape_region (META_SHAPED_TEXTURE (priv->actor), NULL);
+  meta_window_actor_clear_shape_region (self);
+
+  region = meta_window_get_frame_bounds (priv->window);
+  if (region != NULL)
+    {
+      /* This returns the window's internal frame bounds region,
+       * so we need to copy it because we modify it below. */
+      region = cairo_region_copy (region);
+    }
+  else
+    {
+      /* If we have no region, we have no frame. We have no frame,
+       * so just use the bounding region instead */
+      region = cairo_region_copy (priv->bounding_region);
+    }
 
 #ifdef HAVE_SHAPE
-  if (priv->shaped)
+  if (priv->window->has_shape)
     {
       Display *xdisplay = meta_display_get_xdisplay (display);
       XRectangle *rects;
       int n_rects, ordering;
+      cairo_rectangle_int_t client_area;
+
+      client_area.width = priv->window->rect.width;
+      client_area.height = priv->window->rect.height;
+
+      if (priv->window->frame)
+        {
+          client_area.x = priv->window->frame->child_x;
+          client_area.y = priv->window->frame->child_y;
+        }
+      else
+        {
+          client_area.x = 0;
+          client_area.y = 0;
+        }
+
+      /* Punch out client area. */
+      cairo_region_subtract_rectangle (region, &client_area);
 
       meta_error_trap_push (display);
       rects = XShapeGetRectangles (xdisplay,
-                                   priv->xwindow,
+                                   priv->window->xwindow,
                                    ShapeBounding,
                                    &n_rects,
                                    &ordering);
@@ -2126,13 +2108,10 @@ check_needs_reshape (MetaWindowActor *self)
       if (rects)
         {
           int i;
-
-          region = cairo_region_create ();
-
           for (i = 0; i < n_rects; i ++)
             {
-              cairo_rectangle_int_t rect = { rects[i].x,
-                                             rects[i].y,
+              cairo_rectangle_int_t rect = { rects[i].x + client_area.x,
+                                             rects[i].y + client_area.y,
                                              rects[i].width,
                                              rects[i].height };
               cairo_region_union_rectangle (region, &rect);
@@ -2154,12 +2133,10 @@ check_needs_reshape (MetaWindowActor *self)
 }
 
 void
-meta_window_actor_update_shape (MetaWindowActor   *self,
-                                gboolean        shaped)
+meta_window_actor_update_shape (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
 
-  priv->shaped = shaped;
   priv->needs_reshape = TRUE;
   if (priv->shadow_shape != NULL)
     {
diff --git a/src/core/display.c b/src/core/display.c
index 412ecc1..12ab18d 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1696,6 +1696,10 @@ event_callback (XEvent   *event,
                               "Window %s shape changed\n",
                               window->desc);
                 }
+
+              if (display->compositor)
+                meta_compositor_window_shape_changed (display->compositor,
+                                                      window);
             }
         }
       else
diff --git a/src/meta/compositor.h b/src/meta/compositor.h
index f9a42b2..4ed4cab 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -64,6 +64,9 @@ void meta_compositor_manage_screen   (MetaCompositor *compositor,
 void meta_compositor_unmanage_screen (MetaCompositor *compositor,
                                       MetaScreen     *screen);
 
+void meta_compositor_window_shape_changed (MetaCompositor *compositor,
+                                           MetaWindow     *window);
+
 gboolean meta_compositor_process_event (MetaCompositor *compositor,
                                         XEvent         *event,
                                         MetaWindow     *window);



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