stage: Do not use weak refs with actors

ClutterActor provides a signal for notifying destruction: using weak
references is neither indicated nor recommended.
This commit is contained in:
Emmanuele Bassi 2012-02-13 08:45:22 +00:00
parent 519da376f0
commit f024b852f9

View File

@ -2980,20 +2980,10 @@ clutter_stage_get_title (ClutterStage *stage)
} }
static void static void
on_key_focused_weak_notify (gpointer data, on_key_focus_destroy (ClutterActor *actor,
GObject *where_the_object_was) ClutterStage *stage)
{ {
ClutterStagePrivate *priv; /* unset the key focus */
ClutterStage *stage = CLUTTER_STAGE (data);
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
priv->key_focused_actor = NULL;
/* focused actor has dissapeared - fall back to stage
* FIXME: need some kind of signal dance/block here.
*/
clutter_stage_set_key_focus (stage, NULL); clutter_stage_set_key_focus (stage, NULL);
} }
@ -3019,10 +3009,13 @@ clutter_stage_set_key_focus (ClutterStage *stage,
priv = stage->priv; priv = stage->priv;
/* avoid emitting signals and notifications if we're setting the same
* actor as the key focus
*/
if (priv->key_focused_actor == actor) if (priv->key_focused_actor == actor)
return; return;
if (priv->key_focused_actor) if (priv->key_focused_actor != NULL)
{ {
ClutterActor *old_focused_actor; ClutterActor *old_focused_actor;
@ -3032,11 +3025,9 @@ clutter_stage_set_key_focus (ClutterStage *stage,
* might hide the previously focused actor in the signal handler and we'd * might hide the previously focused actor in the signal handler and we'd
* get re-entrant call and get glib critical from g_object_weak_unref * get re-entrant call and get glib critical from g_object_weak_unref
*/ */
g_signal_handlers_disconnect_by_func (priv->key_focused_actor,
g_object_weak_unref (G_OBJECT (priv->key_focused_actor), G_CALLBACK (on_key_focus_destroy),
on_key_focused_weak_notify,
stage); stage);
priv->key_focused_actor = NULL; priv->key_focused_actor = NULL;
g_signal_emit_by_name (old_focused_actor, "key-focus-out"); g_signal_emit_by_name (old_focused_actor, "key-focus-out");
@ -3049,13 +3040,12 @@ clutter_stage_set_key_focus (ClutterStage *stage,
* intended. The order of events would be: * intended. The order of events would be:
* 1st focus-out, 2nd focus-out (on stage), 2nd focus-in, 1st focus-in * 1st focus-out, 2nd focus-out (on stage), 2nd focus-in, 1st focus-in
*/ */
if (actor != NULL)
if (actor)
{ {
priv->key_focused_actor = actor; priv->key_focused_actor = actor;
g_object_weak_ref (G_OBJECT (actor), g_signal_connect (actor,
on_key_focused_weak_notify, "destroy", G_CALLBACK (on_key_focus_destroy),
stage); stage);
g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in");
} }