{
SpiDesktopApplication *app = desktop->applications->data;
g_assert (app != NULL);
- spi_desktop_remove_application (desktop, app->path);
+ spi_desktop_remove_application (desktop, app->bus_name);
}
G_OBJECT_CLASS (parent_class)->dispose (object);
DBusError error;
dbus_int32_t index;
SpiDesktopApplication *app;
- const char *path;
+ const char *bus_name;
DBusMessage *reply;
dbus_error_init (&error);
return spi_dbus_general_error (message);
}
app = g_list_nth_data (desktop->applications, index);
- path = (app? app->path: SPI_DBUS_PATH_NULL);
+ bus_name = (app? app->bus_name: "");
reply = dbus_message_new_method_return (message);
if (reply)
{
- dbus_message_append_args (reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
+ dbus_message_append_args (reply, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID);
}
return reply;
gint count;
gint i;
SpiDesktopApplication *app;
- const char *path;
+ const char *bus_name;
DBusMessage *reply;
DBusMessageIter iter, iter_array;
for (i = 0; i < count; i++)
{
app = g_list_nth_data (desktop->applications, i);
- path = (app? app->path: SPI_DBUS_PATH_NULL);
- dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &path);
+ bus_name = (app? app->bus_name: "");
+ dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &bus_name);
}
if (!dbus_message_iter_close_container (&iter, &iter_array))
{
g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
if (!exiting)
- spi_desktop_remove_application (app->desktop, app->path);
+ spi_desktop_remove_application (app->desktop, app->bus_name);
}
void
g_return_if_fail (SPI_IS_DESKTOP (desktop));
- spi_desktop_remove_application (desktop, application);
-
app = g_new (SpiDesktopApplication, 1);
app->desktop = desktop;
- app->path = application;
+ app->bus_name = application;
desktop->applications = g_list_append (desktop->applications, app);
void
spi_desktop_remove_application (SpiDesktop *desktop,
- const char *path)
+ const char *bus_name)
{
guint idx;
GList *l;
- g_return_if_fail (path != NULL);
+ g_return_if_fail ( bus_name != NULL);
g_return_if_fail (SPI_IS_DESKTOP (desktop));
idx = 0;
{
SpiDesktopApplication *app = (SpiDesktopApplication *) l->data;
- if (!strcmp(app->path, path))
+ if (!strcmp(app->bus_name, bus_name))
{
break;
}
idx++;
}
- if (l)
- {
- SpiDesktopApplication *app = (SpiDesktopApplication *) l->data;
+ if (!l) return;
- desktop->applications = g_list_delete_link (desktop->applications, l);
+ g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);
- // TODO: unlisten for broken app, if appropriate
- g_free (app);
-
- g_signal_emit (G_OBJECT (desktop), spi_desktop_signals[APPLICATION_REMOVED], 0, idx);
- }
+ SpiDesktopApplication *app = (SpiDesktopApplication *) l->data;
+
+ desktop->applications = g_list_delete_link (desktop->applications, l);
+
+ g_free (app);
}
static DRouteMethod methods[] =
GType spi_desktop_get_type (void);
SpiDesktop *spi_desktop_new (void);
void spi_desktop_add_application (SpiDesktop *desktop,
- const char *app_path);
+ const char *bus_name);
void spi_desktop_remove_application (SpiDesktop *desktop,
- const char *app_path);
+ const char *bus_name);
typedef struct {
SpiDesktop *desktop;
- const char *path;
+ const char *bus_name;
} SpiDesktopApplication;
G_END_DECLS
} DEControllerGrabMask;
typedef struct {
- char *app_path;
+ char *bus_name;
char *path;
SpiDeviceTypeCategory type;
gulong types;
}
static DEControllerKeyListener *
-spi_dec_key_listener_new (const char *app_path,
+spi_dec_key_listener_new (const char *bus_name,
const char *path,
GSList *keys,
const Accessibility_ControllerEventMask mask,
const Accessibility_EventListenerMode *mode)
{
DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
- key_listener->listener.app_path = g_strdup(app_path);
+ key_listener->listener.bus_name = g_strdup(bus_name);
key_listener->listener.path = g_strdup(path);
key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
key_listener->keys = keys;
}
static DEControllerListener *
-spi_dec_listener_new (const char *app_path,
+spi_dec_listener_new (const char *bus_name,
const char *path,
dbus_uint32_t types)
{
DEControllerListener *listener = g_new0 (DEControllerListener, 1);
- listener->app_path = g_strdup(app_path);
+ listener->bus_name = g_strdup(bus_name);
listener->path = g_strdup(path);
listener->type = SPI_DEVICE_TYPE_MOUSE;
listener->types = types;
spi_listener_clone (DEControllerListener *listener)
{
DEControllerListener *clone = g_new0 (DEControllerListener, 1);
- clone->app_path = g_strdup (listener->app_path);
+ clone->bus_name = g_strdup (listener->bus_name);
clone->path = g_strdup (listener->path);
clone->type = listener->type;
clone->types = listener->types;
spi_key_listener_clone (DEControllerKeyListener *key_listener)
{
DEControllerKeyListener *clone = g_new0 (DEControllerKeyListener, 1);
- clone->listener.app_path = g_strdup (key_listener->listener.app_path);
+ clone->listener.bus_name = g_strdup (key_listener->listener.bus_name);
clone->listener.path = g_strdup (key_listener->listener.path);
clone->listener.type = SPI_DEVICE_TYPE_KBD;
clone->keys = keylist_clone (key_listener->keys);
spi_listener_clone_free (DEControllerListener *clone)
{
g_free (clone->path);
- g_free (clone->app_path);
+ g_free (clone->bus_name);
g_free (clone);
}
static void
spi_dec_listener_free (DEControllerListener *listener)
{
- g_free (listener->app_path);
+ g_free (listener->bus_name);
g_free (listener->path);
if (listener->type == SPI_DEVICE_TYPE_KBD)
spi_key_listener_data_free ((DEControllerKeyListener *) listener);
controller->key_listeners = g_list_prepend (controller->key_listeners,
key_listener);
+ spi_dbus_add_disconnect_match (controller->registry->droute.bus, key_listener->listener.bus_name);
if (key_listener->mode->global)
{
return spi_controller_register_global_keygrabs (controller, key_listener);
break;
case SPI_DEVICE_TYPE_MOUSE:
controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
+ spi_dbus_add_disconnect_match (controller->registry->droute.bus, listener->bus_name);
break;
default:
DBG (1, g_warning ("listener registration for unknown device type.\n"));
static gboolean Accessibility_DeviceEventListener_notifyEvent(SpiRegistry *registry, DEControllerListener *listener, const Accessibility_DeviceEvent *key_event)
{
- DBusMessage *message = dbus_message_new_method_call(listener->app_path, listener->path, "org.freedesktop.atspi.Registry", "notifyEvent");
+ DBusMessage *message = dbus_message_new_method_call(listener->bus_name, listener->path, "org.freedesktop.atspi.Registry", "notifyEvent");
DBusError error;
dbus_bool_t consumed = FALSE;
DEControllerListener *listener = (*list)->data;
RemoveListenerClosure *ctx = user_data;
- if (!strcmp(ctx->listener->app_path, listener->app_path) &&
+ if (!strcmp(ctx->listener->bus_name, listener->bus_name) &&
!strcmp(ctx->listener->path, listener->path))
{
spi_re_entrant_list_delete_link (list);
+ spi_dbus_remove_disconnect_match (ctx->bus, listener->bus_name);
spi_dec_listener_free (listener);
}
DEControllerKeyListener *key_listener = (*list)->data;
RemoveListenerClosure *ctx = user_data;
- if (!strcmp(ctx->listener->app_path, key_listener->listener.app_path) &&
+ if (!strcmp(ctx->listener->bus_name, key_listener->listener.bus_name) &&
!strcmp(ctx->listener->path, key_listener->listener.path))
{
/* TODO: FIXME aggregate keys in case the listener is registered twice */
}
+void
+spi_remove_device_listeners (SpiDEController *controller, const char *bus_name)
+{
+ GList *l, *tmp;
+
+ for (l = controller->mouse_listeners; l; l = tmp)
+ {
+ DEControllerListener *listener = l->data;
+ tmp = l->next;
+ if (!strcmp (listener->bus_name, bus_name))
+ {
+printf("Removing mouse listener %s %s\n", listener->bus_name, listener->path);
+ spi_controller_deregister_device_listener (controller, listener);
+ }
+ }
+ for (l = controller->key_listeners; l; l = tmp)
+ {
+ DEControllerKeyListener *key_listener = l->data;
+ tmp = l->next;
+ if (!strcmp (key_listener->listener.bus_name, bus_name))
+ {
+printf("Removing key listener: %s %s\n", key_listener->listener.bus_name, key_listener->listener.path);
+ spi_deregister_controller_key_listener (controller, key_listener);
+ }
+ }
+}
+
/*
* DBus Accessibility::DEController::deregisterKeystrokeListener
* method implementation
GType spi_device_event_controller_get_type (void);
SpiDEController *spi_device_event_controller_new (SpiRegistry *registry);
+void spi_remove_device_listeners (SpiDEController *controller, const char *bus_name);
+
G_END_DECLS
#endif /* DEVICEEVENTCONTROLLER_H_ */
SpiRegistry *registry = SPI_REGISTRY (data);
const SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index);
- emit(registry, "ApplicationAdd", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->path, DBUS_TYPE_INVALID);
+ emit(registry, "ApplicationAdd", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID);
}
guint index, gpointer data)
{
SpiRegistry *registry = SPI_REGISTRY (data);
- const char *name = g_list_nth_data(desktop->applications, index);
+ SpiDesktopApplication *app = g_list_nth_data(desktop->applications, index);
- emit(registry, "ApplicationRemove", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
+ spi_dbus_remove_disconnect_match (registry->droute.bus, app->bus_name);
+ emit(registry, "ApplicationRemove", DBUS_TYPE_UINT32, &index, DBUS_TYPE_STRING, &app->bus_name, DBUS_TYPE_INVALID);
}
#endif
spi_desktop_add_application (registry->desktop, application);
+ spi_dbus_add_disconnect_match (registry->droute.bus, application);
+
/*
* TODO: change the implementation below to a WM-aware one;
* e.g. don't add all apps to the SpiDesktop
NULL, NULL, NULL, NULL
};
+DBusHandlerResult
+disconnect_watch (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ SpiRegistry *registry = SPI_REGISTRY (user_data);
+ const char *name, *old, *new;
+
+ if (!dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID))
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ if (*old != '\0' && *new == '\0')
+ {
+ spi_desktop_remove_application (registry->desktop, old);
+ spi_remove_device_listeners (registry->de_controller, old);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
static void
spi_registry_init (SpiRegistry *registry)
{
registry);
registry->de_controller = spi_device_event_controller_new (registry);
+
+ dbus_connection_add_filter (registry->droute.bus, disconnect_watch, registry, NULL);
}
SpiRegistry *