X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=atk-adaptor%2Faccessible-register.c;h=63fc10694f1ba73ad9404d02e023f6fefeaf71f8;hb=4ac4e0d4876bd1535748e8dc8ccf35db1e173673;hp=d235c2ea6632c6b118fee86e407a6ab1afc98b7b;hpb=7461acb2027e2e4f0d8e6fa7a6c6630229192c16;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c index d235c2e..63fc106 100644 --- a/atk-adaptor/accessible-register.c +++ b/atk-adaptor/accessible-register.c @@ -240,16 +240,15 @@ append_children (AtkObject *accessible, GQueue *traversal) for (i =0; i < atk_object_get_n_accessible_children (accessible); i++) { current = atk_object_ref_accessible_child (accessible, i); + if (current) + { #ifdef SPI_ATK_DEBUG - non_owned_accessible (current); + non_owned_accessible (current); #endif - if (!has_manages_descendants (current)) - { - g_queue_push_tail (traversal, current); - } - else - { - g_object_unref (G_OBJECT (current)); + if (!has_manages_descendants (current)) + g_queue_push_tail (traversal, current); + else + g_object_unref (G_OBJECT (current)); } } } @@ -363,6 +362,63 @@ atk_dbus_path_to_object (const char *path) } /* + * TODO WARNING HACK This function is dangerous. + * It should only be called before sending an event on an + * object that has not already been registered. + */ +gchar * +atk_dbus_object_attempt_registration (AtkObject *accessible) +{ + guint ref; + + ref = object_to_ref (accessible); + if (!ref) + { + /* See if the object is attached to the main tree */ + AtkObject *current, *prev = NULL; + guint cref = 0; + + /* This should iterate until it hits a NULL or registered parent */ + prev = accessible; + current = atk_object_get_parent (accessible); + if (current) + cref = object_to_ref (current); + while (current && !cref) + { + prev = current; + current = atk_object_get_parent (current); + if (current) + cref = object_to_ref (current); + } + + /* A registered parent, with non-registered child, has been found */ + if (current) + { + register_subtree (prev); + } + + /* The object SHOULD be registered now. If it isn't - I give up */ + ref = object_to_ref (accessible); + if (ref) + { + return ref_to_path (ref); + } + else + { +#ifdef SPI_ATK_DEBUG + g_debug ("AT-SPI: Could not register a non-attached accessible object"); +#endif + return NULL; + } + } + else + { + return ref_to_path (ref); + } +} + + +/* * Used to lookup a D-Bus path from the AtkObject. */ gchar * @@ -385,6 +441,12 @@ atk_dbus_desktop_object_path () /*---------------------------------------------------------------------------*/ +typedef gboolean (*TreeUpdateAction) (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data, + AtkObject *accessible); + /* * Events are not evaluated for non-registered accessibles. * @@ -394,22 +456,22 @@ atk_dbus_desktop_object_path () * When a parent is changed the subtree is de-registered * if the parent is not attached to the root accessible. */ +/* TODO Turn this function into a macro? */ static gboolean -tree_update_listener (GSignalInvocationHint *signal_hint, - guint n_param_values, - const GValue *param_values, - gpointer data) +tree_update_wrapper (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data, + TreeUpdateAction action) { AtkObject *accessible; - AtkPropertyValues *values; - const gchar *pname = NULL; g_static_rec_mutex_lock (®istration_mutex); /* Ensure that only registered accessibles * have their signals processed. */ - accessible = g_value_get_object (¶m_values[0]); + accessible = ATK_OBJECT(g_value_get_object (¶m_values[0])); g_return_val_if_fail (ATK_IS_OBJECT (accessible), TRUE); if (object_to_ref (accessible)) @@ -420,57 +482,74 @@ tree_update_listener (GSignalInvocationHint *signal_hint, g_debug ("AT-SPI: Tree update listener"); #endif + action (signal_hint, n_param_values, param_values, data, accessible); + recursion_check_unset (); + } + + g_static_rec_mutex_unlock (®istration_mutex); + + return TRUE; +} + +static gboolean +tree_update_state_action (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data, + AtkObject *accessible) +{ + update_accessible (accessible); +} + +static gboolean +tree_update_state_listener (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + tree_update_wrapper (signal_hint, n_param_values, param_values, data, tree_update_state_action); +} + +static gboolean +tree_update_property_action (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data, + AtkObject *accessible) +{ + AtkPropertyValues *values; + const gchar *pname = NULL; values = (AtkPropertyValues*) g_value_get_pointer (¶m_values[1]); pname = values[0].property_name; if (strcmp (pname, "accessible-name") == 0 || - strcmp (pname, "accessible-description") == 0) + strcmp (pname, "accessible-description") == 0 || + strcmp (pname, "accessible-parent") == 0) { update_accessible (accessible); } /* Parent value us updated by child-add signal of parent object */ - - recursion_check_unset (); - } - - g_static_rec_mutex_unlock (®istration_mutex); - - return TRUE; } -/* - * Events are not evaluated for non registered accessibles. - * - * When the children of a registered accessible are changed - * the subtree, rooted at the child is registered. - */ static gboolean -tree_update_children_listener (GSignalInvocationHint *signal_hint, +tree_update_property_listener (GSignalInvocationHint *signal_hint, guint n_param_values, const GValue *param_values, gpointer data) { - AtkObject *accessible; - const gchar *detail = NULL; - AtkObject *child; - - g_static_rec_mutex_lock (®istration_mutex); - - /* Ensure that only registered accessibles - * have their signals processed. - */ - accessible = g_value_get_object (¶m_values[0]); - g_return_val_if_fail (ATK_IS_OBJECT (accessible), TRUE); - - if (object_to_ref (accessible)) - { -#ifdef SPI_ATK_DEBUG - if (recursion_check_and_set ()) - g_warning ("AT-SPI: Recursive use of registration module"); + tree_update_wrapper (signal_hint, n_param_values, param_values, data, tree_update_property_action); +} - g_debug ("AT-SPI: Tree update children listener"); -#endif +static gboolean +tree_update_children_action (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data, + AtkObject *accessible) +{ + const gchar *detail = NULL; + AtkObject *child; if (signal_hint->detail) detail = g_quark_to_string (signal_hint->detail); @@ -491,15 +570,19 @@ tree_update_children_listener (GSignalInvocationHint *signal_hint, register_subtree (child); update_accessible (accessible); } +} - recursion_check_unset (); - } - - g_static_rec_mutex_unlock (®istration_mutex); - - return TRUE; +static gboolean +tree_update_children_listener (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + tree_update_wrapper (signal_hint, n_param_values, param_values, data, tree_update_children_action); } +/*---------------------------------------------------------------------------*/ + static void spi_atk_register_toplevel_added (AtkObject *accessible, guint index, @@ -578,8 +661,9 @@ atk_dbus_initialize (AtkObject *root) register_subtree (root); - atk_add_global_event_listener (tree_update_listener, "Gtk:AtkObject:property-change"); + atk_add_global_event_listener (tree_update_property_listener, "Gtk:AtkObject:property-change"); atk_add_global_event_listener (tree_update_children_listener, "Gtk:AtkObject:children-changed"); + atk_add_global_event_listener (tree_update_state_listener, "Gtk:AtkObject:state-change"); g_signal_connect (root, "children-changed::add",