gchar **data;
GList *new_list;
+ spi_atk_add_client (bus_name);
evdata = (event_data *) g_malloc (sizeof (*evdata));
if (!evdata)
return;
spi_global_app_data->events = new_list;
}
+static GSList *clients = NULL;
+
static void
get_registered_event_listeners (SpiBridge *app)
{
SPI_DBUS_PATH_REGISTRY,
SPI_DBUS_INTERFACE_REGISTRY,
"GetRegisteredEvents");
- spi_global_app_data->events_initialized = TRUE;
if (!message)
return;
reply = dbus_connection_send_with_reply_and_block (app->bus, message, 5000, NULL);
dbus_message_unref (message);
if (!reply)
- return;
+ {
+ spi_global_app_data->events_initialized = TRUE;
+ return;
+ }
if (strcmp (dbus_message_get_signature (reply), "a(ss)") != 0)
{
- /* TODO: Add a warning when it's okay to add strings */
+ g_warning ("atk-bridge: GetRegisteredEvents returned message with unknown signature");
dbus_message_unref (reply);
+ spi_global_app_data->events_initialized = TRUE;
return;
}
dbus_message_iter_init (reply, &iter);
dbus_message_iter_next (&iter_array);
}
dbus_message_unref (reply);
+
+ if (!clients)
+ spi_atk_deregister_event_listeners ();
+ spi_global_app_data->events_initialized = TRUE;
}
static void
else
result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+
+ if (!g_strcmp0(interface, DBUS_INTERFACE_DBUS) &&
+ !g_strcmp0(member, "NameOwnerChanged"))
+ {
+ char *name, *old, *new;
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old,
+ DBUS_TYPE_STRING, &new,
+ DBUS_TYPE_INVALID))
+ {
+ if (*old != '\0' && *new == '\0')
+ spi_atk_remove_client (old);
+ }
+ }
+
return result;
}
exit_func ();
}
+static gchar *name_match_tmpl =
+ "type='signal', interface='org.freedesktop.DBus', member='NameOwnerChanged', arg0='%s'";
+
+void
+spi_atk_add_client (const char *bus_name)
+{
+ GSList *l;
+ gchar *match;
+
+ for (l = clients; l; l = l->next)
+ {
+ if (!g_strcmp0 (l->data, bus_name))
+ return;
+ }
+ if (!clients && spi_global_app_data->events_initialized)
+ spi_atk_register_event_listeners ();
+ clients = g_slist_append (clients, g_strdup (bus_name));
+ match = g_strdup_printf (name_match_tmpl, bus_name);
+ dbus_bus_add_match (spi_global_app_data->bus, match, NULL);
+ g_free (match);
+}
+
+void
+spi_atk_remove_client (const char *bus_name)
+{
+ GSList *l;
+
+ for (l = clients; l; l = l->next)
+ {
+ if (!g_strcmp0 (l->data, bus_name))
+ {
+ gchar *match = g_strdup_printf (name_match_tmpl, l->data);
+ dbus_bus_remove_match (spi_global_app_data->bus, match, NULL);
+ g_free (match);
+ g_free (l->data);
+ clients = g_slist_remove_link (clients, l);
+ if (!clients)
+ spi_atk_deregister_event_listeners ();
+ }
+ }
+}
+
/*END------------------------------------------------------------------------*/
g_object_unref (G_OBJECT (bo));
g_object_unref (ao);
+ if (listener_ids)
+ {
+ g_warning ("atk_bridge: spi_atk-register_event_listeners called multiple times");
+ return;
+ }
+
/* Register for focus event notifications, and register app with central registry */
listener_ids = g_array_sized_new (FALSE, TRUE, sizeof (guint), 16);
"Gtk:AtkTable:column-reordered");
add_signal_listener (generic_event_listener, "Gtk:AtkTable:column-deleted");
add_signal_listener (generic_event_listener, "Gtk:AtkTable:model-changed");
-
- /* Children signal listeners */
- atk_add_global_event_listener (children_changed_event_listener,
- "Gtk:AtkObject:children-changed");
+ add_signal_listener (children_changed_event_listener, "Gtk:AtkObject:children-changed");
#if 0
g_signal_connect (G_OBJECT (spi_global_app_data->root),
listener_ids = NULL;
if (atk_bridge_focus_tracker_id)
+ {
atk_remove_focus_tracker (atk_bridge_focus_tracker_id);
+ atk_bridge_focus_tracker_id = 0;
+ }
for (i = 0; ids && i < ids->len; i++)
{
atk_remove_global_event_listener (g_array_index (ids, guint, i));
}
+ g_array_free (ids, TRUE);
if (atk_bridge_key_event_listener_id)
+ {
atk_remove_key_event_listener (atk_bridge_key_event_listener_id);
+ atk_bridge_key_event_listener_id = 0;
+ }
}
/*---------------------------------------------------------------------------*/