discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=432d1e37768a8218764ca8176a041f120f1c9253
commit 432d1e37768a8218764ca8176a041f120f1c9253 Author: Mike Blumenkrantz <zm...@osg.samsung.com> Date: Wed Oct 14 16:30:41 2015 -0400 cache systray items for each dbus session the current spec does not directly require any behavior from clients when a systray host, leading to an issue where clients do not re-register their items when a new host appears when using an in-process systray watcher, as the current implementation does, the best choice for maintaining consistency for systray items across restarts is to cache them according to the current dbus session. the process of setting up the item will validate it on subsequent restarts, and changes to the session will clear the cache fix T2786 --- src/modules/systray/e_mod_main.c | 10 ++++ src/modules/systray/e_mod_main.h | 14 +++++- src/modules/systray/e_mod_notifier_host_dbus.c | 6 +++ src/modules/systray/e_mod_notifier_watcher.c | 64 ++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/modules/systray/e_mod_main.c b/src/modules/systray/e_mod_main.c index 3fceb47..dfe230e 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 4d83d24..189c884 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 8eba2b1..7975bad 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 3e9a47b..c091bb2 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 --