diff --git a/clutter/clutter/cally/cally-root.c b/clutter/clutter/cally/cally-root.c index 53312f9db..2b1abc798 100644 --- a/clutter/clutter/cally/cally-root.c +++ b/clutter/clutter/cally/cally-root.c @@ -20,7 +20,7 @@ /** * CallyRoot: - * + * * Root object for the Cally toolkit * * #CallyRoot is the root object of the accessibility tree-like @@ -41,10 +41,6 @@ #include "clutter/clutter-stage-private.h" #include "clutter/clutter-stage-manager.h" - -/* GObject */ -static void cally_root_finalize (GObject *object); - /* AtkObject.h */ static void cally_root_initialize (AtkObject *accessible, gpointer data); @@ -54,39 +50,13 @@ static AtkObject * cally_root_ref_child (AtkObject *obj, static AtkObject * cally_root_get_parent (AtkObject *obj); static const char * cally_root_get_name (AtkObject *obj); -/* Private */ -static void cally_util_stage_added_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data); -static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data); - -typedef struct _CallyRootPrivate -{ -/* We save the CallyStage objects. Other option could save the stage - * list, and then just get the a11y object on the ref_child, etc. But - * the ref_child is more common that the init and the stage-add, - * stage-remove, so we avoid getting the accessible object - * constantly - */ - GSList *stage_list; - - /* signals id */ - gulong stage_added_id; - gulong stage_removed_id; -} CallyRootPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) +G_DEFINE_TYPE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) static void cally_root_class_init (CallyRootClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - gobject_class->finalize = cally_root_finalize; - /* AtkObject */ class->get_n_children = cally_root_get_n_children; class->ref_child = cally_root_ref_child; @@ -98,11 +68,6 @@ cally_root_class_init (CallyRootClass *klass) static void cally_root_init (CallyRoot *root) { - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - priv->stage_list = NULL; - priv->stage_added_id = 0; - priv->stage_removed_id = 0; } /** @@ -129,31 +94,6 @@ cally_root_new (void) return accessible; } -static void -cally_root_finalize (GObject *object) -{ - CallyRoot *root = CALLY_ROOT (object); - GObject *stage_manager = NULL; - CallyRootPrivate *priv; - - g_return_if_fail (CALLY_IS_ROOT (object)); - - priv = cally_root_get_instance_private (root); - if (priv->stage_list) - { - g_slist_free (priv->stage_list); - priv->stage_list = NULL; - } - - stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); - - g_clear_signal_handler (&priv->stage_added_id, stage_manager); - - g_clear_signal_handler (&priv->stage_removed_id, stage_manager); - - G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); -} - /* AtkObject.h */ static void cally_root_initialize (AtkObject *accessible, @@ -165,8 +105,6 @@ cally_root_initialize (AtkObject *accessible, ClutterStage *clutter_stage = NULL; AtkObject *cally_stage = NULL; CallyRoot *root = CALLY_ROOT (accessible); - CallyRootPrivate *priv = cally_root_get_instance_private (root); - accessible->role = ATK_ROLE_APPLICATION; accessible->accessible_parent = NULL; @@ -181,18 +119,8 @@ cally_root_initialize (AtkObject *accessible, cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage)); atk_object_set_parent (cally_stage, ATK_OBJECT (root)); - - priv->stage_list = g_slist_append (priv->stage_list, cally_stage); } - priv->stage_added_id = - g_signal_connect (G_OBJECT (stage_manager), "stage-added", - G_CALLBACK (cally_util_stage_added_cb), root); - - priv->stage_removed_id = - g_signal_connect (G_OBJECT (stage_manager), "stage-removed", - G_CALLBACK (cally_util_stage_removed_cb), root); - ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data); } @@ -201,9 +129,12 @@ static gint cally_root_get_n_children (AtkObject *obj) { CallyRoot *root = CALLY_ROOT (obj); - CallyRootPrivate *priv = cally_root_get_instance_private (root); + GObject *stage_manager = + atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); + const GSList *stages = + clutter_stage_manager_peek_stages (CLUTTER_STAGE_MANAGER (stage_manager)); - return g_slist_length (priv->stage_list); + return g_slist_length ((GSList *)stages); } static AtkObject* @@ -211,25 +142,26 @@ cally_root_ref_child (AtkObject *obj, gint i) { CallyRoot *cally_root = CALLY_ROOT (obj); - CallyRootPrivate *priv = cally_root_get_instance_private (cally_root); - GSList *stage_list = NULL; - gint num = 0; - AtkObject *item = NULL; + GObject *stage_manager = + atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_root)); + const GSList *stages = + clutter_stage_manager_peek_stages (CLUTTER_STAGE_MANAGER (stage_manager)); + gint n_stages = g_slist_length ((GSList *)stages); + ClutterStage *item = NULL; + AtkObject *accessible_item = NULL; - stage_list = priv->stage_list; - num = g_slist_length (stage_list); + g_return_val_if_fail ((i < n_stages)&&(i >= 0), NULL); - g_return_val_if_fail ((i < num)&&(i >= 0), NULL); - - item = g_slist_nth_data (stage_list, i); + item = g_slist_nth_data ((GSList *)stages, i); if (!item) - { - return NULL; - } + return NULL; - g_object_ref (item); + accessible_item = clutter_actor_get_accessible (CLUTTER_ACTOR (item)); + if (accessible_item) + g_object_ref (accessible_item); - return item; + /* TODO: cache the accessible object */ + return accessible_item; } static AtkObject* @@ -243,52 +175,3 @@ cally_root_get_name (AtkObject *obj) { return g_get_prgname (); } - -/* -------------------------------- PRIVATE --------------------------------- */ - -static void -cally_util_stage_added_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data) -{ - CallyRoot *root = CALLY_ROOT (data); - AtkObject *cally_stage = NULL; - CallyRootPrivate *priv = cally_root_get_instance_private (root); - - gint index = -1; - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - atk_object_set_parent (cally_stage, ATK_OBJECT (root)); - - priv->stage_list = g_slist_append (priv->stage_list, cally_stage); - - index = g_slist_index (priv->stage_list, cally_stage); - g_signal_emit_by_name (root, "children_changed::add", - index, cally_stage, NULL); - g_signal_emit_by_name (cally_stage, "create", 0); -} - -static void -cally_util_stage_removed_cb (ClutterStageManager *stage_manager, - ClutterStage *stage, - gpointer data) -{ - CallyRoot *root = CALLY_ROOT (data); - AtkObject *cally_stage = NULL; - CallyRootPrivate *priv - = cally_root_get_instance_private (root); - gint index = -1; - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - - index = g_slist_index (priv->stage_list, cally_stage); - - priv->stage_list = g_slist_remove (priv->stage_list, - cally_stage); - - index = g_slist_index (priv->stage_list, cally_stage); - g_signal_emit_by_name (root, "children_changed::remove", - index, cally_stage, NULL); - g_signal_emit_by_name (cally_stage, "destroy", 0); -} diff --git a/clutter/clutter/clutter-stage-manager.c b/clutter/clutter/clutter-stage-manager.c index ecf001217..32f50b7ca 100644 --- a/clutter/clutter/clutter-stage-manager.c +++ b/clutter/clutter/clutter-stage-manager.c @@ -23,7 +23,7 @@ /** * ClutterStageManager: - * + * * Maintains the list of stages * * #ClutterStageManager is a singleton object, owned by Clutter, which @@ -239,6 +239,11 @@ _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, { ClutterStageManagerPrivate *priv = clutter_stage_manager_get_instance_private (stage_manager); + AtkObject *stage_accessible = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + AtkObject *stage_manager_accessible = + atk_gobject_accessible_for_object (G_OBJECT (stage_manager)); + int index = -1; + if (g_slist_find (priv->stages, stage)) { g_warning ("Trying to add a stage to the list of managed stages, " @@ -249,6 +254,15 @@ _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, g_object_ref_sink (stage); priv->stages = g_slist_append (priv->stages, stage); + index = g_slist_index (priv->stages, stage); + + if (stage_accessible && stage_manager_accessible) + { + atk_object_set_parent (stage_accessible, stage_manager_accessible); + g_signal_emit_by_name (stage_manager_accessible, "children_changed::add", + index, stage_accessible, NULL); + g_signal_emit_by_name (stage_manager_accessible, "create", 0); + } g_signal_emit (stage_manager, manager_signals[STAGE_ADDED], 0, stage); } @@ -259,12 +273,17 @@ _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, { ClutterStageManagerPrivate *priv = clutter_stage_manager_get_instance_private (stage_manager); + AtkObject *stage_accessible = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + AtkObject *stage_manager_accessible = + atk_gobject_accessible_for_object (G_OBJECT (stage_manager)); + int index = -1; /* this might be called multiple times from a ::dispose, so it * needs to just return without warning */ if (!g_slist_find (priv->stages, stage)) return; + index = g_slist_index (priv->stages, stage); priv->stages = g_slist_remove (priv->stages, stage); /* if the default stage is being destroyed then we unset the pointer */ @@ -273,5 +292,13 @@ _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, g_signal_emit (stage_manager, manager_signals[STAGE_REMOVED], 0, stage); + if (stage_manager_accessible && stage_accessible) + { + atk_object_set_parent (stage_accessible, NULL); + g_signal_emit_by_name (stage_manager_accessible, "children_changed::remove", + index, stage_accessible, NULL); + g_signal_emit_by_name (stage_accessible, "destroy", 0); + } + g_object_unref (stage); }