From 58e610ff0c08c44ab53e54e7849232cb56264881 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 14 Oct 2015 22:55:23 +0200 Subject: [PATCH] systray: use the external watcher daemon --- src/modules/Makefile_systray.mk | 3 +- src/modules/systray/e_mod_main.c | 10 + .../systray/e_mod_notifier_host_dbus.c | 43 +-- src/modules/systray/e_mod_notifier_watcher.c | 247 ------------------ 4 files changed, 14 insertions(+), 289 deletions(-) delete mode 100644 src/modules/systray/e_mod_notifier_watcher.c diff --git a/src/modules/Makefile_systray.mk b/src/modules/Makefile_systray.mk index 7a6a4364c..e6dab2c6f 100644 --- a/src/modules/Makefile_systray.mk +++ b/src/modules/Makefile_systray.mk @@ -21,8 +21,7 @@ src_modules_systray_module_la_SOURCES = src/modules/systray/e_mod_main.h \ src/modules/systray/e_mod_main.c \ src/modules/systray/e_mod_notifier_host_private.h \ src/modules/systray/e_mod_notifier_host.c \ - src/modules/systray/e_mod_notifier_host_dbus.c \ - src/modules/systray/e_mod_notifier_watcher.c + src/modules/systray/e_mod_notifier_host_dbus.c PHONIES += systray install-systray systray: $(systraypkg_LTLIBRARIES) $(systray_DATA) diff --git a/src/modules/systray/e_mod_main.c b/src/modules/systray/e_mod_main.c index dfe230e38..74d47cb4e 100644 --- a/src/modules/systray/e_mod_main.c +++ b/src/modules/systray/e_mod_main.c @@ -412,6 +412,16 @@ e_modapi_init(E_Module *m) systray_notifier_host_init(); + //start the watcher service + char buf[PATH_MAX]; + + snprintf(buf, sizeof(buf), "%s/%s/watcher", e_module_dir_get(m), MODULE_ARCH); + + if (!ecore_exe_run(buf, NULL)) + { + printf("Starting watcher failed\n"); + } + return ctx; } diff --git a/src/modules/systray/e_mod_notifier_host_dbus.c b/src/modules/systray/e_mod_notifier_host_dbus.c index 75867dc3f..718e41940 100644 --- a/src/modules/systray/e_mod_notifier_host_dbus.c +++ b/src/modules/systray/e_mod_notifier_host_dbus.c @@ -477,36 +477,13 @@ item_unregistered_local_cb(void *data, const char *bus, const char *path) eina_stringshare_del(p); } -static void -name_request_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) +void +systray_notifier_dbus_init(Context_Notifier_Host *ctx) { - const char *error, *error_msg; - unsigned flag; Eldbus_Object *obj; - Context_Notifier_Host *ctx = data; - ctx->pending = eina_list_remove(ctx->pending, pending); - if (eldbus_message_error_get(msg, &error, &error_msg)) - { - ERR("%s %s", error, error_msg); - goto end; - } + eldbus_init(); - if (!eldbus_message_arguments_get(msg, "u", &flag)) - { - ERR("Error reading message."); - goto end; - } - - if (flag == ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER) - { - systray_notifier_dbus_watcher_start(ctx->conn, - item_registered_local_cb, - item_unregistered_local_cb, ctx); - return; - } -end: - WRN("Bus name: %s already in use, getting data via dbus.\n", WATCHER_BUS); obj = eldbus_object_get(ctx->conn, WATCHER_BUS, WATCHER_PATH); ctx->watcher = eldbus_proxy_get(obj, WATCHER_IFACE); eldbus_proxy_call(ctx->watcher, "RegisterStatusNotifierHost", NULL, NULL, -1, "s", @@ -519,20 +496,6 @@ end: notifier_item_del_cb, ctx); } -void -systray_notifier_dbus_init(Context_Notifier_Host *ctx) -{ - Eldbus_Pending *p; - - eldbus_init(); - ctx->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION); - if (!ctx->conn) return; - p = eldbus_name_request(ctx->conn, - WATCHER_BUS, ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING, - name_request_cb, ctx); - if (p) ctx->pending = eina_list_append(ctx->pending, p); -} - void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx) { Eina_Inlist *safe_list; diff --git a/src/modules/systray/e_mod_notifier_watcher.c b/src/modules/systray/e_mod_notifier_watcher.c deleted file mode 100644 index 8e8308cc6..000000000 --- a/src/modules/systray/e_mod_notifier_watcher.c +++ /dev/null @@ -1,247 +0,0 @@ -#include "e_mod_notifier_host_private.h" - -#define PATH "/StatusNotifierWatcher" -#define IFACE "org.kde.StatusNotifierWatcher" -#define PROTOCOL_VERSION 1 - -#define ERROR_HOST_ALREADY_REGISTERED "org.kde.StatusNotifierWatcher.Host.AlreadyRegistered" -#define ERROR_ITEM_ALREADY_REGISTERED "org.kde.StatusNotifierWatcher.Item.AlreadyRegistered" - -static Eldbus_Connection *conn = NULL; -static Eldbus_Service_Interface *iface = NULL; -static Eina_List *items; -static const char *host_service = NULL; -static E_Notifier_Watcher_Item_Registered_Cb registered_cb; -static E_Notifier_Watcher_Item_Unregistered_Cb unregistered_cb; -static void *user_data; - -enum -{ - ITEM_REGISTERED = 0, - ITEM_UNREGISTERED, - HOST_REGISTERED, - HOST_UNREGISTERED -}; - -static void -item_name_monitor_cb(void *data, const char *bus, const char *old_id EINA_UNUSED, const char *new_id) -{ - const char *svc, *service = data; - Eina_List *l; - - l = eina_list_data_find_list(items, service); - if (strcmp(new_id, "")) - { - if (l) return; - items = eina_list_append(items, service); - svc = strchr(service, '/') + 1; - registered_cb(user_data, bus, svc); - return; - } - - svc = strchr(service, '/') + 1; - - eldbus_service_signal_emit(iface, ITEM_UNREGISTERED, svc); - if (l) - { - items = eina_list_remove_list(items, l); - if (unregistered_cb) - unregistered_cb(user_data, bus, svc); - } - bus = eina_stringshare_add(bus); - if (eina_hash_del_by_key(systray_ctx_get()->config->items, bus)) - e_config_save_queue(); - eina_stringshare_del(bus); - eldbus_name_owner_changed_callback_del(conn, bus, item_name_monitor_cb, service); - eina_stringshare_del(service); -} - -static Eldbus_Message * -register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *msg) -{ - const char *service, *svc; - char buf[1024]; - Eina_Bool stupid; - - if (!eldbus_message_arguments_get(msg, "s", &service)) - return NULL; - svc = service; - /* if stupid, this app does not conform to http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ - * and is expecting to have its send id watched as it is not providing a real bus name here */ - stupid = !!strncmp(svc, "org.", 4); - - snprintf(buf, sizeof(buf), "%s/%s", stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "/StatusNotifierItem"); - service = eina_stringshare_add(buf); - if (eina_list_data_find(items, service)) - { - eina_stringshare_del(service); - return eldbus_message_error_new(msg, ERROR_ITEM_ALREADY_REGISTERED, ""); - } - - items = eina_list_append(items, service); - eldbus_service_signal_emit(s_iface, ITEM_REGISTERED, svc); - eldbus_name_owner_changed_callback_add(conn, stupid ? eldbus_message_sender_get(msg) : svc, - item_name_monitor_cb, service, - EINA_FALSE); - - if (registered_cb) - registered_cb(user_data, stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "/StatusNotifierItem"); - return eldbus_message_method_return_new(msg); -} - -static void -host_name_monitor_cb(void *data EINA_UNUSED, const char *bus, const char *old_id EINA_UNUSED, const char *new_id) -{ - if (strcmp(new_id, "")) - return; - - eldbus_service_signal_emit(iface, HOST_UNREGISTERED); - eina_stringshare_del(host_service); - host_service = NULL; - eldbus_name_owner_changed_callback_del(conn, bus, host_name_monitor_cb, NULL); -} - -static Eldbus_Message * -register_host_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *msg) -{ - if (host_service) - return eldbus_message_error_new(msg, ERROR_HOST_ALREADY_REGISTERED, ""); - - if (!eldbus_message_arguments_get(msg, "s", &host_service)) - return NULL; - - host_service = eina_stringshare_add(host_service); - eldbus_service_signal_emit(s_iface, HOST_REGISTERED); - eldbus_name_owner_changed_callback_add(conn, eldbus_message_sender_get(msg), - host_name_monitor_cb, NULL, EINA_FALSE); - return eldbus_message_method_return_new(msg); -} - -static Eina_Bool -properties_get(const Eldbus_Service_Interface *s_iface EINA_UNUSED, const char *propname, Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED, Eldbus_Message **error EINA_UNUSED) -{ - if (!strcmp(propname, "ProtocolVersion")) - eldbus_message_iter_basic_append(iter, 'i', PROTOCOL_VERSION); - else if (!strcmp(propname, "RegisteredStatusNotifierItems")) - { - Eldbus_Message_Iter *array; - Eina_List *l; - const char *service; - - eldbus_message_iter_arguments_append(iter, "as", &array); - EINA_LIST_FOREACH(items, l, service) - eldbus_message_iter_arguments_append(array, "s", service); - eldbus_message_iter_container_close(iter, array); - } - else if (!strcmp(propname, "IsStatusNotifierHostRegistered")) - eldbus_message_iter_arguments_append(iter, "b", host_service ? EINA_TRUE : EINA_FALSE); - return EINA_TRUE; -} - -static const Eldbus_Property properties[] = -{ - { "RegisteredStatusNotifierItems", "as", NULL, NULL, 0 }, - { "IsStatusNotifierHostRegistered", "b", NULL, NULL, 0 }, - { "ProtocolVersion", "i", NULL, NULL, 0 }, - { NULL, NULL, NULL, NULL, 0 } -}; - -static const Eldbus_Signal signals[] = { - { "StatusNotifierItemRegistered", ELDBUS_ARGS({"s", "service"}), 0 }, - { "StatusNotifierItemUnregistered", ELDBUS_ARGS({"s", "service"}), 0 }, - { "StatusNotifierHostRegistered", NULL, 0 }, - { "StatusNotifierHostUnregistered", NULL, 0 }, - { NULL, NULL, 0 } -}; - -static const Eldbus_Method methods[] = -{ - { "RegisterStatusNotifierItem", ELDBUS_ARGS({"s", "service"}), NULL, - register_item_cb, 0 }, - { "RegisterStatusNotifierHost", ELDBUS_ARGS({"s", "service"}), NULL, - register_host_cb, 0 }, - { NULL, NULL, NULL, NULL, 0 } -}; - -static const Eldbus_Service_Interface_Desc iface_desc = { - IFACE, methods, signals, properties, properties_get, NULL -}; - - -static void -systray_notifier_item_hash_del(Notifier_Item_Cache *item) -{ - eina_stringshare_del(item->path); - free(item); -} - -void -systray_notifier_dbus_watcher_start(Eldbus_Connection *connection, E_Notifier_Watcher_Item_Registered_Cb registered, E_Notifier_Watcher_Item_Unregistered_Cb unregistered, const void *data) -{ - const char *dbus; - - EINA_SAFETY_ON_TRUE_RETURN(!!conn); - conn = connection; - iface = eldbus_service_interface_register(conn, PATH, &iface_desc); - registered_cb = registered; - unregistered_cb = unregistered; - user_data = (void *)data; - host_service = eina_stringshare_add("internal"); - dbus = eldbus_connection_unique_name_get(conn); - if (systray_ctx_get()->config->items) - eina_hash_free_cb_set(systray_ctx_get()->config->items, (Eina_Free_Cb)systray_notifier_item_hash_del); - if (dbus && systray_ctx_get()->config->dbus && systray_ctx_get()->config->items) - { - if (!strcmp(systray_ctx_get()->config->dbus, dbus)) - { - Eina_Iterator *it; - Eina_Hash_Tuple *t; - - it = eina_hash_iterator_tuple_new(systray_ctx_get()->config->items); - EINA_ITERATOR_FOREACH(it, t) - { - char buf[1024]; - Notifier_Item_Cache *nic = t->data; - - snprintf(buf, sizeof(buf), "%s/%s", (char*)t->key, nic->path); - eldbus_name_owner_changed_callback_add(conn, t->key, - item_name_monitor_cb, eina_stringshare_add(buf), - EINA_TRUE); - } - eina_iterator_free(it); - return; - } - } - eina_stringshare_replace(&systray_ctx_get()->config->dbus, dbus); - if (systray_ctx_get()->config->items) - eina_hash_free_buckets(systray_ctx_get()->config->items); - else - systray_ctx_get()->config->items = eina_hash_stringshared_new((Eina_Free_Cb)systray_notifier_item_hash_del); - e_config_save_queue(); -} - -void -systray_notifier_dbus_watcher_stop(void) -{ - const char *txt; - - eldbus_service_interface_unregister(iface); - EINA_LIST_FREE(items, txt) - { - char *bus; - int i; - - for (i = 0; txt[i] != '/'; i++); - i++; - bus = malloc(sizeof(char) * i); - snprintf(bus, i, "%s", txt); - eldbus_name_owner_changed_callback_del(conn, bus, item_name_monitor_cb, txt); - free(bus); - eina_stringshare_del(txt); - } - if (host_service) - eina_stringshare_del(host_service); - conn = NULL; - E_FREE_FUNC(systray_ctx_get()->config->items, eina_hash_free); - eina_stringshare_replace(&systray_ctx_get()->config->dbus, NULL); -}