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

-- 


Reply via email to