discomfitor pushed a commit to branch enlightenment-0.19.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=6f4d1268d159013ab17ff097acfef673cf76ebd2

commit 6f4d1268d159013ab17ff097acfef673cf76ebd2
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Tue Sep 22 18:38:34 2015 -0400

    fix systray implementation of notifier watcher (StatusNotifierItem)
    
    previously, this would throw dbus errors (or not) and then do nothing in
    many cases. now it manages bus/path names more effectively and falls back
    to binary image data when an icon path is not available
    
    fix T2626 and probably some others
---
 src/modules/systray/e_mod_notifier_host.c         | 21 ++++-
 src/modules/systray/e_mod_notifier_host_dbus.c    | 96 ++++++++++++++++++++---
 src/modules/systray/e_mod_notifier_host_private.h |  4 +
 src/modules/systray/e_mod_notifier_watcher.c      | 21 ++---
 4 files changed, 116 insertions(+), 26 deletions(-)

diff --git a/src/modules/systray/e_mod_notifier_host.c 
b/src/modules/systray/e_mod_notifier_host.c
index 0cd7a26..065c82f 100644
--- a/src/modules/systray/e_mod_notifier_host.c
+++ b/src/modules/systray/e_mod_notifier_host.c
@@ -42,6 +42,8 @@ systray_notifier_item_free(Notifier_Item *item)
      e_dbusmenu_unload(item->menu_data);
    eina_stringshare_del(item->bus_id);
    eina_stringshare_del(item->path);
+   free(item->imgdata);
+   free(item->attnimgdata);
    if (item->attention_icon_name)
      eina_stringshare_del(item->attention_icon_name);
    if (item->icon_name)
@@ -64,7 +66,7 @@ systray_notifier_item_free(Notifier_Item *item)
 }
 
 static void
-image_load(const char *name, const char *path, Evas_Object *image)
+image_load(const char *name, const char *path, uint32_t *imgdata, int w, int 
h, Evas_Object *image)
 {
    const char **ext, *exts[] =
    {
@@ -96,7 +98,18 @@ image_load(const char *name, const char *path, Evas_Object 
*image)
                }
           }
      }
-   if (!e_util_icon_theme_set(image, name))
+   if (name && name[0] && e_util_icon_theme_set(image, name)) return;
+   if (imgdata)
+     {
+        Evas_Object *o;
+
+        o = evas_object_image_filled_add(evas_object_evas_get(image));
+        evas_object_image_alpha_set(o, 1);
+        evas_object_image_size_set(o, w, h);
+        evas_object_image_data_set(o, imgdata);
+        e_icon_image_object_set(image, o);
+     }
+   else
      e_util_icon_theme_set(image, "dialog-error");
 }
 
@@ -261,7 +274,7 @@ jump_search:
      {
       case STATUS_ACTIVE:
         {
-           image_load(item->icon_name, item->icon_path, ii->icon);
+           image_load(item->icon_name, item->icon_path, item->imgdata, 
item->imgw, item->imgh, ii->icon);
            if (!evas_object_visible_get(ii->icon))
              {
                 systray_edje_box_append(host_inst->inst, ii->icon);
@@ -280,7 +293,7 @@ jump_search:
         }
       case STATUS_ATTENTION:
         {
-           image_load(item->attention_icon_name, item->icon_path, ii->icon);
+           image_load(item->attention_icon_name, item->icon_path, 
item->attnimgdata, item->attnimgw, item->attnimgh, ii->icon);
            if (!evas_object_visible_get(ii->icon))
              {
                 systray_edje_box_append(host_inst->inst, ii->icon);
diff --git a/src/modules/systray/e_mod_notifier_host_dbus.c 
b/src/modules/systray/e_mod_notifier_host_dbus.c
index f5de199..77ae5b5 100644
--- a/src/modules/systray/e_mod_notifier_host_dbus.c
+++ b/src/modules/systray/e_mod_notifier_host_dbus.c
@@ -14,6 +14,8 @@
 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;
@@ -57,6 +59,36 @@ id_find(const char *s, const char *names[])
 }
 
 static void
+icon_pixmap_deserialize(Eldbus_Message_Iter *variant, uint32_t **data, int *w, 
int *h)
+{
+   Eldbus_Message_Iter *iter, *struc;
+
+   *data = NULL;
+   *w = *h = 0;
+   eldbus_message_iter_arguments_get(variant, "a(iiay)", &iter);
+   while (eldbus_message_iter_get_and_next(iter, 'r', &struc))
+     {
+        Eldbus_Message_Iter *imgdata;
+
+        if (eldbus_message_iter_arguments_get(struc, "iiay", w, h, &imgdata))
+          {
+             uint32_t *img;
+             int len;
+
+             if (eldbus_message_iter_fixed_array_get(imgdata, 'y', &img, &len))
+               {
+                  unsigned int pos;
+
+                  *data = malloc(len * sizeof(int));
+                  for (pos = 0; pos < (unsigned int)len; pos++)
+                    (*data)[pos] = eina_swap32(img[pos]);
+                  return;
+               }
+          }
+     }
+}
+
+static void
 item_prop_get(void *data, const void *key, Eldbus_Message_Iter *var)
 {
    Notifier_Item *item = data;
@@ -73,6 +105,16 @@ item_prop_get(void *data, const void *key, 
Eldbus_Message_Iter *var)
         eldbus_message_iter_arguments_get(var, "s", &name);
         eina_stringshare_replace(&item->icon_name, name);
      }
+   else if (!strcmp(key, "IconPixmap"))
+     {
+        free(item->imgdata);
+        icon_pixmap_deserialize(var, &item->imgdata, &item->imgw, &item->imgh);
+     }
+   else if (!strcmp(key, "AttentionIconPixmap"))
+     {
+        free(item->attnimgdata);
+        icon_pixmap_deserialize(var, &item->attnimgdata, &item->attnimgw, 
&item->attnimgh);
+     }
    else if (!strcmp(key, "AttentionIconName"))
      {
         const char *name;
@@ -191,12 +233,27 @@ basic_prop_get(const char *propname, void *data, const 
Eldbus_Message *msg)
 }
 
 static void
+attention_icon_pixmap_get_cb(void *data, const Eldbus_Message *msg, 
Eldbus_Pending *pending EINA_UNUSED)
+{
+   Notifier_Item *item = data;
+   Eldbus_Message_Iter *variant;
+
+   if (!eldbus_message_arguments_get(msg, "v", &variant)) return;
+   free(item->attnimgdata);
+   icon_pixmap_deserialize(variant, &item->attnimgdata, &item->attnimgw, 
&item->attnimgh);
+   systray_notifier_item_update(item);
+}
+
+static void
 attention_icon_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending 
*pending EINA_UNUSED)
 {
    Notifier_Item *item = data;
    const char *propname = "AttentionIconName";
    basic_prop_get(propname, item, msg);
-   systray_notifier_item_update(item);
+   if ((!item->attention_icon_name) || (!item->attention_icon_name[0]))
+     eldbus_proxy_property_get(item->proxy, "AttentionIconPixmap", 
attention_icon_pixmap_get_cb, item);
+   else
+     systray_notifier_item_update(item);
 }
 
 static void
@@ -207,12 +264,27 @@ new_attention_icon_cb(void *data, const Eldbus_Message 
*msg EINA_UNUSED)
 }
 
 static void
+icon_pixmap_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending 
*pending EINA_UNUSED)
+{
+   Notifier_Item *item = data;
+   Eldbus_Message_Iter *variant;
+
+   if (!eldbus_message_arguments_get(msg, "v", &variant)) return;
+   free(item->imgdata);
+   icon_pixmap_deserialize(variant, &item->imgdata, &item->imgw, &item->imgh);
+   systray_notifier_item_update(item);
+}
+
+static void
 icon_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending 
EINA_UNUSED)
 {
    Notifier_Item *item = data;
    const char *propname = "IconName";
    basic_prop_get(propname, item, msg);
-   systray_notifier_item_update(item);
+   if ((!item->icon_name) || (!item->icon_name[0]))
+     eldbus_proxy_property_get(item->proxy, "IconPixmap", icon_pixmap_get_cb, 
item);
+   else
+     systray_notifier_item_update(item);
 }
 
 static void
@@ -373,28 +445,24 @@ notifier_items_get_cb(void *data, const Eldbus_Message 
*msg, Eldbus_Pending *pen
 }
 
 static void
-item_registered_local_cb(void *data, const char *service)
+item_registered_local_cb(void *data, const char *bus)
 {
-   const char *bus, *path;
    Context_Notifier_Host *ctx = data;
-   if (service_string_parse(service, &path, &bus))
-     notifier_item_add(path, bus, ctx);
+   notifier_item_add(eina_stringshare_ref(DBUS_PATH), 
eina_stringshare_add(bus), ctx);
 }
 
 static void
-item_unregistered_local_cb(void *data, const char *service)
+item_unregistered_local_cb(void *data, const char *bus)
 {
-   const char *bus, *path;
    Context_Notifier_Host *ctx = data;
    Notifier_Item *item;
+   Eina_Stringshare *s;
 
-   if (!service_string_parse(service, &path, &bus))
-     return;
-   item = notifier_item_find(path, bus, ctx);
+   s = eina_stringshare_add(bus);
+   item = notifier_item_find(DBUS_PATH, s, ctx);
    if (item)
      systray_notifier_item_free(item);
-   eina_stringshare_del(path);
-   eina_stringshare_del(bus);
+   eina_stringshare_del(s);
 }
 
 static void
@@ -447,6 +515,7 @@ 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);
@@ -473,6 +542,7 @@ 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();
 }
diff --git a/src/modules/systray/e_mod_notifier_host_private.h 
b/src/modules/systray/e_mod_notifier_host_private.h
index f318916..ad3bcd6 100644
--- a/src/modules/systray/e_mod_notifier_host_private.h
+++ b/src/modules/systray/e_mod_notifier_host_private.h
@@ -57,6 +57,10 @@ struct _Notifier_Item
    const char *menu_path;
    E_DBusMenu_Ctx *menu_data;
    Eina_List *signals;
+   uint32_t *imgdata;
+   int imgw, imgh;
+   uint32_t *attnimgdata;
+   int attnimgw, attnimgh;
 };
 
 typedef void (*E_Notifier_Watcher_Item_Registered_Cb)(void *data, const char 
*service);
diff --git a/src/modules/systray/e_mod_notifier_watcher.c 
b/src/modules/systray/e_mod_notifier_watcher.c
index e31ab45..666a5b4 100644
--- a/src/modules/systray/e_mod_notifier_watcher.c
+++ b/src/modules/systray/e_mod_notifier_watcher.c
@@ -26,29 +26,32 @@ enum
 static void
 item_name_monitor_cb(void *data, const char *bus, const char *old_id 
EINA_UNUSED, const char *new_id)
 {
-   const char *service = data;
+   const char *svc, *service = data;
 
    if (strcmp(new_id, ""))
      return;
 
-   eldbus_service_signal_emit(iface, ITEM_UNREGISTERED, service);
+   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, service);
+     unregistered_cb(user_data, bus);
+   eldbus_name_owner_changed_callback_del(conn, svc, item_name_monitor_cb, 
service);
    eina_stringshare_del(service);
-   eldbus_name_owner_changed_callback_del(conn, bus, item_name_monitor_cb, 
service);
 }
 
 static Eldbus_Message *
 register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message 
*msg)
 {
-   const char *service;
+   const char *service, *svc;
    char buf[1024];
 
    if (!eldbus_message_arguments_get(msg, "s", &service))
      return NULL;
+   svc = service;
 
-   snprintf(buf, sizeof(buf), "%s%s", eldbus_message_sender_get(msg), service);
+   snprintf(buf, sizeof(buf), "%s/%s", eldbus_message_sender_get(msg), 
service);
    service = eina_stringshare_add(buf);
    if (eina_list_data_find(items, service))
      {
@@ -57,13 +60,13 @@ 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, service);
-   eldbus_name_owner_changed_callback_add(conn, eldbus_message_sender_get(msg),
+   eldbus_service_signal_emit(s_iface, ITEM_REGISTERED, svc);
+   eldbus_name_owner_changed_callback_add(conn, svc,
                                          item_name_monitor_cb, service,
                                          EINA_FALSE);
 
    if (registered_cb)
-     registered_cb(user_data, service);
+     registered_cb(user_data, svc);
    return eldbus_message_method_return_new(msg);
 }
 

-- 


Reply via email to