diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index a152f8389..9b7eacbfa 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -425,6 +425,7 @@ enum REALIZE, UNREALIZE, QUEUE_REDRAW, + QUEUE_RELAYOUT, EVENT, CAPTURED_EVENT, BUTTON_PRESS_EVENT, @@ -1609,6 +1610,23 @@ clutter_actor_real_queue_redraw (ClutterActor *self, } } +void +clutter_actor_real_queue_relayout (ClutterActor *self) +{ + ClutterActorPrivate *priv = self->priv; + + priv->needs_width_request = TRUE; + priv->needs_height_request = TRUE; + priv->needs_allocation = TRUE; + + /* always repaint also (no-op if not mapped) */ + clutter_actor_queue_redraw (self); + + /* We need to go all the way up the hierarchy */ + if (priv->parent_actor) + clutter_actor_queue_relayout (priv->parent_actor); +} + /* like ClutterVertex, but with a w component */ typedef struct { gfloat x; @@ -3851,6 +3869,32 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); + /** + * ClutterActor::queue-relayout + * @actor: the actor being queued for relayout + * + * The ::queue_layout signal is emitted when clutter_actor_queue_relayout() + * is called on an actor. + * + * The default implementation for #ClutterActor chains up to the + * parent actor and queues a relayout on the parent, thus "bubbling" + * the relayout queue up through the actor graph. + * + * The main purpose of this signal is to allow relayout to be propagated + * properly in the procense of #ClutterClone actors. Applications will + * not normally need to connect to this signal. + * + * Since: 1.2 + */ + actor_signals[QUEUE_RELAYOUT] = + g_signal_new (I_("queue-relayout"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterActorClass, queue_relayout), + NULL, NULL, + clutter_marshal_VOID__VOID, + G_TYPE_NONE, 0); + /** * ClutterActor::event: * @actor: the actor which received the event @@ -4262,6 +4306,7 @@ clutter_actor_class_init (ClutterActorClass *klass) klass->get_preferred_height = clutter_actor_real_get_preferred_height; klass->allocate = clutter_actor_real_allocate; klass->queue_redraw = clutter_actor_real_queue_redraw; + klass->queue_relayout = clutter_actor_real_queue_relayout; klass->apply_transform = clutter_actor_real_apply_transform; } @@ -4385,16 +4430,7 @@ clutter_actor_queue_relayout (ClutterActor *self) priv->needs_allocation) return; /* save some cpu cycles */ - priv->needs_width_request = TRUE; - priv->needs_height_request = TRUE; - priv->needs_allocation = TRUE; - - /* always repaint also (no-op if not mapped) */ - clutter_actor_queue_redraw (self); - - /* We need to go all the way up the hierarchy */ - if (priv->parent_actor) - clutter_actor_queue_relayout (priv->parent_actor); + g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0); } /** diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index bd3407b71..d3e28a91b 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -202,6 +202,7 @@ struct _ClutterActor * @captured_event: signal class closure for #ClutterActor::captured-event * @key_focus_in: signal class closure for #ClutterActor::focus-in * @key_focus_out: signal class closure for #ClutterActor::focus-out + * @queue_relayout: class handler for #ClutterActor::queue-relayout * * Base class for actors. */ @@ -271,9 +272,11 @@ struct _ClutterActorClass void (* key_focus_in) (ClutterActor *actor); void (* key_focus_out) (ClutterActor *actor); + void (* queue_relayout) (ClutterActor *actor); + /*< private >*/ /* padding for future expansion */ - gpointer _padding_dummy[32]; + gpointer _padding_dummy[31]; }; GType clutter_actor_get_type (void) G_GNUC_CONST; diff --git a/clutter/clutter-clone.c b/clutter/clutter-clone.c index 78bc4148a..a7cc1b5a7 100644 --- a/clutter/clutter-clone.c +++ b/clutter/clutter-clone.c @@ -313,6 +313,13 @@ clone_source_queue_redraw_cb (ClutterActor *source, clutter_actor_queue_redraw (CLUTTER_ACTOR (clone)); } +static void +clone_source_queue_relayout_cb (ClutterActor *source, + ClutterClone *clone) +{ + clutter_actor_queue_relayout (CLUTTER_ACTOR (clone)); +} + static void clutter_clone_set_source_internal (ClutterClone *clone, ClutterActor *source) @@ -329,6 +336,9 @@ clutter_clone_set_source_internal (ClutterClone *clone, g_signal_handlers_disconnect_by_func (priv->clone_source, (void *) clone_source_queue_redraw_cb, clone); + g_signal_handlers_disconnect_by_func (priv->clone_source, + (void *) clone_source_queue_relayout_cb, + clone); g_object_unref (priv->clone_source); priv->clone_source = NULL; } @@ -338,6 +348,8 @@ clutter_clone_set_source_internal (ClutterClone *clone, priv->clone_source = g_object_ref (source); g_signal_connect (priv->clone_source, "queue-redraw", G_CALLBACK (clone_source_queue_redraw_cb), clone); + g_signal_connect (priv->clone_source, "queue-relayout", + G_CALLBACK (clone_source_queue_relayout_cb), clone); } g_object_notify (G_OBJECT (clone), "source");