From bf0c21e0154a9666d5be2be18cf93f3a5119953c Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Fri, 24 Apr 2009 16:43:39 +0100 Subject: [PATCH] stage: set key focus actor to NULL before emitting focus-out Someone might hide the previously focused actor in the focus-out signal handler and as key focus still appears to be on that actor we'd get re-entrant call and get glib critical from g_object_weak_unref This changes clutter_stage_get_key_focus() to return stage/NULL during focus-out signal emission. It used to be the actor focus-out was being emitted on. Fixes bug: http://bugzilla.openedhand.com/show_bug.cgi?id=1547 Signed-off-by: Emmanuele Bassi --- clutter/clutter-stage.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 63f33d72a..cdf5848df 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -1520,16 +1520,32 @@ clutter_stage_set_key_focus (ClutterStage *stage, if (priv->key_focused_actor) { + ClutterActor *old_focused_actor; + + old_focused_actor = priv->key_focused_actor; + + /* set key_focused_actor to NULL before emitting the signal or someone + * 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 + */ + g_object_weak_unref (G_OBJECT (priv->key_focused_actor), on_key_focused_weak_notify, stage); - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-out"); priv->key_focused_actor = NULL; + + g_signal_emit_by_name (old_focused_actor, "key-focus-out"); } else g_signal_emit_by_name (stage, "key-focus-out"); + /* Note, if someone changes key focus in focus-out signal handler we'd be + * overriding the latter call below moving the focus where it was originally + * intended. The order of events would be: + * 1st focus-out, 2nd focus-out (on stage), 2nd focus-in, 1st focus-in + */ + if (actor) { priv->key_focused_actor = actor;