[mutter] window-actor: Rebuild the shape and mask when the surface updates



commit 9a6a189e3697fbcfbe4def9d9178d2b1db2ee9e3
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Jul 31 11:05:34 2014 +0200

    window-actor: Rebuild the shape and mask when the surface updates
    
    Connecting to size-changed is wrong -- size-changed tells us when
    we *told* the X server or resize the window. For X11, we're sort of
    guaranteed that the surface will be updated at some point before the
    next frame, but for Xwayland, we can't be sure that the new surface is
    attached at this point.
    
    This fixes weird artifacts when resizing apps like xclock.

 src/compositor/meta-shaped-texture.c |   16 ++++++++++++++++
 src/compositor/meta-surface-actor.c  |   18 ++++++++++++++++++
 src/compositor/meta-window-actor.c   |   12 +++++++-----
 3 files changed, 41 insertions(+), 5 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index be87e81..7ae1913 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -65,6 +65,14 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
                                 MetaShapedTexturePrivate))
 
+enum {
+  SIZE_CHANGED,
+
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL];
+
 struct _MetaShapedTexturePrivate
 {
   MetaTextureTower *paint_tower;
@@ -97,6 +105,13 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
   actor_class->paint = meta_shaped_texture_paint;
   actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
 
+  signals[SIZE_CHANGED] = g_signal_new ("size-changed",
+                                        G_TYPE_FROM_CLASS (gobject_class),
+                                        G_SIGNAL_RUN_LAST,
+                                        0,
+                                        NULL, NULL, NULL,
+                                        G_TYPE_NONE, 0);
+
   g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
 }
 
@@ -262,6 +277,7 @@ set_cogl_texture (MetaShapedTexture *stex,
       priv->tex_width = width;
       priv->tex_height = height;
       clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
+      g_signal_emit (stex, signals[SIZE_CHANGED], 0);
     }
 
   /* NB: We don't queue a redraw of the actor here because we don't
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 20933b6..d280c7a 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -36,6 +36,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
 
 enum {
   REPAINT_SCHEDULED,
+  SIZE_CHANGED,
 
   LAST_SIGNAL,
 };
@@ -120,6 +121,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
                                              NULL, NULL, NULL,
                                              G_TYPE_NONE, 0);
 
+  signals[SIZE_CHANGED] = g_signal_new ("size-changed",
+                                        G_TYPE_FROM_CLASS (object_class),
+                                        G_SIGNAL_RUN_LAST,
+                                        0,
+                                        NULL, NULL, NULL,
+                                        G_TYPE_NONE, 0);
+
   g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
 }
 
@@ -145,6 +153,14 @@ cullable_iface_init (MetaCullableInterface *iface)
 }
 
 static void
+texture_size_changed (MetaShapedTexture *texture,
+                      gpointer           user_data)
+{
+  MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
+  g_signal_emit (actor, signals[SIZE_CHANGED], 0);
+}
+
+static void
 meta_surface_actor_init (MetaSurfaceActor *self)
 {
   MetaSurfaceActorPrivate *priv;
@@ -154,6 +170,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
                                                    MetaSurfaceActorPrivate);
 
   priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
+  g_signal_connect_object (priv->texture, "size-changed",
+                           G_CALLBACK (texture_size_changed), self, 0);
   clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
 }
 
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 66a7e3c..3465ee9 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -76,6 +76,7 @@ struct _MetaWindowActorPrivate
   gint64            frame_drawn_time;
 
   guint             repaint_scheduled_id;
+  guint             size_changed_id;
 
   /*
    * These need to be counters rather than flags, since more plugins
@@ -272,10 +273,10 @@ window_appears_focused_notify (MetaWindow *mw,
 }
 
 static void
-window_size_changed (MetaWindow *mw,
-                     gpointer    data)
+surface_size_changed (MetaSurfaceActor *actor,
+                      gpointer          user_data)
 {
-  MetaWindowActor *self = META_WINDOW_ACTOR (data);
+  MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
 
   meta_window_actor_update_shape (self);
 }
@@ -368,6 +369,7 @@ set_surface (MetaWindowActor  *self,
   if (priv->surface)
     {
       g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
+      g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
       priv->repaint_scheduled_id = 0;
       clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
       g_object_unref (priv->surface);
@@ -380,6 +382,8 @@ set_surface (MetaWindowActor  *self,
       g_object_ref_sink (priv->surface);
       priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
                                                      G_CALLBACK (surface_repaint_scheduled), self);
+      priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
+                                                G_CALLBACK (surface_size_changed), self);
       clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
 
       /* If the previous surface actor was frozen, start out
@@ -489,8 +493,6 @@ meta_window_actor_set_property (GObject      *object,
       priv->window = g_value_dup_object (value);
       g_signal_connect_object (priv->window, "notify::appears-focused",
                                G_CALLBACK (window_appears_focused_notify), self, 0);
-      g_signal_connect_object (priv->window, "size-changed",
-                               G_CALLBACK (window_size_changed), self, 0);
       break;
     case PROP_NO_SHADOW:
       {


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