Commit 9a6a189e authored by Jasper St. Pierre's avatar Jasper St. Pierre

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.
parent 505eabb7
......@@ -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
......
......@@ -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));
}
......@@ -144,6 +152,14 @@ cullable_iface_init (MetaCullableInterface *iface)
iface->reset_culling = meta_surface_actor_reset_culling;
}
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)
{
......@@ -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));
}
......
......@@ -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:
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment