diff --git a/src/modules/systray/e_mod_main.c b/src/modules/systray/e_mod_main.c index 3fceb47c5..dfe230e38 100644 --- a/src/modules/systray/e_mod_main.c +++ b/src/modules/systray/e_mod_main.c @@ -391,10 +391,19 @@ e_modapi_init(E_Module *m) ctx = calloc(1, sizeof(Systray_Context)); ctx->conf_edd = E_CONFIG_DD_NEW("Systray_Config", Systray_Config); + ctx->notifier_item_edd = E_CONFIG_DD_NEW("Notifier_Item_Cache", Notifier_Item_Cache); + #undef T + #undef D + #define T Notifier_Item_Cache + #define D ctx->notifier_item_edd + E_CONFIG_VAL(D, T, path, STR); #undef T #undef D #define T Systray_Config #define D ctx->conf_edd + E_CONFIG_VAL(D, T, dbus, STR); + E_CONFIG_HASH(D, T, items, ctx->notifier_item_edd); + ctx->config = e_config_domain_load(_name, ctx->conf_edd); if (!ctx->config) ctx->config = calloc(1, sizeof(Systray_Config)); @@ -415,6 +424,7 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED) systray_notifier_host_shutdown(); E_CONFIG_DD_FREE(ctx->conf_edd); + E_CONFIG_DD_FREE(ctx->notifier_item_edd); free(ctx->config); free(ctx); return 1; diff --git a/src/modules/systray/e_mod_main.h b/src/modules/systray/e_mod_main.h index 4d83d249c..189c884f4 100644 --- a/src/modules/systray/e_mod_main.h +++ b/src/modules/systray/e_mod_main.h @@ -14,7 +14,7 @@ typedef struct _Context_Notifier_Host Context_Notifier_Host; typedef struct _Instance_Notifier_Host Instance_Notifier_Host; typedef struct _Notifier_Item Notifier_Item; typedef struct _Systray_Context Systray_Context; -typedef struct _E_Config_Dialog_Data Systray_Config; +typedef struct Systray_Config Systray_Config; struct _E_Config_Dialog_Data { @@ -24,6 +24,7 @@ struct _Systray_Context { Systray_Config *config; E_Config_DD *conf_edd; + E_Config_DD *notifier_item_edd; }; struct _Instance @@ -41,6 +42,17 @@ struct _Instance } job; }; +typedef struct Notifier_Item_Cache +{ + Eina_Stringshare *path; +} Notifier_Item_Cache; + +struct Systray_Config +{ + Eina_Stringshare *dbus; + Eina_Hash *items; +}; + E_Gadcon_Orient systray_orient_get(const Instance *inst); const E_Gadcon *systray_gadcon_get(const Instance *inst); E_Gadcon_Client *systray_gadcon_client_get(const Instance *inst); diff --git a/src/modules/systray/e_mod_notifier_host_dbus.c b/src/modules/systray/e_mod_notifier_host_dbus.c index 8eba2b19d..7975bade3 100644 --- a/src/modules/systray/e_mod_notifier_host_dbus.c +++ b/src/modules/systray/e_mod_notifier_host_dbus.c @@ -340,6 +340,7 @@ static void notifier_item_add(const char *path, const char *bus_id, Context_Notifier_Host *ctx) { Eldbus_Proxy *proxy; + Notifier_Item_Cache *nic; Notifier_Item *item = calloc(1, sizeof(Notifier_Item)); Eldbus_Signal_Handler *s; EINA_SAFETY_ON_NULL_RETURN(item); @@ -368,6 +369,11 @@ notifier_item_add(const char *path, const char *bus_id, Context_Notifier_Host *c item->signals = eina_list_append(item->signals, s); s = eldbus_proxy_signal_handler_add(proxy, "NewTitle", new_title_cb, item); item->signals = eina_list_append(item->signals, s); + if (eina_hash_find(systray_ctx_get()->config->items, bus_id)) return; + nic = malloc(sizeof(Notifier_Item_Cache)); + nic->path = eina_stringshare_ref(path); + eina_hash_add(systray_ctx_get()->config->items, bus_id, nic); + e_config_save_queue(); } static void diff --git a/src/modules/systray/e_mod_notifier_watcher.c b/src/modules/systray/e_mod_notifier_watcher.c index 3e9a47bd5..c091bb2eb 100644 --- a/src/modules/systray/e_mod_notifier_watcher.c +++ b/src/modules/systray/e_mod_notifier_watcher.c @@ -27,16 +27,31 @@ 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, "")) - return; + { + 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); - items = eina_list_remove(items, service); - if (unregistered_cb) - unregistered_cb(user_data, bus, 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); } @@ -152,9 +167,19 @@ 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); @@ -162,6 +187,37 @@ systray_notifier_dbus_watcher_start(Eldbus_Connection *connection, E_Notifier_Wa unregistered_cb = unregistered; user_data = (void *)data; host_service = eina_stringshare_add("internal"); + dbus = getenv("DBUS_SESSION_BUS_ADDRESS"); + 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 (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