forked from enlightenment/enlightenment
fix systray to work with spec-breaking apps, eg. steam
according to the StatusNotifierItem specification, applications register "service org.freedesktop.StatusNotifierItem-PID-ID" on the session bus, and then "must register the unique instance name to the StatusNotifierWatcher". some applications, such as steam, instead register the path that they will run on (/org/ayatana/NotificationItem/steam) and then expect the watcher to register the method call's send id bus: this is totally bogus. to catch this, when registering the new item the enlightenment watcher must first determine if the item is spec-conforming. if yes, proceed as normal. if no, pretend the application knows what it's doing and try to make things work as expected anyway for more details, read the full spec here http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem fix T2763
This commit is contained in:
parent
4d30674ab8
commit
6ff98d8a39
|
@ -14,8 +14,6 @@
|
|||
extern const char *Category_Names[];
|
||||
extern const char *Status_Names[];
|
||||
|
||||
static Eina_Stringshare *DBUS_PATH;
|
||||
|
||||
typedef struct _Notifier_Host_Data {
|
||||
Instance_Notifier_Host *host_inst;
|
||||
void *data;
|
||||
|
@ -445,24 +443,26 @@ notifier_items_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
|
|||
}
|
||||
|
||||
static void
|
||||
item_registered_local_cb(void *data, const char *bus)
|
||||
item_registered_local_cb(void *data, const char *bus, const char *path)
|
||||
{
|
||||
Context_Notifier_Host *ctx = data;
|
||||
notifier_item_add(eina_stringshare_ref(DBUS_PATH), eina_stringshare_add(bus), ctx);
|
||||
notifier_item_add(eina_stringshare_add(path), eina_stringshare_add(bus), ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
item_unregistered_local_cb(void *data, const char *bus)
|
||||
item_unregistered_local_cb(void *data, const char *bus, const char *path)
|
||||
{
|
||||
Context_Notifier_Host *ctx = data;
|
||||
Notifier_Item *item;
|
||||
Eina_Stringshare *s;
|
||||
Eina_Stringshare *s, *p;
|
||||
|
||||
s = eina_stringshare_add(bus);
|
||||
item = notifier_item_find(DBUS_PATH, s, ctx);
|
||||
p = eina_stringshare_add(path);
|
||||
item = notifier_item_find(p, s, ctx);
|
||||
if (item)
|
||||
systray_notifier_item_free(item);
|
||||
eina_stringshare_del(s);
|
||||
eina_stringshare_del(p);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -515,7 +515,6 @@ systray_notifier_dbus_init(Context_Notifier_Host *ctx)
|
|||
eldbus_init();
|
||||
ctx->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
||||
if (!ctx->conn) return;
|
||||
DBUS_PATH = eina_stringshare_add("/StatusNotifierItem");
|
||||
p = eldbus_name_request(ctx->conn,
|
||||
WATCHER_BUS, ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING,
|
||||
name_request_cb, ctx);
|
||||
|
@ -542,7 +541,6 @@ void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
|
|||
eldbus_object_unref(obj);
|
||||
ctx->watcher = NULL;
|
||||
}
|
||||
eina_stringshare_replace(&DBUS_PATH, NULL);
|
||||
eldbus_connection_unref(ctx->conn);
|
||||
eldbus_shutdown();
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ struct _Notifier_Item
|
|||
int attnimgw, attnimgh;
|
||||
};
|
||||
|
||||
typedef void (*E_Notifier_Watcher_Item_Registered_Cb)(void *data, const char *service);
|
||||
typedef void (*E_Notifier_Watcher_Item_Unregistered_Cb)(void *data, const char *service);
|
||||
typedef void (*E_Notifier_Watcher_Item_Registered_Cb)(void *data, const char *service, const char *path);
|
||||
typedef void (*E_Notifier_Watcher_Item_Unregistered_Cb)(void *data, const char *service, const char *path);
|
||||
|
||||
void systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item);
|
||||
void systray_notifier_item_update(Notifier_Item *item);
|
||||
|
|
|
@ -36,8 +36,8 @@ item_name_monitor_cb(void *data, const char *bus, const char *old_id EINA_UNUSED
|
|||
eldbus_service_signal_emit(iface, ITEM_UNREGISTERED, svc);
|
||||
items = eina_list_remove(items, service);
|
||||
if (unregistered_cb)
|
||||
unregistered_cb(user_data, bus);
|
||||
eldbus_name_owner_changed_callback_del(conn, svc, item_name_monitor_cb, service);
|
||||
unregistered_cb(user_data, bus, svc);
|
||||
eldbus_name_owner_changed_callback_del(conn, bus, item_name_monitor_cb, service);
|
||||
eina_stringshare_del(service);
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,16 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
|
|||
{
|
||||
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", eldbus_message_sender_get(msg), service);
|
||||
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))
|
||||
{
|
||||
|
@ -61,12 +65,12 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
|
|||
|
||||
items = eina_list_append(items, service);
|
||||
eldbus_service_signal_emit(s_iface, ITEM_REGISTERED, svc);
|
||||
eldbus_name_owner_changed_callback_add(conn, 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, svc);
|
||||
registered_cb(user_data, stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "/StatusNotifierItem");
|
||||
return eldbus_message_method_return_new(msg);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue