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.
This commit is contained in:
parent
505eabb78c
commit
9a6a189e36
@ -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:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user