1 #include "e_mod_main.h"
3 /* Notification box protos */
4 static Notification_Box *_notification_box_new(const char *id,
6 static void _notification_box_free(Notification_Box *b);
7 static void _notification_box_evas_set(Notification_Box *b,
9 static void _notification_box_empty(Notification_Box *b);
10 static void _notification_box_resize_handle(Notification_Box *b);
11 static void _notification_box_empty_handle(Notification_Box *b);
12 static Eina_List *_notification_box_find(E_Notification_Urgency urgency);
14 /* Notification box icons protos */
15 static Notification_Box_Icon *_notification_box_icon_new(Notification_Box *b,
19 static void _notification_box_icon_free(Notification_Box_Icon *ic);
20 static void _notification_box_icon_fill(Notification_Box_Icon *ic,
22 static void _notification_box_icon_fill_label(Notification_Box_Icon *ic);
23 static void _notification_box_icon_empty(Notification_Box_Icon *ic);
24 static Notification_Box_Icon *_notification_box_icon_find(Notification_Box *b,
27 static void _notification_box_icon_signal_emit(Notification_Box_Icon *ic,
32 static E_Border *_notification_find_source_border(E_Notification *n);
34 /* Notification box callbacks */
35 static void _notification_box_cb_menu_post(void *data,
39 notification_box_notify(E_Notification *n,
40 unsigned int replaces_id,
46 Notification_Box_Icon *ic = NULL;
48 bd = _notification_find_source_border(n);
50 n_box = _notification_box_find(e_notification_hint_urgency_get(n));
51 EINA_LIST_FREE(n_box, b)
53 if (bd || replaces_id)
54 ic = _notification_box_icon_find(b, bd, replaces_id);
57 e_notification_unref(ic->notif);
58 e_notification_ref(n);
61 _notification_box_icon_empty(ic);
62 _notification_box_icon_fill(ic, n);
66 ic = _notification_box_icon_new(b, n, bd, id);
68 b->icons = eina_list_append(b->icons, ic);
69 e_box_pack_end(b->o_box, ic->o_holder);
71 _notification_box_empty_handle(b);
72 _notification_box_resize_handle(b);
73 _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
78 notification_box_shutdown(void)
82 EINA_LIST_FREE(notification_cfg->n_box, b)
84 if (b) _notification_box_free(b);
89 notification_box_del(const char *id)
95 EINA_LIST_FOREACH(notification_cfg->n_box, l, b)
99 _notification_box_free(b);
100 notification_cfg->n_box = eina_list_remove(notification_cfg->n_box, b);
107 notification_box_visible_set(Notification_Box *b, Eina_Bool visible)
110 Notification_Box_Icon *ic;
111 Ecore_Cb cb = (Ecore_Cb)(visible ? evas_object_show : evas_object_hide);
114 if (b->o_empty) cb(b->o_empty);
115 EINA_LIST_FOREACH(b->icons, l, ic)
126 notification_box_get(const char *id,
132 /* Find old config */
133 EINA_LIST_FOREACH(notification_cfg->n_box, l, b)
137 _notification_box_evas_set(b, evas);
138 notification_box_visible_set(b, EINA_TRUE);
143 b = _notification_box_new(id, evas);
144 notification_cfg->n_box = eina_list_append(notification_cfg->n_box, b);
149 notification_box_config_item_get(const char *id)
153 GADCON_CLIENT_CONFIG_GET(Config_Item, notification_cfg->items, _gc_class, id);
155 ci = E_NEW(Config_Item, 1);
156 ci->id = eina_stringshare_ref(id);
159 ci->focus_window = 1;
161 ci->store_normal = 1;
162 ci->store_critical = 0;
163 notification_cfg->items = eina_list_append(notification_cfg->items, ci);
169 notification_box_orient_set(Notification_Box *b,
172 e_box_orientation_set(b->o_box, horizontal);
173 e_box_align_set(b->o_box, 0.5, 0.5);
177 notification_box_cb_obj_moveresize(void *data,
179 Evas_Object *obj __UNUSED__,
180 void *event_info __UNUSED__)
185 _notification_box_resize_handle(inst->n_box);
189 notification_box_cb_border_remove(void *data __UNUSED__,
191 E_Event_Border_Remove *ev)
193 Notification_Box_Icon *ic;
197 EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
204 ic = _notification_box_icon_find(b, ev->border, 0);
206 b->icons = eina_list_remove(b->icons, ic);
207 _notification_box_icon_free(ic);
208 _notification_box_empty_handle(b);
209 _notification_box_resize_handle(b);
210 _gc_orient(inst->gcc, inst->gcc->gadcon->orient);
212 return ECORE_CALLBACK_RENEW;
215 static Notification_Box *
216 _notification_box_new(const char *id,
221 b = E_NEW(Notification_Box, 1);
222 b->id = eina_stringshare_ref(id);
223 b->o_box = e_box_add(evas);
224 e_box_homogenous_set(b->o_box, 1);
225 e_box_orientation_set(b->o_box, 1);
226 e_box_align_set(b->o_box, 0.5, 0.5);
227 _notification_box_empty(b);
232 _notification_box_free(Notification_Box *b)
234 _notification_box_empty(b);
235 eina_stringshare_del(b->id);
236 evas_object_del(b->o_box);
237 if (b->o_empty) evas_object_del(b->o_empty);
243 _notification_box_evas_set(Notification_Box *b,
246 Eina_List *new_icons = NULL;
247 Notification_Box_Icon *ic, *new_ic;
249 evas_object_del(b->o_box);
250 if (b->o_empty) evas_object_del(b->o_empty);
252 b->o_box = e_box_add(evas);
254 e_box_homogenous_set(b->o_box, 1);
255 e_box_orientation_set(b->o_box, 1);
256 e_box_align_set(b->o_box, 0.5, 0.5);
258 EINA_LIST_FREE(b->icons, ic)
262 new_ic = _notification_box_icon_new(b, ic->notif, ic->border, ic->n_id);
263 _notification_box_icon_free(ic);
264 new_icons = eina_list_append(new_icons, new_ic);
266 e_box_pack_end(b->o_box, new_ic->o_holder);
268 b->icons = new_icons;
269 _notification_box_empty_handle(b);
270 _notification_box_resize_handle(b);
274 _notification_box_empty(Notification_Box *b)
276 Notification_Box_Icon *ic;
277 EINA_LIST_FREE(b->icons, ic)
278 _notification_box_icon_free(b->icons->data);
279 _notification_box_empty_handle(b);
283 _notification_box_resize_handle(Notification_Box *b)
285 Notification_Box_Icon *ic;
288 evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
289 if (e_box_orientation_get(b->o_box))
293 e_box_freeze(b->o_box);
294 EINA_LIST_FREE(b->icons, ic)
295 e_box_pack_options_set(ic->o_holder, 1, 1, 0, 0, 0.5, 0.5, w, h, w, h);
296 e_box_thaw(b->o_box);
300 _notification_box_find(E_Notification_Urgency urgency)
302 Eina_List *l, *n_box = NULL;
305 EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
307 if ((urgency == E_NOTIFICATION_URGENCY_LOW) && (!inst->ci->store_low))
309 if ((urgency == E_NOTIFICATION_URGENCY_NORMAL) && (!inst->ci->store_normal))
311 if ((urgency == E_NOTIFICATION_URGENCY_CRITICAL) && (!inst->ci->store_critical))
313 n_box = eina_list_append(n_box, inst->n_box);
319 _notification_box_icon_free(Notification_Box_Icon *ic)
321 if (notification_cfg->menu)
323 e_menu_post_deactivate_callback_set(notification_cfg->menu, NULL, NULL);
324 e_object_del(E_OBJECT(notification_cfg->menu));
325 notification_cfg->menu = NULL;
327 _notification_box_icon_empty(ic);
328 evas_object_del(ic->o_holder);
329 evas_object_del(ic->o_holder2);
330 if (ic->border) e_object_unref(E_OBJECT(ic->border));
331 if (ic->notif) e_notification_unref(ic->notif);
336 _notification_box_icon_fill(Notification_Box_Icon *ic,
340 const char *icon_path;
341 Evas_Object *app_icon;
342 Evas_Object *dummy = NULL;
345 if ((icon_path = e_notification_app_icon_get(n)) && *icon_path)
347 if (!memcmp(icon_path, "file://", 7)) icon_path += 7;
348 app_icon = evas_object_image_add(evas_object_evas_get(ic->n_box->o_box));
349 evas_object_image_load_scale_down_set(app_icon, 1);
350 evas_object_image_load_size_set(app_icon, 80, 80);
351 evas_object_image_file_set(app_icon, icon_path, NULL);
352 evas_object_image_fill_set(app_icon, 0, 0, 80, 80);
354 else if ((img = e_notification_hint_icon_data_get(n)))
356 app_icon = e_notification_image_evas_object_add(evas_object_evas_get(ic->n_box->o_box), img);
362 snprintf(buf, sizeof(buf), "%s/e-module-notification.edj", notification_mod->dir);
363 dummy = edje_object_add(evas_object_evas_get(ic->n_box->o_box));
364 if (!e_theme_edje_object_set(dummy, "base/theme/modules/notification",
365 "modules/notification/logo"))
366 edje_object_file_set(dummy, buf, "modules/notification/logo");
367 evas_object_resize(dummy, 80, 80);
368 app_icon = (Evas_Object*)edje_object_part_object_get(dummy, "image");
370 evas_object_image_size_get(app_icon, &w, &h);
372 ic->o_icon = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
373 e_icon_alpha_set(ic->o_icon, 1);
374 e_icon_data_set(ic->o_icon, evas_object_image_data_get(app_icon, 0), w, h);
375 edje_object_part_swallow(ic->o_holder, "e.swallow.content", ic->o_icon);
376 evas_object_pass_events_set(ic->o_icon, 1);
377 evas_object_show(ic->o_icon);
379 ic->o_icon2 = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
380 e_icon_alpha_set(ic->o_icon2, 1);
381 e_icon_data_set(ic->o_icon2, evas_object_image_data_get(app_icon, 0), w, h);
382 edje_object_part_swallow(ic->o_holder2, "e.swallow.content", ic->o_icon2);
383 evas_object_pass_events_set(ic->o_icon2, 1);
384 evas_object_show(ic->o_icon2);
386 if (dummy) evas_object_del(dummy);
387 evas_object_del(app_icon);
388 _notification_box_icon_fill_label(ic);
392 _notification_box_icon_fill_label(Notification_Box_Icon *ic)
394 const char *label = NULL;
397 label = ic->border->client.netwm.name;
399 if (!label) label = e_notification_app_name_get(ic->notif);
400 edje_object_part_text_set(ic->o_holder, "e.text.label", label);
401 edje_object_part_text_set(ic->o_holder2, "e.text.label", label);
405 _notification_box_icon_empty(Notification_Box_Icon *ic)
407 if (ic->o_icon) evas_object_del(ic->o_icon);
408 if (ic->o_icon2) evas_object_del(ic->o_icon2);
409 ic->o_icon2 = ic->o_icon = NULL;
412 static Notification_Box_Icon *
413 _notification_box_icon_find(Notification_Box *b,
418 Notification_Box_Icon *ic;
420 EINA_LIST_FOREACH(b->icons, l, ic)
423 if ((ic->border == bd) || (ic->n_id == n_id))
431 _notification_box_icon_signal_emit(Notification_Box_Icon *ic,
436 edje_object_signal_emit(ic->o_holder, sig, src);
438 edje_object_signal_emit(ic->o_icon, sig, src);
440 edje_object_signal_emit(ic->o_holder2, sig, src);
442 edje_object_signal_emit(ic->o_icon2, sig, src);
446 _notification_find_source_border(E_Notification *n)
448 const char *app_name;
452 if (!(app_name = e_notification_app_name_get(n))) return NULL;
454 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
458 if ((!bd) || ((!bd->client.icccm.name) && (!bd->client.icccm.class))) continue;
459 /* We can't be sure that the app_name really match the application name.
460 * Some plugin put their name instead. But this search gives some good
463 app = strlen(app_name);
464 if (bd->client.icccm.name)
466 test = eina_strlen_bounded(bd->client.icccm.name, app + 1);
467 if (!strncasecmp(bd->client.icccm.name, app_name, (app < test) ? app : test))
470 if (bd->client.icccm.class)
472 test = eina_strlen_bounded(bd->client.icccm.class, app + 1);
473 if (!strncasecmp(bd->client.icccm.class, app_name, (app < test) ? app : test))
481 _notification_box_cb_menu_post(void *data __UNUSED__,
482 E_Menu *m __UNUSED__)
484 if (!notification_cfg->menu) return;
485 e_object_del(E_OBJECT(notification_cfg->menu));
486 notification_cfg->menu = NULL;
490 _notification_box_cb_menu_configuration(Notification_Box *b,
491 E_Menu *m __UNUSED__,
492 E_Menu_Item *mi __UNUSED__)
495 E_Config_Dialog *cfd;
497 EINA_LIST_FOREACH(notification_cfg->config_dialog, l, cfd)
499 if (cfd->data == b->inst->ci) return;
501 config_notification_box_module(b->inst->ci);
505 _notification_box_cb_empty_mouse_down(Notification_Box *b,
507 Evas_Object *obj __UNUSED__,
508 Evas_Event_Mouse_Down *ev)
514 if (notification_cfg->menu) return;
516 mi = e_menu_item_new(m);
517 e_menu_item_label_set(mi, _("Settings"));
518 e_util_menu_item_theme_icon_set(mi, "preferences-system");
519 e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, b);
521 notification_cfg->menu = m = e_gadcon_client_util_menu_items_append(b->inst->gcc, m, 0);
522 e_menu_post_deactivate_callback_set(m, _notification_box_cb_menu_post, NULL);
524 e_gadcon_canvas_zone_geometry_get(b->inst->gcc->gadcon,
526 e_menu_activate_mouse(m,
527 e_util_zone_current_get(e_manager_current_get()),
528 cx + ev->output.x, cy + ev->output.y, 1, 1,
529 E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
533 _notification_box_cb_icon_move(Notification_Box_Icon *ic,
535 Evas_Object *obj __UNUSED__,
536 void *event_info __UNUSED__)
540 evas_object_geometry_get(ic->o_holder, &x, &y, NULL, NULL);
541 evas_object_move(ic->o_holder2, x, y);
542 evas_object_raise(ic->o_holder2);
546 _notification_box_cb_icon_resize(Notification_Box_Icon *ic,
548 Evas_Object *obj __UNUSED__,
549 void *event_info __UNUSED__)
553 evas_object_geometry_get(ic->o_holder, NULL, NULL, &w, &h);
554 evas_object_resize(ic->o_holder2, w, h);
555 evas_object_raise(ic->o_holder2);
560 _notification_box_cb_icon_mouse_still_in(Notification_Box_Icon *ic)
562 e_notification_timeout_set(ic->notif, 0);
563 e_notification_hint_urgency_set(ic->notif, 4);
564 ic->popup = notification_popup_notify(ic->notif,
565 e_notification_id_get(ic->notif),
566 e_notification_app_name_get(ic->notif));
567 ecore_timer_del(ic->mouse_in_timer);
568 ic->mouse_in_timer = NULL;
574 _notification_box_cb_icon_mouse_in(Notification_Box_Icon *ic,
576 Evas_Object *obj __UNUSED__,
577 void *event_info __UNUSED__)
581 if ((!ic) || !ic->n_box || !ic->n_box->inst) return;
582 if (!(ci = ic->n_box->inst->ci)) return;
584 _notification_box_icon_signal_emit(ic, "e,state,focused", "e");
587 _notification_box_icon_fill_label(ic);
588 _notification_box_icon_signal_emit(ic, "e,action,show,label", "e");
590 if (ci->show_popup && !ic->popup && !ic->mouse_in_timer)
591 ic->mouse_in_timer = ecore_timer_add(0.5, (Ecore_Task_Cb)_notification_box_cb_icon_mouse_still_in, ic);
595 _notification_box_cb_icon_mouse_out(Notification_Box_Icon *ic,
597 Evas_Object *obj __UNUSED__,
598 void *event_info __UNUSED__)
600 _notification_box_icon_signal_emit(ic, "e,state,unfocused", "e");
601 if (ic->n_box->inst->ci->show_label)
602 _notification_box_icon_signal_emit(ic, "e,action,hide,label", "e");
604 if (ic->mouse_in_timer)
606 ecore_timer_del(ic->mouse_in_timer);
607 ic->mouse_in_timer = NULL;
611 notification_popup_close(e_notification_id_get(ic->notif));
617 _notification_box_cb_icon_mouse_up(Notification_Box_Icon *ic,
619 Evas_Object *obj __UNUSED__,
620 Evas_Event_Mouse_Up *ev)
625 if (ev->button != 1) return;
627 if (b->inst->ci->focus_window && ic->border)
629 e_border_uniconify(ic->border);
630 e_desk_show(ic->border->desk);
631 e_border_show(ic->border);
632 e_border_raise(ic->border);
633 e_border_focus_set(ic->border, 1, 1);
635 b->icons = eina_list_remove(b->icons, ic);
636 _notification_box_icon_free(ic);
637 _notification_box_empty_handle(b);
638 _notification_box_resize_handle(b);
639 _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
643 _notification_box_cb_icon_mouse_down(Notification_Box_Icon *ic,
645 Evas_Object *obj __UNUSED__,
646 Evas_Event_Mouse_Down *ev)
652 if (notification_cfg->menu || (ev->button != 3)) return;
655 mi = e_menu_item_new(m);
656 e_menu_item_label_set(mi, _("Settings"));
657 e_util_menu_item_theme_icon_set(mi, "preferences-system");
658 e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, ic->n_box);
660 m = e_gadcon_client_util_menu_items_append(ic->n_box->inst->gcc, m, 0);
661 e_menu_post_deactivate_callback_set(m, _notification_box_cb_menu_post, NULL);
662 notification_cfg->menu = m;
664 e_gadcon_canvas_zone_geometry_get(ic->n_box->inst->gcc->gadcon,
666 e_menu_activate_mouse(m,
667 e_util_zone_current_get(e_manager_current_get()),
668 cx + ev->output.x, cy + ev->output.y, 1, 1,
669 E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
673 _notification_box_empty_handle(Notification_Box *b)
678 if (b->o_empty) return;
680 b->o_empty = evas_object_rectangle_add(evas_object_evas_get(b->o_box));
681 evas_object_event_callback_add(b->o_empty, EVAS_CALLBACK_MOUSE_DOWN,
682 (Evas_Object_Event_Cb)_notification_box_cb_empty_mouse_down, b);
683 evas_object_color_set(b->o_empty, 0, 0, 0, 0);
684 evas_object_show(b->o_empty);
685 e_box_pack_end(b->o_box, b->o_empty);
686 evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
687 if (e_box_orientation_get(b->o_box))
691 e_box_pack_options_set(b->o_empty,
694 0.5, 0.5, /* align */
701 evas_object_del(b->o_empty);
706 static Notification_Box_Icon *
707 _notification_box_icon_new(Notification_Box *b,
712 Notification_Box_Icon *ic;
714 ic = E_NEW(Notification_Box_Icon, 1);
715 if (bd) e_object_ref(E_OBJECT(bd));
716 e_notification_ref(n);
717 ic->label = e_notification_app_name_get(n);
722 ic->o_holder = edje_object_add(evas_object_evas_get(b->o_box));
723 e_theme_edje_object_set(ic->o_holder, "base/theme/modules/ibox",
724 "e/modules/ibox/icon");
725 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_IN,
726 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_in, ic);
727 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_OUT,
728 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_out, ic);
729 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_DOWN,
730 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_down, ic);
731 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_UP,
732 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_up, ic);
733 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOVE,
734 (Evas_Object_Event_Cb)_notification_box_cb_icon_move, ic);
735 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_RESIZE,
736 (Evas_Object_Event_Cb)_notification_box_cb_icon_resize, ic);
737 evas_object_show(ic->o_holder);
739 ic->o_holder2 = edje_object_add(evas_object_evas_get(b->o_box));
740 e_theme_edje_object_set(ic->o_holder2, "base/theme/modules/ibox",
741 "e/modules/ibox/icon_overlay");
742 evas_object_layer_set(ic->o_holder2, 9999);
743 evas_object_pass_events_set(ic->o_holder2, 1);
744 evas_object_show(ic->o_holder2);
746 _notification_box_icon_fill(ic, n);