From: Mike Gorse Date: Tue, 10 Nov 2009 15:35:56 +0000 (-0500) Subject: Merge branch 'master' into mgorse X-Git-Tag: AT_SPI2_ATK_2_12_0~467^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=83078472bfc64d9a6bb884a82db0a4db3dfd78b7;hp=-c Merge branch 'master' into mgorse --- 83078472bfc64d9a6bb884a82db0a4db3dfd78b7 diff --combined atk-adaptor/accessible-adaptor.c index 8c115f1,1940d9b..ce9c3c9 --- a/atk-adaptor/accessible-adaptor.c +++ b/atk-adaptor/accessible-adaptor.c @@@ -31,7 -31,7 +31,7 @@@ #include "accessible-register.h" static dbus_bool_t -impl_get_name (DBusMessageIter *iter, void *user_data) +impl_get_Name (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; @@@ -41,7 -41,7 +41,7 @@@ } static dbus_bool_t -impl_set_name (DBusMessageIter *iter, void *user_data) +impl_set_Name (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; const char *name = droute_get_v_string (iter); @@@ -53,7 -53,7 +53,7 @@@ } static dbus_bool_t -impl_get_description (DBusMessageIter *iter, void *user_data) +impl_get_Description (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; @@@ -63,7 -63,7 +63,7 @@@ } static dbus_bool_t -impl_set_description (DBusMessageIter *iter, void *user_data) +impl_set_Description (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; const char *description = droute_get_v_string (iter); @@@ -75,7 -75,7 +75,7 @@@ } static dbus_bool_t -impl_get_parent (DBusMessageIter *iter, void *user_data) +impl_get_Parent (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; @@@ -87,7 -87,7 +87,7 @@@ } static dbus_bool_t -impl_get_childCount (DBusMessageIter *iter, void *user_data) +impl_get_ChildCount (DBusMessageIter *iter, void *user_data) { AtkObject *object = (AtkObject *) user_data; @@@ -99,7 -99,7 +99,7 @@@ } static DBusMessage * -impl_getChildAtIndex (DBusConnection *bus, +impl_GetChildAtIndex (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -114,11 -114,11 +114,11 @@@ if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID)) return spi_dbus_general_error (message); child = atk_object_ref_accessible_child (object, i); - return spi_dbus_return_object (message, child, FALSE); + return spi_dbus_return_object (message, child, FALSE, FALSE); } static DBusMessage * -impl_getChildren (DBusConnection *bus, +impl_GetChildren (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -140,7 -140,7 +140,7 @@@ for (i = 0; i < count; i++) { AtkObject *child = atk_object_ref_accessible_child (object, i); - char *path = atk_dbus_object_to_path (child); + char *path = atk_dbus_object_to_path (child, FALSE); if (path) { dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, @@@ -159,7 -159,7 +159,7 @@@ oom } static DBusMessage * -impl_getIndexInParent (DBusConnection *bus, +impl_GetIndexInParent (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -224,7 -224,7 +224,7 @@@ spi_relation_type_from_atk_relation_typ } static DBusMessage * -impl_getRelationSet (DBusConnection *bus, +impl_GetRelationSet (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -241,7 -241,7 +241,7 @@@ if (!reply) return NULL; set = atk_object_ref_relation_set (object); dbus_message_iter_init_append (reply, &iter); - if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(uao)", &iter_array)) + if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ua(so))", &iter_array)) { goto oom; } @@@ -261,7 -261,7 +261,7 @@@ goto oom; } dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &type); - if (!dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "o", &iter_targets)) + if (!dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "(so)", &iter_targets)) { goto oom; } @@@ -270,13 -270,8 +270,13 @@@ AtkObject *obj = target->pdata[j]; char *path; if (!obj) continue; - path = atk_dbus_object_to_path (obj); - dbus_message_iter_append_basic (&iter_targets, DBUS_TYPE_OBJECT_PATH, &path); + path = atk_dbus_object_to_path (obj, FALSE); + if (!path) + { + g_warning ("Unknown object in relation type %d\n", type); + continue; + } + spi_dbus_append_name_and_path_inner (&iter_targets, NULL, path); } dbus_message_iter_close_container (&iter_struct, &iter_targets); dbus_message_iter_close_container (&iter_array, &iter_struct); @@@ -415,7 -410,7 +415,7 @@@ spi_accessible_role_from_atk_role (AtkR } static DBusMessage * -impl_getRole (DBusConnection *bus, DBusMessage *message, void *user_data) +impl_GetRole (DBusConnection *bus, DBusMessage *message, void *user_data) { AtkObject *object = (AtkObject *) user_data; gint role; @@@ -445,7 -440,7 +445,7 @@@ impl_get_role_str (void *datum } static DBusMessage * -impl_getRoleName (DBusConnection *bus, +impl_GetRoleName (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -470,7 -465,7 +470,7 @@@ } static DBusMessage * -impl_getLocalizedRoleName (DBusConnection *bus, +impl_GetLocalizedRoleName (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -495,34 -490,42 +495,42 @@@ } static DBusMessage * -impl_getState (DBusConnection *bus, +impl_GetState (DBusConnection *bus, DBusMessage *message, void *user_data) { AtkObject *object = (AtkObject *) user_data; - dbus_uint32_t rv[2]; - dbus_uint32_t *array = rv; - DBusMessage *reply; + + DBusMessage *reply = NULL; + DBusMessageIter iter, iter_array; + + dbus_uint32_t states [2]; + + guint count; g_return_val_if_fail (ATK_IS_OBJECT (user_data), droute_not_yet_handled_error (message)); - spi_atk_state_to_dbus_array (object, rv); + reply = dbus_message_new_method_return (message); - if (reply) + dbus_message_iter_init_append (reply, &iter); + + spi_atk_state_to_dbus_array (object, states); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_array); + for (count = 0; count < 2; count++) { - dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &array, - 2, DBUS_TYPE_INVALID); + dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_UINT32, &states[count]); } + dbus_message_iter_close_container (&iter, &iter_array); return reply; } static DBusMessage * -impl_getAttributes (DBusConnection *bus, +impl_GetAttributes (DBusConnection *bus, DBusMessage *message, void *user_data) { AtkObject *object = (AtkObject *) user_data; - DBusMessage *reply; + DBusMessage *reply = NULL; AtkAttributeSet *attributes; DBusMessageIter iter; @@@ -543,16 -546,16 +551,16 @@@ } static DBusMessage * -impl_getApplication (DBusConnection *bus, +impl_GetApplication (DBusConnection *bus, DBusMessage *message, void *user_data) { AtkObject *root = atk_get_root (); - return spi_dbus_return_object (message, root, FALSE); + return spi_dbus_return_object (message, root, FALSE, FALSE); } static DBusMessage * -impl_getInterfaces (DBusConnection *bus, +impl_GetInterfaces (DBusConnection *bus, DBusMessage *message, void *user_data) { @@@ -576,25 -579,25 +584,25 @@@ } static DRouteMethod methods[] = { - {impl_getChildAtIndex, "getChildAtIndex"}, - {impl_getChildren, "getChildren"}, - {impl_getIndexInParent, "getIndexInParent"}, - {impl_getRelationSet, "getRelationSet"}, - {impl_getRole, "getRole"}, - {impl_getRoleName, "getRoleName"}, - {impl_getLocalizedRoleName, "getLocalizedRoleName"}, - {impl_getState, "getState"}, - {impl_getAttributes, "getAttributes"}, - {impl_getApplication, "getApplication"}, - {impl_getInterfaces, "getInterfaces"}, + {impl_GetChildAtIndex, "GetChildAtIndex"}, + {impl_GetChildren, "GetChildren"}, + {impl_GetIndexInParent, "GetIndexInParent"}, + {impl_GetRelationSet, "GetRelationSet"}, + {impl_GetRole, "GetRole"}, + {impl_GetRoleName, "GetRoleName"}, + {impl_GetLocalizedRoleName, "GetLocalizedRoleName"}, + {impl_GetState, "GetState"}, + {impl_GetAttributes, "GetAttributes"}, + {impl_GetApplication, "GetApplication"}, + {impl_GetInterfaces, "GetInterfaces"}, {NULL, NULL} }; static DRouteProperty properties[] = { - {impl_get_name, impl_set_name, "name"}, - {impl_get_description, impl_set_description, "description"}, - {impl_get_parent, NULL, "parent"}, - {impl_get_childCount, NULL, "childCount"}, + {impl_get_Name, impl_set_Name, "Name"}, + {impl_get_Description, impl_set_Description, "Description"}, + {impl_get_Parent, NULL, "Parent"}, + {impl_get_ChildCount, NULL, "ChildCount"}, {NULL, NULL, NULL} }; diff --combined atk-adaptor/accessible-register.c index 3441c0c,8f774a0..7c21641 --- a/atk-adaptor/accessible-register.c +++ b/atk-adaptor/accessible-register.c @@@ -70,16 -70,13 +70,16 @@@ */ #define SPI_ATK_OBJECT_PATH_PREFIX "/org/freedesktop/atspi/accessible" - #define SPI_ATK_OBJECT_PATH_DESKTOP "/root" + #define SPI_ATK_OBJECT_PATH_DESKTOP "/desktop" #define SPI_ATK_PATH_PREFIX_LENGTH 33 #define SPI_ATK_OBJECT_REFERENCE_TEMPLATE SPI_ATK_OBJECT_PATH_PREFIX "/%d" static GHashTable *ref2ptr = NULL; /* Used for converting a D-Bus path (Reference) to the object pointer */ +static GHashTable *objects_with_subrefs = NULL; +static GHashTable *leased_refs = NULL; +static int leased_refs_count; static guint reference_counter = 0; @@@ -89,11 -86,6 +89,11 @@@ static GStaticRecMutex registration_mut static GStaticMutex recursion_check_guard = G_STATIC_MUTEX_INIT; static gboolean recursion_check = FALSE; +static int last_gc_time; + +static void deregister_sub_accessible (gpointer key, gpointer obj_data, gpointer iter); + +static void deregister_sub_hyperlink (gpointer key, gpointer obj_data, gpointer iter); static gboolean recursion_check_and_set () @@@ -129,7 -121,6 +129,7 @@@ assign_reference(void /* Reference of 0 not allowed as used as direct key in hash table */ if (reference_counter == 0) reference_counter++; + /* TODO: If we've wrapped, ensure that two objects don't have the same ref */ return reference_counter; } @@@ -137,21 -128,9 +137,21 @@@ * Returns the reference of the object, or 0 if it is not registered. */ static guint +gobject_to_ref (GObject *gobj) +{ + return GPOINTER_TO_INT(g_object_get_data (gobj, "dbus-id")); +} + +static guint object_to_ref (AtkObject *accessible) { - return GPOINTER_TO_INT(g_object_get_data (G_OBJECT (accessible), "dbus-id")); + return gobject_to_ref (G_OBJECT (accessible)); +} + +static guint +hyperlink_to_ref (AtkHyperlink *link) +{ + return gobject_to_ref (G_OBJECT (link)); } /* @@@ -172,136 -151,33 +172,136 @@@ atk_dbus_ref_to_path (guint ref * it is no longer exposed over D-Bus. */ static void -deregister_accessible (gpointer data, GObject *accessible) +deregister_object (gpointer data, GObject *gobj) { guint ref; - g_return_if_fail (ATK_IS_OBJECT (accessible)); + GHashTable *subrefs_atk; + GHashTable *subrefs_hyperlink; + g_return_if_fail (ATK_IS_OBJECT (gobj) || ATK_IS_HYPERLINK (gobj)); + + subrefs_atk = (GHashTable *) g_object_get_data (gobj, "dbus-subrefs-atk"); + subrefs_hyperlink = (GHashTable *) g_object_get_data (gobj, "dbus-subrefs-hyperlink"); + + if (subrefs_atk) + { + g_hash_table_foreach (subrefs_atk, deregister_sub_accessible, data); + g_hash_table_unref (subrefs_atk); + } + + if (subrefs_hyperlink) + { + g_hash_table_foreach (subrefs_hyperlink, deregister_sub_hyperlink, data); + g_hash_table_unref (subrefs_hyperlink); + } + + if (subrefs_atk || subrefs_hyperlink) + g_hash_table_remove (objects_with_subrefs, gobj); + + if (ATK_IS_OBJECT (gobj)) + { + ref = object_to_ref (ATK_OBJECT (gobj)); + if (ref != 0) + { + spi_emit_cache_removal (ref, atk_adaptor_app_data->bus); + g_hash_table_remove(ref2ptr, GINT_TO_POINTER(ref)); + } + } + } - ref = object_to_ref (ATK_OBJECT(accessible)); +static void +deregister_sub_accessible (gpointer key, gpointer obj_data, gpointer iter) +{ + GObject *obj = G_OBJECT (obj_data); + deregister_object (NULL, obj); + g_hash_table_remove (leased_refs, obj); + g_object_unref (obj); +} + +static void +deregister_sub_hyperlink (gpointer key, gpointer obj_data, gpointer iter) +{ + guint ref; + GObject *ghyperlink = G_OBJECT (obj_data); + + g_return_if_fail (ATK_IS_HYPERLINK (ghyperlink)); + + ref = gobject_to_ref (ghyperlink); if (ref != 0) { - spi_emit_cache_removal (ref, atk_adaptor_app_data->bus); g_hash_table_remove(ref2ptr, GINT_TO_POINTER(ref)); } + g_object_unref (ghyperlink); +} + +static void +register_gobject (GObject *gobj, GObject *container) +{ + guint ref; + g_return_if_fail (G_IS_OBJECT(gobj)); + + ref = assign_reference(); + + g_hash_table_insert (ref2ptr, GINT_TO_POINTER(ref), gobj); + g_object_set_data (G_OBJECT(gobj), "dbus-id", GINT_TO_POINTER(ref)); + g_object_weak_ref(G_OBJECT(gobj), deregister_object, NULL); + + if (container) + { + GHashTable *subrefs = (GHashTable *) g_object_get_data (G_OBJECT (container), "dbus-subrefs-atk"); + if (!subrefs) + { + subrefs = g_hash_table_new(g_direct_hash, g_direct_equal); + g_object_set_data (G_OBJECT (container), "dbus-subrefs-atk", subrefs); + } + g_hash_table_insert (subrefs, GINT_TO_POINTER(ref), gobj); + g_hash_table_insert (objects_with_subrefs, gobj, subrefs); + } + + if (ATK_IS_HYPERLINK (gobj)) + g_object_ref (gobj); + else if (ATK_IS_OBJECT (gobj)) + { + AtkObject *accessible = ATK_OBJECT (gobj); + AtkStateSet *state = atk_object_ref_state_set (accessible); + if (atk_state_set_contains_state (state, ATK_STATE_TRANSIENT)) + { + g_object_ref (gobj); + } + g_object_unref (state); + } } /* * Called to register an AtkObject with AT-SPI and expose it over D-Bus. */ static void -register_accessible (AtkObject *accessible) +register_accessible (AtkObject *accessible, AtkObject *container) { - guint ref; g_return_if_fail (ATK_IS_OBJECT(accessible)); + register_gobject (G_OBJECT (accessible), G_OBJECT (container)); +} + +static void +register_hyperlink (AtkHyperlink *hyperlink, AtkObject *container) +{ + guint ref; + g_return_if_fail (ATK_IS_HYPERLINK (hyperlink)); + g_return_if_fail (container); + ref = assign_reference(); - g_hash_table_insert (ref2ptr, GINT_TO_POINTER(ref), accessible); - g_object_set_data (G_OBJECT(accessible), "dbus-id", GINT_TO_POINTER(ref)); - g_object_weak_ref(G_OBJECT(accessible), deregister_accessible, NULL); + g_hash_table_insert (ref2ptr, GINT_TO_POINTER(ref), hyperlink); + g_object_set_data (G_OBJECT(hyperlink), "dbus-id", GINT_TO_POINTER(ref)); + g_object_ref (G_OBJECT (hyperlink)); + + GHashTable *subrefs = (GHashTable *) g_object_get_data (G_OBJECT (container), "dbus-subrefs-hyperlink"); + if (!subrefs) + { + subrefs = g_hash_table_new(g_direct_hash, g_direct_equal); + g_object_set_data (G_OBJECT (container), "dbus-subrefs-hyperlink", GINT_TO_POINTER(ref)); + } + g_hash_table_insert (subrefs, GINT_TO_POINTER(ref), hyperlink); } /*---------------------------------------------------------------------------*/ @@@ -334,11 -210,8 +334,11 @@@ non_owned_accessible (AtkObject *access /*---------------------------------------------------------------------------*/ +/* TRUE if we should not keep this object / tell the AT about it + * Currently true if TRANSIENT and not SHOWING + */ static gboolean -has_manages_descendants (AtkObject *accessible) +object_is_moot (AtkObject *accessible) { AtkStateSet *state; gboolean result = FALSE; @@@ -348,9 -221,11 +348,9 @@@ * by modifying the tree alot. */ state = atk_object_ref_state_set (accessible); - if (atk_state_set_contains_state (state, ATK_STATE_MANAGES_DESCENDANTS)) + if ( atk_state_set_contains_state (state, ATK_STATE_TRANSIENT) && + !atk_state_set_contains_state (state, ATK_STATE_SHOWING)) { -#ifdef SPI_ATK_DEBUG - g_warning ("AT-SPI: Object with 'Manages descendants' states not currently handled by AT-SPI"); -#endif result = TRUE; } g_object_unref (state); @@@ -374,7 -249,10 +374,7 @@@ append_children (AtkObject *accessible #ifdef SPI_ATK_DEBUG non_owned_accessible (current); #endif - if (!has_manages_descendants (current)) - g_queue_push_tail (traversal, current); - else - g_object_unref (G_OBJECT (current)); + g_queue_push_tail (traversal, current); } } } @@@ -409,7 -287,7 +409,7 @@@ register_subtree (AtkObject *accessible g_queue_push_tail (emit_update, current); if (!object_to_ref (current)) { - register_accessible (current); + register_accessible (current, NULL); #ifdef SPI_ATK_DEBUG g_debug ("REG - %s - %d - %s", atk_object_get_name (current), atk_object_get_role (current), @@@ -460,8 -338,8 +460,8 @@@ atk_dbus_foreach_registered(GHFunc func /* * Used to lookup an AtkObject from its D-Bus path. */ -AtkObject * -atk_dbus_path_to_object (const char *path) +GObject * +atk_dbus_path_to_gobject (const char *path) { guint index; void *data; @@@ -474,7 -352,7 +474,7 @@@ path += SPI_ATK_PATH_PREFIX_LENGTH; /* Skip over the prefix */ if (!g_strcmp0 (SPI_ATK_OBJECT_PATH_DESKTOP, path)) - return atk_get_root(); + return G_OBJECT (atk_get_root()); if (path[0] != '/') return NULL; @@@ -482,21 -360,11 +482,21 @@@ index = atoi (path); data = g_hash_table_lookup (ref2ptr, GINT_TO_POINTER(index)); if (data) - return ATK_OBJECT (data); + { + GObject *gobj = G_OBJECT (data); + g_object_set_data (gobj, "last-ref-time", (gpointer) time (NULL)); + return gobj; + } else return NULL; } +AtkObject * +atk_dbus_path_to_object (const char *path) +{ + return ATK_OBJECT (atk_dbus_path_to_gobject (path)); +} + /* * TODO WARNING HACK This function is dangerous. * It should only be called before sending an event on an @@@ -557,49 -425,12 +557,49 @@@ atk_dbus_object_attempt_registration (A /* * Used to lookup a D-Bus path from the AtkObject. */ +static gchar * +atk_dbus_gobject_to_path_internal (GObject *gobj, gboolean do_register, GObject *container) +{ + guint ref; + + ref = gobject_to_ref (gobj); + if (!ref && do_register) + { + register_gobject (gobj, container); + ref = gobject_to_ref (gobj); + } + + if (!ref) + return NULL; + else + return atk_dbus_ref_to_path (ref); +} + +gchar * +atk_dbus_object_to_path (AtkObject *accessible, gboolean do_register) +{ + AtkObject *container = (accessible && do_register? atk_object_get_parent (accessible): NULL); + return atk_dbus_gobject_to_path_internal (G_OBJECT (accessible), do_register, G_OBJECT (container)); +} + +gchar * +atk_dbus_sub_object_to_path (GObject *gobj, GObject *container) +{ + return atk_dbus_gobject_to_path_internal (gobj, TRUE, container); +} + gchar * -atk_dbus_object_to_path (AtkObject *accessible) +atk_dbus_hyperlink_to_path (AtkHyperlink *hyperlink, AtkObject *container) { guint ref; - ref = object_to_ref (accessible); + ref = gobject_to_ref (G_OBJECT (hyperlink)); + if (!ref && container) + { + register_hyperlink (hyperlink, container); + ref = hyperlink_to_ref (hyperlink); + } + if (!ref) return NULL; else @@@ -666,68 -497,12 +666,68 @@@ tree_update_wrapper (GSignalInvocationH } static gboolean +maybe_expire_lease (gpointer key, gpointer obj_data, gpointer iter) +{ + time_t secs = time (NULL) - (time_t)obj_data; + + if (secs < 30) + return FALSE; + deregister_sub_accessible (key, obj_data, iter); + return TRUE; +} + +static void +expire_old_leases_in (gpointer key, gpointer obj_data, gpointer iter) +{ + g_hash_table_foreach_remove ((GHashTable *)obj_data, maybe_expire_lease, NULL); +} + +static void +expire_old_leases () +{ + g_hash_table_foreach (objects_with_subrefs, expire_old_leases_in, NULL); +} + +static gboolean tree_update_state_action (GSignalInvocationHint *signal_hint, guint n_param_values, const GValue *param_values, gpointer data, AtkObject *accessible) { + const gchar *name; + gboolean state; + + if (n_param_values < 3) + { + g_warning ("at-spi: Not enough params in state-changed signal"); + return TRUE; + } + + name = g_value_get_string (param_values + 1); + state = g_value_get_boolean (param_values + 2); + if (!strcmp (name, "visible")) + { + AtkStateSet *set = atk_object_ref_state_set (accessible); + if (atk_state_set_contains_state (set, ATK_STATE_TRANSIENT)) + { + if (state == 0) + { + g_hash_table_insert (leased_refs, accessible, (gpointer) time (NULL)); + leased_refs_count++; + /* todo: Set to a high number: 5 for dbg. */ + if (leased_refs_count > 5) + expire_old_leases (); + } + else + { + g_hash_table_remove (leased_refs, accessible); + leased_refs_count--; + } + } + g_object_unref (set); + } + update_accessible (accessible); return TRUE; } @@@ -756,8 -531,7 +756,8 @@@ tree_update_property_action (GSignalInv pname = values[0].property_name; if (strcmp (pname, "accessible-name") == 0 || strcmp (pname, "accessible-description") == 0 || - strcmp (pname, "accessible-parent") == 0) + strcmp (pname, "accessible-parent") == 0 || + strcmp (pname, "accessible-role") == 0) { update_accessible (accessible); } @@@ -785,6 -559,7 +785,6 @@@ tree_update_children_action (GSignalInv const gchar *detail = NULL; AtkObject *child; - if (has_manages_descendants (accessible)) return TRUE; if (signal_hint->detail) detail = g_quark_to_string (signal_hint->detail); @@@ -888,12 -663,6 +888,12 @@@ atk_dbus_initialize (AtkObject *root if (!ref2ptr) ref2ptr = g_hash_table_new(g_direct_hash, g_direct_equal); + if (!objects_with_subrefs) + objects_with_subrefs = g_hash_table_new(g_direct_hash, g_direct_equal); + + if (!leased_refs) + leased_refs = g_hash_table_new(g_direct_hash, g_direct_equal); + #ifdef SPI_ATK_DEBUG if (g_thread_supported ()) g_message ("AT-SPI: Threads enabled");