From afe5c55c213844a609041bb15be62c3f751b1863 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Fri, 20 Sep 2013 12:16:31 -0500 Subject: [PATCH] Send interfaces, and sometimes extents, along with events When possible, in order to reduce the need to make synchronous D-Bus calls, we should send the data that an AT-SPI client will need to process an event. This should really be configurable by the client, but, for now, let's send the data that gnome-shell's focus handler requires, in order to prevent a deadlock. https://bugzilla.gnome.org/show_bug.cgi?id=708387 --- atk-adaptor/event.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c index d8a74cc..2322197 100644 --- a/atk-adaptor/event.c +++ b/atk-adaptor/event.c @@ -420,6 +420,14 @@ adapt_minor_for_dbus (const char *source) return ret; } +static void +open_variant (DBusMessageIter *iter, const char *name, const char *type, + DBusMessageIter *out) +{ + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &name); + dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, type, out); +} + /* * Emits an AT-SPI event. * AT-SPI events names are split into three parts: @@ -447,7 +455,7 @@ emit_event (AtkObject *obj, gchar *cname; DBusMessage *sig; - DBusMessageIter iter; + DBusMessageIter iter, iter_dict, iter_dict_entry, iter_variant, iter_array; if (!klass) klass = ""; if (!major) major = ""; @@ -476,7 +484,48 @@ emit_event (AtkObject *obj, dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2); append_variant (&iter, type, val); - spi_object_append_reference (&iter, spi_global_app_data->root); + + /* append extra properties */ + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &iter_dict); + /* append interfaces */ + dbus_message_iter_open_container (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, + &iter_dict_entry); + open_variant (&iter_dict_entry, "interfaces", "as", &iter_variant); + dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_ARRAY, "s", &iter_array); + spi_object_append_interfaces (&iter_array, obj); + dbus_message_iter_close_container (&iter_variant, &iter_array); + dbus_message_iter_close_container (&iter_dict_entry, &iter_variant); + dbus_message_iter_close_container (&iter_dict, &iter_dict_entry); + + /* Hack -- sent extents of focused items, for gnome-shell */ + /* TODO: Allow ATs to indicate what data they need. */ + if (!strcmp (major, "state-changed") && !strcmp (minor, "focused") && + ATK_IS_COMPONENT (obj)) + { + AtkComponent *component = ATK_COMPONENT (obj); + DBusMessageIter iter_struct; + gint x = -1, y = -1, width = -1, height = -1; + dbus_int32_t d_x, d_y, d_width, d_height; + atk_component_get_extents (component, &x, &y, &width, &height, + ATK_XY_SCREEN); + d_x = x; + d_y = y; + d_width = width; + d_height = height; + dbus_message_iter_open_container (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, + &iter_dict_entry); + open_variant (&iter_dict_entry, "extents", "(iiii)", &iter_variant); + dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL, + &iter_struct); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_x); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_y); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_width); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_height); + dbus_message_iter_close_container (&iter_variant, &iter_struct); + dbus_message_iter_close_container (&iter_dict_entry, &iter_variant); + dbus_message_iter_close_container (&iter_dict, &iter_dict_entry); + } + dbus_message_iter_close_container (&iter, &iter_dict); dbus_connection_send(bus, sig, NULL); dbus_message_unref(sig); -- 1.8.1.4