diff options
Diffstat (limited to 'atspi/atspi-accessible.c')
-rw-r--r-- | atspi/atspi-accessible.c | 103 |
1 files changed, 60 insertions, 43 deletions
diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c index 9c21f446..a5d2928d 100644 --- a/atspi/atspi-accessible.c +++ b/atspi/atspi-accessible.c @@ -104,6 +104,8 @@ atspi_accessible_init (AtspiAccessible *accessible) accessible_count++; printf("at-spi: init: %d objects\n", accessible_count); #endif + + accessible->children = g_ptr_array_new_with_free_func (g_object_unref); } static void @@ -112,6 +114,7 @@ atspi_accessible_dispose (GObject *object) AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object); AtspiEvent e; AtspiAccessible *parent; + gint i; /* TODO: Only fire if object not already marked defunct */ memset (&e, 0, sizeof (e)); @@ -128,23 +131,30 @@ atspi_accessible_dispose (GObject *object) } parent = accessible->accessible_parent; - if (parent && parent->children) + if (parent) + { + accessible->accessible_parent = NULL; + if (parent->children) + g_ptr_array_remove (parent->children, accessible); + g_object_unref (parent); + } + + while (accessible->children && accessible->children->len > 0) { - GList*ls = g_list_find (parent->children, accessible); - if(ls) + int index = accessible->children->len - 1; + AtspiAccessible *child = g_ptr_array_index (accessible->children, index); + if (child && child->accessible_parent == accessible) { - gboolean replace = (ls == parent->children); - ls = g_list_remove (ls, accessible); - if (replace) - parent->children = ls; - g_object_unref (object); + child->accessible_parent = NULL; + g_object_unref (accessible); } + g_ptr_array_remove_index (accessible->children, index); } - if (parent) + if (accessible->children) { - g_object_unref (parent); - accessible->accessible_parent = NULL; + g_ptr_array_free (accessible->children, TRUE); + accessible->children = NULL; } G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object); @@ -165,8 +175,7 @@ atspi_accessible_finalize (GObject *object) g_print ("at-spi: finalize: %d objects\n", accessible_count); #endif - G_OBJECT_CLASS (atspi_accessible_parent_class) - ->finalize (object); + G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object); } static void @@ -419,7 +428,10 @@ atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error) return ret; } - return g_list_length (obj->children); + if (!obj->children) + return 0; /* assume it's disposed */ + + return obj->children->len; } /** @@ -438,22 +450,33 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj, GError **error) { AtspiAccessible *child; + DBusMessage *reply; g_return_val_if_fail (obj != NULL, NULL); - if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) + if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) { - DBusMessage *reply; - reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, - "GetChildAtIndex", error, "i", - child_index); - return _atspi_dbus_return_accessible_from_message (reply); + if (!obj->children) + return NULL; /* assume disposed */ + + child = g_ptr_array_index (obj->children, child_index); + if (child) + return g_object_ref (child); } - child = g_list_nth_data (obj->children, child_index); + reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, + "GetChildAtIndex", error, "i", child_index); + child = _atspi_dbus_return_accessible_from_message (reply); + if (!child) return NULL; - return g_object_ref (child); + if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) + { + if (child_index >= obj->children->len) + g_ptr_array_set_size (obj->children, child_index + 1); + g_ptr_array_index (obj->children, child_index) = g_object_ref (child); + } + return child; } /** @@ -469,28 +492,22 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj, gint atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error) { - GList *l; gint i = 0; + dbus_uint32_t ret = -1; g_return_val_if_fail (obj != NULL, -1); if (!obj->accessible_parent) return -1; - if (!_atspi_accessible_test_cache (obj->accessible_parent, + if (_atspi_accessible_test_cache (obj->accessible_parent, ATSPI_CACHE_CHILDREN)) { - dbus_uint32_t ret = -1; - _atspi_dbus_call (obj, atspi_interface_accessible, - "GetIndexInParent", NULL, "=>u", &ret); - return ret; + for (i = 0; i < obj->accessible_parent->children->len; i++) + if (g_ptr_array_index (obj->accessible_parent->children, i) == obj) + return i; } - l = obj->accessible_parent->children; - while (l) - { - if (l->data == obj) return i; - l = g_list_next (l); - i++; - } - return -1; + _atspi_dbus_call (obj, atspi_interface_accessible, + "GetIndexInParent", NULL, "=>u", &ret); + return ret; } typedef struct @@ -1442,21 +1459,21 @@ atspi_accessible_set_cache_mask (AtspiAccessible *accessible, AtspiCache mask) /** * atspi_accessible_clear_cache: - * @accessible: The #AtspiAccessible whose cache to clear. + * @obj: The #AtspiAccessible whose cache to clear. * * Clears the cached information for the given accessible and all of its * descendants. */ void -atspi_accessible_clear_cache (AtspiAccessible *accessible) +atspi_accessible_clear_cache (AtspiAccessible *obj) { - GList *l; + int i; - if (accessible) + if (obj) { - accessible->cached_properties = ATSPI_CACHE_NONE; - for (l = accessible->children; l; l = l->next) - atspi_accessible_clear_cache (l->data); + obj->cached_properties = ATSPI_CACHE_NONE; + for (i = 0; i < obj->children->len; i++) + atspi_accessible_clear_cache (g_ptr_array_index (obj->children, i)); } } |