forked from enlightenment/enlightenment
notifications - extend to support actions, links and img tags
we didn't support enough of noktifications to make everyone happy - this is why ffox, chrome etc. did their own notification windows and didn't use e's notifications. we now advertise doing everything. we say w edo sound though don't.... will add that later, but this now means we really do a lot more and thus pushes these other notifications into e's notifications so we're much better now and this annoyance i have noticed is now gone. @feat
This commit is contained in:
parent
1933f745f2
commit
b23eedae98
|
@ -2,8 +2,8 @@
|
|||
|
||||
typedef struct _Notification_Data
|
||||
{
|
||||
Eldbus_Connection *conn;
|
||||
Eldbus_Service_Interface *iface;
|
||||
Eldbus_Connection *conn;
|
||||
Eldbus_Service_Interface *iface;
|
||||
E_Notification_Notify_Cb notify_cb;
|
||||
E_Notification_Close_Cb close_cb;
|
||||
void *data;
|
||||
|
@ -15,15 +15,28 @@ static Notification_Data *n_data = NULL;
|
|||
static void
|
||||
_notification_free(E_Notification_Notify *notify)
|
||||
{
|
||||
int i;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(notify);
|
||||
eina_stringshare_del(notify->app_name);
|
||||
eina_stringshare_del(notify->body);
|
||||
eina_stringshare_del(notify->icon.icon);
|
||||
if (notify->icon.icon_path)
|
||||
eina_stringshare_del(notify->icon.icon_path);
|
||||
eina_stringshare_del(notify->summary);
|
||||
if (notify->icon.raw.data)
|
||||
free(notify->icon.raw.data);
|
||||
if (notify->app_name) eina_stringshare_del(notify->app_name);
|
||||
if (notify->body) eina_stringshare_del(notify->body);
|
||||
if (notify->icon.icon) eina_stringshare_del(notify->icon.icon);
|
||||
if (notify->icon.icon_path) eina_stringshare_del(notify->icon.icon_path);
|
||||
if (notify->summary) eina_stringshare_del(notify->summary);
|
||||
if (notify->icon.raw.data) free(notify->icon.raw.data);
|
||||
if (notify->category) eina_stringshare_del(notify->category);
|
||||
if (notify->desktop_entry) eina_stringshare_del(notify->desktop_entry);
|
||||
if (notify->sound_file) eina_stringshare_del(notify->sound_file);
|
||||
if (notify->sound_name) eina_stringshare_del(notify->sound_name);
|
||||
if (notify->actions)
|
||||
{
|
||||
for (i = 0; notify->actions[i].action; i++)
|
||||
{
|
||||
eina_stringshare_del(notify->actions[i].action);
|
||||
eina_stringshare_del(notify->actions[i].label);
|
||||
}
|
||||
free(notify->actions);
|
||||
}
|
||||
free(notify);
|
||||
}
|
||||
|
||||
|
@ -31,12 +44,15 @@ static void
|
|||
hints_dict_iter(void *data, const void *key, Eldbus_Message_Iter *var)
|
||||
{
|
||||
E_Notification_Notify *n = data;
|
||||
if (!strcmp(key, "image-data") || !strcmp(key, "image_data"))
|
||||
|
||||
if ((!strcmp(key, "image-data")) || (!strcmp(key, "image_data")) ||
|
||||
(!strcmp(key, "icon_data")))
|
||||
{
|
||||
Eldbus_Message_Iter *st, *data_iter;
|
||||
int w, h, r, bits, channels;
|
||||
Eina_Bool alpha;
|
||||
unsigned char *raw_data;
|
||||
|
||||
if (!eldbus_message_iter_arguments_get(var, "(iiibiiay)", &st))
|
||||
return;
|
||||
if (!eldbus_message_iter_arguments_get(st, "iiibiiay", &w, &h, &r,
|
||||
|
@ -54,22 +70,136 @@ hints_dict_iter(void *data, const void *key, Eldbus_Message_Iter *var)
|
|||
n->icon.raw.data = malloc(sizeof(char) * n->icon.raw.data_size);
|
||||
EINA_SAFETY_ON_NULL_RETURN(n->icon.raw.data);
|
||||
memcpy(n->icon.raw.data, raw_data, sizeof(char) * n->icon.raw.data_size);
|
||||
}
|
||||
else if (!strcmp(key, "urgency"))
|
||||
{
|
||||
unsigned char urgency;
|
||||
eldbus_message_iter_arguments_get(var, "y", &urgency);
|
||||
if (urgency < 3)
|
||||
n->urgency = urgency;
|
||||
printf("NOT: image-data=%ix%i,a=%i\n", w, h, alpha);
|
||||
}
|
||||
else if (!strcmp(key, "image-path") || !strcmp(key, "image_path"))
|
||||
{
|
||||
eldbus_message_iter_arguments_get(var, "s", &n->icon.icon_path);
|
||||
n->icon.icon_path = eina_stringshare_add(n->icon.icon_path);
|
||||
printf("NOT: image-path=[%s]\n", n->icon.icon_path);
|
||||
// path to image file
|
||||
}
|
||||
else if (!strcmp(key, "urgency"))
|
||||
{
|
||||
unsigned char urgency;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "y", &urgency);
|
||||
if (urgency < 3) n->urgency = urgency;
|
||||
printf("NOT: urgency=%i\n", n->urgency);
|
||||
// 0=low, 1=normal, 2=critical
|
||||
}
|
||||
else if (!strcmp(key, "category"))
|
||||
{ // XXX: store category
|
||||
const char *val = NULL;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "s", &val);
|
||||
printf("NOT: category=[%s]\n", val);
|
||||
// "device" A generic device-related notification that doesn't fit into any other category.
|
||||
// "device.added" A device, such as a USB device, was added to the system.
|
||||
// "device.error" A device had some kind of error.
|
||||
// "device.removed" A device, such as a USB device, was removed from the system.
|
||||
// "email" A generic e-mail-related notification that doesn't fit into any other category.
|
||||
// "email.arrived" A new e-mail notification.
|
||||
// "email.bounced" A notification stating that an e-mail has bounced.
|
||||
// "im" A generic instant message-related notification that doesn't fit into any other category.
|
||||
// "im.error" An instant message error notification.
|
||||
// "im.received" A received instant message notification.
|
||||
// "network" A generic network notification that doesn't fit into any other category.
|
||||
// "network.connected" A network connection notification, such as successful sign-on to a network service. This should not be confused with device.added for new network devices.
|
||||
// "network.disconnected" A network disconnected notification. This should not be confused with device.removed for disconnected network devices.
|
||||
// "network.error" A network-related or connection-related error.
|
||||
// "presence" A generic presence change notification that doesn't fit into any other category, such as going away or idle.
|
||||
// "presence.offline" An offline presence change notification.
|
||||
// "presence.online" An online presence change notification.
|
||||
// "transfer" A generic file transfer or download notification that doesn't fit into any other category.
|
||||
// "transfer.complete" A file transfer or download complete notification.
|
||||
// "transfer.error" A file transfer or download error.
|
||||
if (val) n->category = eina_stringshare_add(val);
|
||||
}
|
||||
else if (!strcmp(key, "desktop-entry"))
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "s", &val);
|
||||
printf("NOT: desktop-entry=[%s]\n", val);
|
||||
// if rage.desktop -> "rage"
|
||||
// if terminology.desktop -> "terminology"
|
||||
if (val) n->desktop_entry = eina_stringshare_add(val);
|
||||
}
|
||||
else if (!strcmp(key, "icon-actions"))
|
||||
{
|
||||
Eina_Bool val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "b", &val);
|
||||
printf("NOT: icon-actions=%i\n", val);
|
||||
// 1 == interpret action identifier == named icon in icon naming standards
|
||||
n->icon_actions = val;
|
||||
}
|
||||
else if (!strcmp(key, "resident"))
|
||||
{
|
||||
Eina_Bool val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "b", &val);
|
||||
printf("NOT: resident=%i\n", val);
|
||||
// 1== remove notification when action invoked - no timeout
|
||||
n->resident = val;
|
||||
}
|
||||
else if (!strcmp(key, "supress-sound"))
|
||||
{
|
||||
Eina_Bool val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "b", &val);
|
||||
printf("NOT: supress-sound=%i\n", val);
|
||||
// 1== remove notification when action invoked - no timeout
|
||||
n->suppress_sound = val;
|
||||
}
|
||||
else if (!strcmp(key, "sound-file"))
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "s", &val);
|
||||
printf("NOT: sound-file=[%s]\n", val);
|
||||
// path to sound file to play
|
||||
if (val) n->sound_file = eina_stringshare_add(val);
|
||||
}
|
||||
else if (!strcmp(key, "sound-name"))
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "s", &val);
|
||||
printf("NOT: sound-file=[%s]\n", val);
|
||||
// sound naming spec to play
|
||||
// http://0pointer.de/public/sound-naming-spec.html
|
||||
if (val) n->sound_name = eina_stringshare_add(val);
|
||||
}
|
||||
else if (!strcmp(key, "transient"))
|
||||
{
|
||||
Eina_Bool val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "b", &val);
|
||||
printf("NOT: transient=%i\n", val);
|
||||
n->transient = val;
|
||||
}
|
||||
else if (!strcmp(key, "x"))
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "i", &val);
|
||||
printf("NOT: x=%i\n", val);
|
||||
n->x = val;
|
||||
n->have_xy = EINA_TRUE;
|
||||
}
|
||||
else if (!strcmp(key, "y"))
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
eldbus_message_iter_arguments_get(var, "i", &val);
|
||||
printf("NOT: y=%i\n", val);
|
||||
n->y = val;
|
||||
n->have_xy = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* this function should be external in edje for use in cases such as this module.
|
||||
*
|
||||
* happily, it was decided that the function would not be external so that it could
|
||||
|
@ -93,134 +223,188 @@ _text_escape(Eina_Strbuf *txt, const char *text)
|
|||
return advance;
|
||||
}
|
||||
|
||||
/* hardcoded list of allowed tags based on
|
||||
* https://people.gnome.org/~mccann/docs/notification-spec/notification-spec-latest.html#markup
|
||||
*/
|
||||
static const char *tags[] =
|
||||
static int
|
||||
_tag_len(const char *txt)
|
||||
{
|
||||
"<b",
|
||||
"<i",
|
||||
"<u",
|
||||
//"<a", FIXME: we can't actually display these right now
|
||||
//"<img",
|
||||
};
|
||||
const char *s;
|
||||
Eina_Bool backslash = EINA_FALSE;
|
||||
Eina_Bool inquote = EINA_FALSE, indblquote = EINA_FALSE;
|
||||
|
||||
static const char *
|
||||
_get_tag(const char *c)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (c[1] != '>') return NULL;
|
||||
for (i = 0; i < EINA_C_ARRAY_LENGTH(tags); i++)
|
||||
if (tags[i][1] == c[0]) return tags[i];
|
||||
return NULL;
|
||||
if (txt[0] != '<') return 0;
|
||||
for (s = txt; *s; s++)
|
||||
{
|
||||
if (!backslash)
|
||||
{
|
||||
if (*s == '\\') backslash = EINA_TRUE;
|
||||
else
|
||||
{
|
||||
if (inquote)
|
||||
{
|
||||
if (*s == '\'') inquote = EINA_FALSE;
|
||||
}
|
||||
else if (indblquote)
|
||||
{
|
||||
if (*s == '"') indblquote = EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*s == '>')
|
||||
{
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
else if (*s == '\'') inquote = EINA_TRUE;
|
||||
else if (*s == '\"') indblquote = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else backslash = EINA_FALSE;
|
||||
}
|
||||
return s - txt;
|
||||
}
|
||||
|
||||
char *
|
||||
static char *
|
||||
_path_get(const char *txt)
|
||||
{
|
||||
Eina_Strbuf *buf;
|
||||
char *ret;
|
||||
const char *s;
|
||||
Eina_Bool backslash = EINA_FALSE;
|
||||
Eina_Bool inquote = EINA_FALSE, indblquote = EINA_FALSE;
|
||||
|
||||
if (txt[0] == '>') return NULL;
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
if (!buf) return NULL;
|
||||
|
||||
for (s = txt; *s; s++)
|
||||
{
|
||||
if (!backslash)
|
||||
{
|
||||
if (*s == '\\') backslash = EINA_TRUE;
|
||||
else
|
||||
{
|
||||
if (inquote)
|
||||
{
|
||||
if (*s == '\'') inquote = EINA_FALSE;
|
||||
else eina_strbuf_append_char(buf, *s);
|
||||
}
|
||||
else if (indblquote)
|
||||
{
|
||||
if (*s == '"') indblquote = EINA_FALSE;
|
||||
else eina_strbuf_append_char(buf, *s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*s == '>') break;
|
||||
else if (*s == ' ') break;
|
||||
else if (*s == '\'') inquote = EINA_TRUE;
|
||||
else if (*s == '\"') indblquote = EINA_TRUE;
|
||||
else eina_strbuf_append_char(buf, *s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_strbuf_append_char(buf, *s);
|
||||
backslash = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
ret = eina_strbuf_string_steal(buf);
|
||||
eina_strbuf_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
_nedje_text_escape(const char *text)
|
||||
{
|
||||
Eina_Strbuf *txt;
|
||||
char *ret;
|
||||
const char *text_end;
|
||||
size_t text_len;
|
||||
Eina_Array *arr;
|
||||
const char *cur_tag = NULL;
|
||||
int taglen;
|
||||
|
||||
if (!text) return NULL;
|
||||
|
||||
txt = eina_strbuf_new();
|
||||
text_len = strlen(text);
|
||||
arr = eina_array_new(3);
|
||||
if (!txt) return NULL;
|
||||
|
||||
text_end = text + strlen(text);
|
||||
|
||||
text_end = text + text_len;
|
||||
while (text < text_end)
|
||||
{
|
||||
int advance;
|
||||
|
||||
if ((text[0] == '<') && text[1])
|
||||
taglen = _tag_len(text);
|
||||
if (taglen == 0)
|
||||
{
|
||||
const char *tag, *popped;
|
||||
Eina_Bool closing = EINA_FALSE;
|
||||
|
||||
if (text[1] == '/') //closing tag
|
||||
{
|
||||
closing = EINA_TRUE;
|
||||
tag = _get_tag(text + 2);
|
||||
}
|
||||
else
|
||||
tag = _get_tag(text + 1);
|
||||
if (closing)
|
||||
{
|
||||
if (cur_tag && (tag != cur_tag))
|
||||
{
|
||||
/* tag mismatch: autoclose all failure tags
|
||||
* not technically required by the spec,
|
||||
* but it makes me feel better about myself
|
||||
*/
|
||||
do
|
||||
{
|
||||
popped = eina_array_pop(arr);
|
||||
if (eina_array_count(arr))
|
||||
cur_tag = eina_array_data_get(arr, eina_array_count(arr) - 1);
|
||||
else
|
||||
cur_tag = NULL;
|
||||
eina_strbuf_append_printf(txt, "</%c>", popped[1]);
|
||||
} while (cur_tag && (popped != tag));
|
||||
advance = 4;
|
||||
}
|
||||
else if (cur_tag)
|
||||
{
|
||||
/* tag match: just pop */
|
||||
popped = eina_array_pop(arr);
|
||||
if (eina_array_count(arr))
|
||||
cur_tag = eina_array_data_get(arr, eina_array_count(arr) - 1);
|
||||
else
|
||||
cur_tag = NULL;
|
||||
eina_strbuf_append_printf(txt, "</%c>", popped[1]);
|
||||
advance = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no current tag: escape */
|
||||
advance = _text_escape(txt, text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tag)
|
||||
{
|
||||
cur_tag = tag;
|
||||
eina_array_push(arr, tag);
|
||||
eina_strbuf_append_printf(txt, "<%c>", tag[1]);
|
||||
advance = 3;
|
||||
}
|
||||
else
|
||||
advance = _text_escape(txt, text);
|
||||
}
|
||||
}
|
||||
else if (text[0] == '&')
|
||||
{
|
||||
const char *s;
|
||||
|
||||
s = strchr(text, ';');
|
||||
if (s)
|
||||
s = evas_textblock_escape_string_range_get(text, s + 1);
|
||||
if (s)
|
||||
{
|
||||
eina_strbuf_append_char(txt, text[0]);
|
||||
advance = 1;
|
||||
}
|
||||
else
|
||||
advance = _text_escape(txt, text);
|
||||
eina_strbuf_append_char(txt, text[0]);
|
||||
text++;
|
||||
}
|
||||
else
|
||||
advance = _text_escape(txt, text);
|
||||
{
|
||||
if (!strncmp(text, "<b>", 3)) eina_strbuf_append(txt, "<b>");
|
||||
else if (!strncmp(text, "</b>", 4)) eina_strbuf_append(txt, "</b>");
|
||||
else if (!strncmp(text, "<i>", 3)) eina_strbuf_append(txt, "<i>");
|
||||
else if (!strncmp(text, "</i>", 4)) eina_strbuf_append(txt, "</i>");
|
||||
else if (!strncmp(text, "<u>", 3)) eina_strbuf_append(txt, "<u>");
|
||||
else if (!strncmp(text, "</u>", 4)) eina_strbuf_append(txt, "</u>");
|
||||
else if (!strncmp(text, "<a ", 3))
|
||||
{
|
||||
eina_strbuf_append(txt, "<link>");
|
||||
eina_strbuf_append_n(txt, text, taglen);
|
||||
}
|
||||
else if (!strncmp(text, "</a>", 3))
|
||||
{
|
||||
eina_strbuf_append(txt, "</a></link>");
|
||||
}
|
||||
else if (!strncmp(text, "<img src=", 9))
|
||||
{
|
||||
Evas_Object *o;
|
||||
int w = 0, h = 0;
|
||||
char *path;
|
||||
|
||||
text += advance;
|
||||
path = _path_get(text + 9);
|
||||
if ((path) && (strlen(path) > 0))
|
||||
{
|
||||
o = evas_object_image_add(e_comp->evas);
|
||||
evas_object_image_file_set(o, path, NULL);
|
||||
evas_object_image_size_get(o, &w, &h);
|
||||
printf("NOT: imgpath=%s %ix%i\n", path, w, h);
|
||||
if ((w > 0) && (h > 0))
|
||||
{
|
||||
double neww = w, newh = h;
|
||||
|
||||
if (neww > 200.0)
|
||||
{
|
||||
double oldw = neww;
|
||||
|
||||
neww = 200.0;
|
||||
newh = (newh * neww) / oldw;
|
||||
}
|
||||
if (newh > 100.0)
|
||||
{
|
||||
double oldh = newh;
|
||||
|
||||
newh = 100.0;
|
||||
neww = (neww * newh) / oldh;
|
||||
}
|
||||
neww *= e_scale;
|
||||
newh *= e_scale;
|
||||
w = neww + 0.5;
|
||||
h = newh + 0.5;
|
||||
eina_strbuf_append_printf
|
||||
(txt, "<item absize=%ix%i href=", w, h);
|
||||
eina_strbuf_append_n(txt, text + 9, taglen - 9);
|
||||
eina_strbuf_append(txt, "</item>");
|
||||
}
|
||||
evas_object_del(o);
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
text += taglen;
|
||||
}
|
||||
}
|
||||
|
||||
eina_array_free(arr);
|
||||
ret = eina_strbuf_string_steal(txt);
|
||||
printf("NOT: body -> [%s]\n", ret);
|
||||
eina_strbuf_free(txt);
|
||||
return ret;
|
||||
}
|
||||
|
@ -231,28 +415,30 @@ notify_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Messag
|
|||
E_Notification_Notify *n;
|
||||
Eldbus_Message_Iter *actions_iter, *hints_iter;
|
||||
Eldbus_Message *reply;
|
||||
char *txt;
|
||||
char *txt, *txt2;
|
||||
int num;
|
||||
|
||||
if (!n_data->notify_cb)
|
||||
return NULL;
|
||||
if (!n_data->notify_cb) return NULL;
|
||||
|
||||
n = E_OBJECT_ALLOC(E_Notification_Notify, E_NOTIFICATION_TYPE, _notification_free);
|
||||
n->urgency = E_NOTIFICATION_NOTIFY_URGENCY_NORMAL;
|
||||
if (!eldbus_message_arguments_get(msg, "susssasa{sv}i", &n->app_name,
|
||||
&n->replaces_id, &n->icon.icon, &n->summary,
|
||||
&n->body, &actions_iter, &hints_iter,
|
||||
&n->timeout))
|
||||
if (!eldbus_message_arguments_get(msg, "susssasa{sv}i",
|
||||
&n->app_name, &n->replaces_id,
|
||||
&n->icon.icon, &n->summary, &n->body,
|
||||
&actions_iter, &hints_iter, &n->timeout))
|
||||
{
|
||||
ERR("Reading message.");
|
||||
e_object_del(E_OBJECT(n));
|
||||
return NULL;
|
||||
}
|
||||
if (e_screensaver_on_get() && e_config->screensaver_wake_on_notify)
|
||||
{
|
||||
{ // XXX: this is an attempt to wake the screen? should be an option
|
||||
int x, y;
|
||||
|
||||
ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
|
||||
ecore_evas_pointer_warp(e_comp->ee, x, y);
|
||||
}
|
||||
// walk hints
|
||||
eldbus_message_iter_dict_iterate(hints_iter, "sv", hints_dict_iter, n);
|
||||
n->app_name = eina_stringshare_add(n->app_name);
|
||||
n->icon.icon = eina_stringshare_add(n->icon.icon);
|
||||
|
@ -261,22 +447,43 @@ notify_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Messag
|
|||
n->body = eina_stringshare_add(txt);
|
||||
free(txt);
|
||||
|
||||
num = 0;
|
||||
while (eldbus_message_iter_get_and_next(actions_iter, 's', &txt))
|
||||
{
|
||||
if (eldbus_message_iter_get_and_next(actions_iter, 's', &txt2))
|
||||
{ // XXX: add actions to notification
|
||||
E_Notification_Notify_Action *actions;
|
||||
|
||||
printf("NOT: act=[%s] [%s]\n", txt, txt2);
|
||||
num++;
|
||||
actions = realloc(n->actions, (num + 1) * sizeof(E_Notification_Notify));
|
||||
if (actions)
|
||||
{
|
||||
n->actions = actions;
|
||||
n->actions[num - 1].action = eina_stringshare_add(txt);
|
||||
n->actions[num - 1].label = eina_stringshare_add(txt2);
|
||||
n->actions[num].action = NULL;
|
||||
n->actions[num].label = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e_object_ref(E_OBJECT(n));
|
||||
n->id = n_data->notify_cb(n_data->data, n);
|
||||
reply = eldbus_message_method_return_new(msg);
|
||||
eldbus_message_arguments_append(reply, "u", n->id);
|
||||
e_object_unref(E_OBJECT(n));
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
close_notification_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
unsigned id;
|
||||
if (!eldbus_message_arguments_get(msg, "u", &id))
|
||||
return NULL;
|
||||
if (n_data->close_cb)
|
||||
n_data->close_cb(n_data->data, id);
|
||||
unsigned int id;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "u", &id)) return NULL;
|
||||
if (n_data->close_cb) n_data->close_cb(n_data->data, id);
|
||||
return eldbus_message_method_return_new(msg);
|
||||
}
|
||||
|
||||
|
@ -291,8 +498,10 @@ capabilities_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_
|
|||
eldbus_message_iter_arguments_append(main_iter, "as", &array);
|
||||
|
||||
for (i = 0; n_data->server_info->capabilities[i]; i++)
|
||||
eldbus_message_iter_arguments_append(array, "s",
|
||||
n_data->server_info->capabilities[i]);
|
||||
{
|
||||
eldbus_message_iter_arguments_append
|
||||
(array, "s", n_data->server_info->capabilities[i]);
|
||||
}
|
||||
eldbus_message_iter_container_close(main_iter, array);
|
||||
return reply;
|
||||
}
|
||||
|
@ -301,23 +510,32 @@ static Eldbus_Message *
|
|||
server_info_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
||||
eldbus_message_arguments_append(reply, "ssss", n_data->server_info->name,
|
||||
n_data->server_info->vendor,
|
||||
n_data->server_info->version,
|
||||
n_data->server_info->spec_version);
|
||||
eldbus_message_arguments_append(reply, "ssss",
|
||||
n_data->server_info->name,
|
||||
n_data->server_info->vendor,
|
||||
n_data->server_info->version,
|
||||
n_data->server_info->spec_version);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static const Eldbus_Method methods[] = {
|
||||
{ "Notify",
|
||||
ELDBUS_ARGS({"s", "app_name"}, {"u", "replaces_id"}, {"s", "app_icon"}, {"s", "summary"}, {"s", "body"}, {"as", "actions"}, {"a{sv}", "hints"}, {"i", "expire_timeout"}),
|
||||
ELDBUS_ARGS({"u", "id"}), notify_cb, 0 },
|
||||
{ "CloseNotification", ELDBUS_ARGS({"u", "id"}), NULL, close_notification_cb, 0 },
|
||||
{ "GetCapabilities", NULL, ELDBUS_ARGS({"as", "capabilities"}),
|
||||
capabilities_cb, 0 },
|
||||
{ "GetServerInformation", NULL,
|
||||
ELDBUS_ARGS({"s", "name"}, {"s", "vendor"}, {"s", "version"}, {"s", "spec_version"}),
|
||||
server_info_cb, 0 },
|
||||
ELDBUS_ARGS({"s", "app_name"}, {"u", "replaces_id"}, {"s", "app_icon"}, {"s", "summary"}, {"s", "body"}, {"as", "actions"}, {"a{sv}", "hints"}, {"i", "expire_timeout"}),
|
||||
ELDBUS_ARGS({"u", "id"}),
|
||||
notify_cb, 0 },
|
||||
{ "CloseNotification",
|
||||
ELDBUS_ARGS({"u", "id"}),
|
||||
NULL,
|
||||
close_notification_cb, 0 },
|
||||
{ "GetCapabilities",
|
||||
NULL,
|
||||
ELDBUS_ARGS({"as", "capabilities"}),
|
||||
capabilities_cb, 0 },
|
||||
{ "GetServerInformation",
|
||||
NULL,
|
||||
ELDBUS_ARGS({"s", "name"}, {"s", "vendor"}, {"s", "version"}, {"s", "spec_version"}),
|
||||
server_info_cb, 0 },
|
||||
|
||||
{ NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -332,6 +550,7 @@ static const Eldbus_Signal signals[] = {
|
|||
{ "NotificationClosed", ELDBUS_ARGS({"u", "id"}, {"u", "reason"}), 0 },
|
||||
[SIGNAL_ACTION_INVOKED] =
|
||||
{ "ActionInvoked", ELDBUS_ARGS({"u", "id"}, {"s", "action_key"}), 0 },
|
||||
|
||||
{ NULL, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -347,8 +566,8 @@ E_API Eina_Bool
|
|||
e_notification_server_register(const E_Notification_Server_Info *server_info, E_Notification_Notify_Cb n_cb, E_Notification_Close_Cb close_cb, const void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(server_info, EINA_FALSE);
|
||||
if (n_data)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (n_data) return EINA_FALSE;
|
||||
n_data = calloc(1, sizeof(Notification_Data));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(n_data, EINA_FALSE);
|
||||
|
||||
|
@ -359,8 +578,7 @@ e_notification_server_register(const E_Notification_Server_Info *server_info, E_
|
|||
n_data->data = (void *)data;
|
||||
n_data->server_info = server_info;
|
||||
eldbus_name_request(n_data->conn, BUS,
|
||||
ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING, NULL, NULL);
|
||||
|
||||
ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING, NULL, NULL);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -381,7 +599,17 @@ e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify
|
|||
EINA_SAFETY_ON_NULL_RETURN(notify);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(reason <= E_NOTIFICATION_NOTIFY_CLOSED_REASON_UNDEFINED);
|
||||
eldbus_service_signal_emit(n_data->iface, SIGNAL_NOTIFICATION_CLOSED,
|
||||
notify->id, reason);
|
||||
notify->id, reason);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_notification_notify_action(E_Notification_Notify *notify, const char *action)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(n_data);
|
||||
EINA_SAFETY_ON_NULL_RETURN(notify);
|
||||
if (!action) action = "";
|
||||
eldbus_service_signal_emit(n_data->iface, SIGNAL_ACTION_INVOKED,
|
||||
notify->id, action);
|
||||
}
|
||||
|
||||
E_API Evas_Object *
|
||||
|
@ -491,6 +719,7 @@ notification_client_dbus_send(E_Notification_Notify *notify, E_Notification_Clie
|
|||
{
|
||||
Eldbus_Message_Iter *st, *data_iter;
|
||||
int i;
|
||||
|
||||
eldbus_message_iter_arguments_append(hints, "{sv}", &entry);
|
||||
eldbus_message_iter_arguments_append(entry, "s", "image-data");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "(iiibiiay)");
|
||||
|
@ -533,8 +762,7 @@ notification_client_dbus_send(E_Notification_Notify *notify, E_Notification_Clie
|
|||
|
||||
p = eldbus_connection_send(conn, msg, client_notify_cb, data, 5000);
|
||||
EINA_SAFETY_ON_NULL_GOTO(p, error);
|
||||
if (cb)
|
||||
eldbus_pending_data_set(p, "cb", cb);
|
||||
if (cb) eldbus_pending_data_set(p, "cb", cb);
|
||||
eldbus_pending_data_set(p, "conn", conn);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
@ -547,8 +775,7 @@ error:
|
|||
static void
|
||||
normalize_notify(E_Notification_Notify *notify)
|
||||
{
|
||||
if (!notify->timeout)
|
||||
notify->timeout = -1;
|
||||
if (!notify->timeout) notify->timeout = -1;
|
||||
}
|
||||
|
||||
E_API Eina_Bool
|
||||
|
@ -562,11 +789,12 @@ e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_
|
|||
|
||||
if (!n_data)
|
||||
{
|
||||
fprintf(stderr, "UNHANDLED NOTIFICATION:\nSummary: %s\nBody: %s\n", notify->summary, notify->body);
|
||||
fprintf(stderr, "UNHANDLED NOTIFICATION:\nSummary: %s\nBody: %s\n",
|
||||
notify->summary, notify->body);
|
||||
return notification_client_dbus_send(notify, cb, data);
|
||||
}
|
||||
|
||||
//local
|
||||
// local
|
||||
copy = malloc(sizeof(E_Notification_Notify));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE);
|
||||
memcpy(copy, notify, sizeof(E_Notification_Notify));
|
||||
|
@ -579,8 +807,7 @@ e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_
|
|||
copy->icon.icon_path = eina_stringshare_add(notify->icon.icon_path);
|
||||
|
||||
id = n_data->notify_cb(n_data->data, copy);
|
||||
if (cb)
|
||||
cb((void *)data, id);
|
||||
if (cb) cb((void *)data, id);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,35 +7,39 @@
|
|||
|
||||
typedef enum _E_Notification_Notify_Urgency
|
||||
{
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_LOW,
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_NORMAL,
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_CRITICAL
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_LOW = 0,
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_NORMAL = 1,
|
||||
E_NOTIFICATION_NOTIFY_URGENCY_CRITICAL = 2
|
||||
} E_Notification_Notify_Urgency;
|
||||
|
||||
typedef enum _E_Notification_Notify_Closed_Reason
|
||||
{
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_EXPIRED, /** The notification expired. */
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_DISMISSED, /** The notification was dismissed by the user. */
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED, /** The notification was closed by a call to CloseNotification method. */
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_UNDEFINED /** Undefined/reserved reasons. */
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_EXPIRED = 1,
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_DISMISSED = 2,
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED = 3,
|
||||
E_NOTIFICATION_NOTIFY_CLOSED_REASON_UNDEFINED = 4
|
||||
} E_Notification_Notify_Closed_Reason;
|
||||
|
||||
typedef struct _E_Notification_Notify_Action
|
||||
{
|
||||
const char *action;
|
||||
const char *label;
|
||||
} E_Notification_Notify_Action;
|
||||
|
||||
typedef struct _E_Notification_Notify
|
||||
{
|
||||
E_Object e_obj_inherit;
|
||||
unsigned int id;
|
||||
const char *app_name;
|
||||
unsigned replaces_id;
|
||||
unsigned int replaces_id;
|
||||
const char *summary;
|
||||
const char *body;
|
||||
int timeout;
|
||||
int timeout; // time in ms
|
||||
E_Notification_Notify_Urgency urgency;
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char *icon;
|
||||
const char *icon_path;
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
int rowstride;
|
||||
|
@ -46,6 +50,17 @@ typedef struct _E_Notification_Notify
|
|||
int data_size;
|
||||
} raw;
|
||||
} icon;
|
||||
const char *category;
|
||||
const char *desktop_entry;
|
||||
const char *sound_file;
|
||||
const char *sound_name;
|
||||
int x, y;
|
||||
Eina_Bool have_xy;
|
||||
Eina_Bool icon_actions;
|
||||
Eina_Bool resident;
|
||||
Eina_Bool suppress_sound;
|
||||
Eina_Bool transient;
|
||||
E_Notification_Notify_Action *actions;
|
||||
} E_Notification_Notify;
|
||||
|
||||
typedef unsigned int (*E_Notification_Notify_Cb)(void *data, E_Notification_Notify *n);
|
||||
|
@ -80,7 +95,9 @@ E_API Evas_Object *e_notification_notify_raw_image_get(E_Notification_Notify *no
|
|||
|
||||
//client
|
||||
typedef void (*E_Notification_Client_Send_Cb)(void *data, unsigned int id);
|
||||
|
||||
E_API Eina_Bool e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data);
|
||||
E_API void e_notification_notify_action(E_Notification_Notify *notify, const char *action);
|
||||
E_API Eina_Bool e_notification_util_send(const char *summary, const char *body);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,11 +28,20 @@ _notification_notify(E_Notification_Notify *n)
|
|||
E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Notification"};
|
||||
|
||||
static const E_Notification_Server_Info server_info = {
|
||||
.name = "e17",
|
||||
.vendor = "enlightenment.org",
|
||||
.version = "0.17",
|
||||
.name = "Notification Service",
|
||||
.vendor = "Enlightenment",
|
||||
.version = PACKAGE_VERSION,
|
||||
.spec_version = "1.2",
|
||||
.capabilities = { "body", "body-markup", NULL }
|
||||
.capabilities = {
|
||||
"body", "body-markup",
|
||||
"body-hyperlinks", "body-images",
|
||||
"actions", "action-icons",
|
||||
// "icon-multi",
|
||||
// or
|
||||
// "icon-static",
|
||||
"persistence",
|
||||
// "sound",
|
||||
NULL }
|
||||
};
|
||||
|
||||
/* Callbacks */
|
||||
|
|
|
@ -31,34 +31,37 @@ typedef enum
|
|||
|
||||
struct _Config
|
||||
{
|
||||
E_Config_Dialog *cfd;
|
||||
E_Config_Dialog *cfd;
|
||||
|
||||
int version;
|
||||
int show_low;
|
||||
int show_normal;
|
||||
int show_critical;
|
||||
int force_timeout;
|
||||
int ignore_replacement;
|
||||
Popup_Display_Policy dual_screen;
|
||||
float timeout;
|
||||
Popup_Corner corner;
|
||||
int version;
|
||||
int show_low;
|
||||
int show_normal;
|
||||
int show_critical;
|
||||
int force_timeout;
|
||||
int ignore_replacement;
|
||||
Popup_Display_Policy dual_screen;
|
||||
float timeout;
|
||||
Popup_Corner corner;
|
||||
|
||||
Eina_List *popups;
|
||||
unsigned int next_id;
|
||||
Eina_List *popups;
|
||||
unsigned int next_id;
|
||||
};
|
||||
|
||||
struct _Popup_Data
|
||||
{
|
||||
unsigned id;
|
||||
E_Notification_Notify *notif;
|
||||
Evas_Object *win;
|
||||
Eina_List *mirrors;
|
||||
Evas *e;
|
||||
Evas_Object *theme;
|
||||
const char *app_name;
|
||||
Evas_Object *app_icon;
|
||||
Ecore_Timer *timer;
|
||||
Eina_Bool pending E_BITFIELD;
|
||||
unsigned id;
|
||||
E_Notification_Notify *notif;
|
||||
Evas_Object *win;
|
||||
Eina_List *mirrors;
|
||||
Evas *e;
|
||||
Evas_Object *theme;
|
||||
const char *app_name;
|
||||
Evas_Object *app_icon;
|
||||
Evas_Object *desktop_icon;
|
||||
Evas_Object *action_box;
|
||||
Eina_List *actions;
|
||||
Ecore_Timer *timer;
|
||||
Eina_Bool pending E_BITFIELD;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -239,6 +239,61 @@ _notification_theme_cb_find(Popup_Data *popup,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_notification_theme_cb_anchor(Popup_Data *popup EINA_UNUSED,
|
||||
Evas_Object *obj EINA_UNUSED,
|
||||
const char *emission,
|
||||
const char *source EINA_UNUSED)
|
||||
{
|
||||
if (!strncmp(emission, "anchor,mouse,clicked,1,",
|
||||
strlen("anchor,mouse,clicked,1,")))
|
||||
{
|
||||
const char *href = emission + strlen("anchor,mouse,clicked,1,");
|
||||
Eina_Strbuf *buf = eina_strbuf_new();
|
||||
|
||||
if (buf)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
eina_strbuf_append(buf, href);
|
||||
s = eina_strbuf_string_get(buf);
|
||||
if ((s) && (*s == '"'))
|
||||
{
|
||||
eina_strbuf_remove(buf, 0, 1);
|
||||
s = eina_strbuf_string_get(buf);
|
||||
if ((s) && (strlen(s) > 0) && (s[strlen(s) - 1] == '"'))
|
||||
eina_strbuf_replace_last(buf, "\"", "");
|
||||
}
|
||||
if ((s) && (*s == '\''))
|
||||
{
|
||||
eina_strbuf_remove(buf, 0, 1);
|
||||
s = eina_strbuf_string_get(buf);
|
||||
if ((s) && (strlen(s) > 0) && (s[strlen(s) - 1] == '\''))
|
||||
eina_strbuf_replace_last(buf, "'", "");
|
||||
}
|
||||
printf("NOT: clicked=[%s]\n", eina_strbuf_string_get(buf));
|
||||
e_util_open(eina_strbuf_string_get(buf), NULL);
|
||||
eina_strbuf_free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_notification_theme_cb_action(Popup_Data *popup,
|
||||
Evas_Object *obj,
|
||||
const char *emission EINA_UNUSED,
|
||||
const char *source EINA_UNUSED)
|
||||
{
|
||||
const char *action = evas_object_data_get(obj, "action");
|
||||
|
||||
if (action)
|
||||
{
|
||||
printf("NOT: action=[%s]\n", action);
|
||||
e_notification_notify_action(popup->notif, action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_notification_popup_place_coords_get(int zw, int zh, int ow, int oh, int pos, int *x, int *y)
|
||||
{
|
||||
|
@ -269,6 +324,22 @@ _notification_popup_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EIN
|
|||
popup->win = NULL;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_cb_item_provider(void *data, Evas_Object *obj EINA_UNUSED, const char *part, const char *item)
|
||||
{
|
||||
Popup_Data *popup = data;
|
||||
|
||||
printf("NOT: PROVIDER.... [%s] item: [%s]\n", part, item);
|
||||
// if (!strcmp(part, "notification.textblock.message"))
|
||||
{
|
||||
Evas_Object *o = e_icon_add(popup->e);
|
||||
|
||||
e_icon_file_set(o, item);
|
||||
return o;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Popup_Data *
|
||||
_notification_popup_new(E_Notification_Notify *n, unsigned id)
|
||||
{
|
||||
|
@ -307,6 +378,7 @@ _notification_popup_new(E_Notification_Notify *n, unsigned id)
|
|||
|
||||
/* Setup the theme */
|
||||
popup->theme = edje_object_add(popup->e);
|
||||
edje_object_item_provider_set(popup->theme, _cb_item_provider, popup);
|
||||
e_theme_edje_object_set(popup->theme,
|
||||
"base/theme/modules/notification",
|
||||
"e/modules/notification/main");
|
||||
|
@ -318,14 +390,17 @@ _notification_popup_new(E_Notification_Notify *n, unsigned id)
|
|||
evas_object_event_callback_add(popup->win, EVAS_CALLBACK_DEL, _notification_popup_del_cb, popup);
|
||||
|
||||
edje_object_signal_callback_add
|
||||
(popup->theme, "notification,deleted", "theme",
|
||||
(popup->theme, "notification,deleted", "*",
|
||||
(Edje_Signal_Cb)_notification_theme_cb_deleted, popup);
|
||||
edje_object_signal_callback_add
|
||||
(popup->theme, "notification,close", "theme",
|
||||
(popup->theme, "notification,close", "*",
|
||||
(Edje_Signal_Cb)_notification_theme_cb_close, popup);
|
||||
edje_object_signal_callback_add
|
||||
(popup->theme, "notification,find", "theme",
|
||||
(popup->theme, "notification,find", "*",
|
||||
(Edje_Signal_Cb)_notification_theme_cb_find, popup);
|
||||
edje_object_signal_callback_add
|
||||
(popup->theme, "anchor,mouse,clicked,1,*", "notification.textblock.message",
|
||||
(Edje_Signal_Cb)_notification_theme_cb_anchor, popup);
|
||||
|
||||
_notification_popup_refresh(popup);
|
||||
next_pos = _notification_popup_place(popup, next_pos);
|
||||
|
@ -386,17 +461,35 @@ _notification_popup_refresh(Popup_Data *popup)
|
|||
const char *app_icon_max;
|
||||
int w, h, width = 80, height = 80;
|
||||
E_Zone *zone;
|
||||
Evas_Object *o;
|
||||
|
||||
if (!popup) return;
|
||||
|
||||
popup->app_name = popup->notif->app_name;
|
||||
|
||||
EINA_LIST_FREE(popup->actions, o)
|
||||
{
|
||||
evas_object_del(o);
|
||||
}
|
||||
if (popup->action_box)
|
||||
{
|
||||
e_comp_object_util_del_list_remove(popup->win, popup->action_box);
|
||||
E_FREE_FUNC(popup->action_box, evas_object_del);
|
||||
edje_object_signal_emit(popup->theme, "e,state,actions,hide", "e");
|
||||
}
|
||||
|
||||
if (popup->app_icon)
|
||||
{
|
||||
e_comp_object_util_del_list_remove(popup->win, popup->app_icon);
|
||||
E_FREE_FUNC(popup->app_icon, evas_object_del);
|
||||
}
|
||||
|
||||
if (popup->desktop_icon)
|
||||
{
|
||||
e_comp_object_util_del_list_remove(popup->win, popup->desktop_icon);
|
||||
E_FREE_FUNC(popup->desktop_icon, evas_object_del);
|
||||
}
|
||||
|
||||
app_icon_max = edje_object_data_get(popup->theme, "app_icon_max");
|
||||
if (app_icon_max)
|
||||
{
|
||||
|
@ -452,7 +545,7 @@ _notification_popup_refresh(Popup_Data *popup)
|
|||
icon_path = new_path;
|
||||
else
|
||||
{
|
||||
Evas_Object *o = e_icon_add(popup->e);
|
||||
o = e_icon_add(popup->e);
|
||||
if (!e_util_icon_theme_set(o, icon_path))
|
||||
evas_object_del(o);
|
||||
else
|
||||
|
@ -510,12 +603,79 @@ _notification_popup_refresh(Popup_Data *popup)
|
|||
popup->app_icon);
|
||||
edje_object_signal_emit(popup->theme, "notification,icon", "notification");
|
||||
|
||||
if ((popup->notif->desktop_entry) &&
|
||||
(edje_object_part_exists(popup->theme, "notification.swallow.desktop_icon")))
|
||||
{
|
||||
Efreet_Desktop *desktop;
|
||||
unsigned int size;
|
||||
const char *icon_path;
|
||||
char buf[1024];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s.desktop", popup->notif->desktop_entry);
|
||||
desktop = efreet_util_desktop_file_id_find(buf);
|
||||
if ((desktop) && (desktop->icon))
|
||||
{
|
||||
size = e_util_icon_size_normalize(width * e_scale);
|
||||
icon_path = efreet_icon_path_find(e_config->icon_theme,
|
||||
desktop->icon, size);
|
||||
efreet_desktop_free(desktop);
|
||||
|
||||
o = e_icon_add(popup->e);
|
||||
if (!e_util_icon_theme_set(o, icon_path))
|
||||
evas_object_del(o);
|
||||
else
|
||||
{
|
||||
popup->desktop_icon = o;
|
||||
edje_object_part_swallow(popup->theme,
|
||||
"notification.swallow.desktop_icon",
|
||||
popup->desktop_icon);
|
||||
evas_object_show(o);
|
||||
e_comp_object_util_del_list_append(popup->win, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Fill up the event message */
|
||||
_notification_format_message(popup);
|
||||
|
||||
if (popup->notif->actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
o = popup->action_box = elm_box_add(e_comp->elm);
|
||||
elm_box_homogeneous_set(o, EINA_TRUE);
|
||||
elm_box_horizontal_set(o, EINA_TRUE);
|
||||
e_comp_object_util_del_list_append(popup->win, o);
|
||||
for (i = 0; popup->notif->actions[i].action; i++)
|
||||
{
|
||||
o = edje_object_add(popup->e);
|
||||
e_theme_edje_object_set(o,
|
||||
"base/theme/modules/notification",
|
||||
"e/modules/notification/action");
|
||||
evas_object_data_set(o, "action", popup->notif->actions[i].action);
|
||||
edje_object_part_text_unescaped_set(o, "e.text.label",
|
||||
popup->notif->actions[i].label);
|
||||
edje_object_signal_callback_add
|
||||
(o, "e,action,clicked", "e",
|
||||
(Edje_Signal_Cb)_notification_theme_cb_action, popup);
|
||||
edje_object_size_min_calc(o, &w, &h);
|
||||
evas_object_size_hint_min_set(o, w, h);
|
||||
printf("NOT: act %ix%i\n", w, h);
|
||||
elm_box_pack_end(popup->action_box, o);
|
||||
evas_object_show(o);
|
||||
}
|
||||
// evas_smart_objects_calculate(popup->e);
|
||||
// edje_message_signal_process();
|
||||
evas_smart_objects_calculate(popup->e);
|
||||
evas_object_size_hint_min_get(popup->action_box, &w, &h);
|
||||
printf("NOT: actbox %ix%i\n", w, h);
|
||||
edje_object_part_swallow(popup->theme, "notification.swallow.actions", popup->action_box);
|
||||
edje_object_signal_emit(popup->theme, "e,state,actions,show", "e");
|
||||
}
|
||||
|
||||
/* Compute the new size of the popup */
|
||||
edje_object_calc_force(popup->theme);
|
||||
edje_object_size_min_calc(popup->theme, &w, &h);
|
||||
printf("NOT: min %ix%i\n", w, h);
|
||||
if ((zone = e_comp_object_util_zone_get(popup->win)))
|
||||
{
|
||||
w = MIN(w, zone->w / 2);
|
||||
|
@ -585,13 +745,18 @@ _notification_format_message(Popup_Data *popup)
|
|||
{
|
||||
Evas_Object *o = popup->theme;
|
||||
Eina_Strbuf *buf = eina_strbuf_new();
|
||||
|
||||
printf("NOT: set message... [%s]\n", popup->notif->body);
|
||||
edje_object_part_text_unescaped_set(o, "notification.text.title",
|
||||
popup->notif->summary);
|
||||
popup->notif->summary);
|
||||
/* FIXME: Filter to only include allowed markup? */
|
||||
/* We need to replace \n with <ps/>. FIXME: We need to handle all the
|
||||
* newline kinds, and paragraph separator. ATM this will suffice. */
|
||||
eina_strbuf_append(buf, popup->notif->body);
|
||||
eina_strbuf_replace_all(buf, "\n", "<br/>");
|
||||
// message is thge shadow sizer part
|
||||
edje_object_part_text_set(o, "message",
|
||||
eina_strbuf_string_get(buf));
|
||||
edje_object_part_text_set(o, "notification.textblock.message",
|
||||
eina_strbuf_string_get(buf));
|
||||
eina_strbuf_free(buf);
|
||||
|
|
Loading…
Reference in New Issue