forked from enlightenment/enlightenment
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
This commit is contained in:
parent
71f7720669
commit
432d1e3776
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue