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 */
36 notification_box_notify(E_Notification *n,
37 unsigned int replaces_id,
43 Notification_Box_Icon *ic = NULL;
45 bd = _notification_find_source_border(n);
47 n_box = _notification_box_find(e_notification_hint_urgency_get(n));
48 EINA_LIST_FREE(n_box, b)
50 if (bd || replaces_id)
51 ic = _notification_box_icon_find(b, bd, replaces_id);
54 e_notification_unref(ic->notif);
55 e_notification_ref(n);
58 _notification_box_icon_empty(ic);
59 _notification_box_icon_fill(ic, n);
63 ic = _notification_box_icon_new(b, n, bd, id);
65 b->icons = eina_list_append(b->icons, ic);
66 e_box_pack_end(b->o_box, ic->o_holder);
68 _notification_box_empty_handle(b);
69 _notification_box_resize_handle(b);
70 _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
75 notification_box_shutdown(void)
79 EINA_LIST_FREE(notification_cfg->n_box, b)
81 if (b) _notification_box_free(b);
86 notification_box_visible_set(Notification_Box *b, Eina_Bool visible)
89 Notification_Box_Icon *ic;
90 Ecore_Cb cb = (Ecore_Cb)(visible ? evas_object_show : evas_object_hide);
92 if (b->o_box) cb(b->o_box);
93 if (b->o_empty) cb(b->o_empty);
94 EINA_LIST_FOREACH(b->icons, l, ic)
105 notification_box_get(const char *id,
111 /* Find old config */
112 EINA_LIST_FOREACH(notification_cfg->n_box, l, b)
116 _notification_box_evas_set(b, evas);
117 notification_box_visible_set(b, EINA_TRUE);
122 b = _notification_box_new(id, evas);
123 notification_cfg->n_box = eina_list_append(notification_cfg->n_box, b);
128 notification_box_config_item_get(const char *id)
132 GADCON_CLIENT_CONFIG_GET(Config_Item, notification_cfg->items, _gc_class, id);
134 ci = E_NEW(Config_Item, 1);
135 ci->id = eina_stringshare_add(id);
138 ci->focus_window = 1;
140 ci->store_normal = 1;
141 ci->store_critical = 0;
142 notification_cfg->items = eina_list_append(notification_cfg->items, ci);
148 notification_box_orient_set(Notification_Box *b,
151 e_box_orientation_set(b->o_box, horizontal);
152 e_box_align_set(b->o_box, 0.5, 0.5);
156 notification_box_cb_obj_moveresize(void *data,
158 Evas_Object *obj __UNUSED__,
159 void *event_info __UNUSED__)
164 _notification_box_resize_handle(inst->n_box);
168 notification_box_cb_border_remove(void *data __UNUSED__,
170 E_Event_Border_Remove *ev)
172 Notification_Box_Icon *ic;
176 EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
183 ic = _notification_box_icon_find(b, ev->border, 0);
185 b->icons = eina_list_remove(b->icons, ic);
186 _notification_box_icon_free(ic);
187 _notification_box_empty_handle(b);
188 _notification_box_resize_handle(b);
189 _gc_orient(inst->gcc, inst->gcc->gadcon->orient);
191 return ECORE_CALLBACK_RENEW;
194 static Notification_Box *
195 _notification_box_new(const char *id,
200 b = E_NEW(Notification_Box, 1);
201 b->id = eina_stringshare_ref(id);
202 b->o_box = e_box_add(evas);
203 e_box_homogenous_set(b->o_box, 1);
204 e_box_orientation_set(b->o_box, 1);
205 e_box_align_set(b->o_box, 0.5, 0.5);
206 _notification_box_empty(b);
211 _notification_box_free(Notification_Box *b)
213 _notification_box_empty(b);
214 eina_stringshare_del(b->id);
219 _notification_box_evas_set(Notification_Box *b,
222 Eina_List *new_icons = NULL;
223 Notification_Box_Icon *ic, *new_ic;
225 if (b->o_box) evas_object_del(b->o_box);
226 if (b->o_empty) evas_object_del(b->o_empty);
228 b->o_box = e_box_add(evas);
230 e_box_homogenous_set(b->o_box, 1);
231 e_box_orientation_set(b->o_box, 1);
232 e_box_align_set(b->o_box, 0.5, 0.5);
234 EINA_LIST_FREE(b->icons, ic)
238 new_ic = _notification_box_icon_new(b, ic->notif, ic->border, ic->n_id);
239 _notification_box_icon_free(ic);
240 new_icons = eina_list_append(new_icons, new_ic);
242 e_box_pack_end(b->o_box, new_ic->o_holder);
244 b->icons = new_icons;
245 _notification_box_empty_handle(b);
246 _notification_box_resize_handle(b);
250 _notification_box_empty(Notification_Box *b)
252 Notification_Box_Icon *ic;
253 EINA_LIST_FREE(b->icons, ic)
254 _notification_box_icon_free(ic);
255 _notification_box_empty_handle(b);
259 _notification_box_resize_handle(Notification_Box *b)
261 Notification_Box_Icon *ic;
264 evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
265 if (e_box_orientation_get(b->o_box))
269 e_box_freeze(b->o_box);
270 EINA_LIST_FREE(b->icons, ic)
271 e_box_pack_options_set(ic->o_holder, 1, 1, 0, 0, 0.5, 0.5, w, h, w, h);
272 e_box_thaw(b->o_box);
276 _notification_box_find(E_Notification_Urgency urgency)
278 Eina_List *l, *n_box = NULL;
281 EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
283 if ((urgency == E_NOTIFICATION_URGENCY_LOW) && (!inst->ci->store_low))
285 if ((urgency == E_NOTIFICATION_URGENCY_NORMAL) && (!inst->ci->store_normal))
287 if ((urgency == E_NOTIFICATION_URGENCY_CRITICAL) && (!inst->ci->store_critical))
289 n_box = eina_list_append(n_box, inst->n_box);
295 _notification_box_icon_free(Notification_Box_Icon *ic)
297 _notification_box_icon_empty(ic);
298 evas_object_del(ic->o_holder);
299 evas_object_del(ic->o_holder2);
300 if (ic->border) e_object_unref(E_OBJECT(ic->border));
301 if (ic->notif) e_notification_unref(ic->notif);
306 _notification_box_icon_fill(Notification_Box_Icon *ic,
310 const char *icon_path;
311 Evas_Object *app_icon;
312 Evas_Object *dummy = NULL;
315 if ((icon_path = e_notification_app_icon_get(n)) && *icon_path)
317 if (!memcmp(icon_path, "file://", 7)) icon_path += 7;
318 app_icon = evas_object_image_add(evas_object_evas_get(ic->n_box->o_box));
319 evas_object_image_load_scale_down_set(app_icon, 1);
320 evas_object_image_load_size_set(app_icon, 80, 80);
321 evas_object_image_file_set(app_icon, icon_path, NULL);
322 evas_object_image_fill_set(app_icon, 0, 0, 80, 80);
324 else if ((img = e_notification_hint_icon_data_get(n)))
326 app_icon = e_notification_image_evas_object_add(evas_object_evas_get(ic->n_box->o_box), img);
332 snprintf(buf, sizeof(buf), "%s/e-module-notification.edj", notification_mod->dir);
333 dummy = edje_object_add(evas_object_evas_get(ic->n_box->o_box));
334 if (!e_theme_edje_object_set(dummy, "base/theme/modules/notification",
335 "modules/notification/logo"))
336 edje_object_file_set(dummy, buf, "modules/notification/logo");
337 evas_object_resize(dummy, 80, 80);
338 app_icon = (Evas_Object*)edje_object_part_object_get(dummy, "image");
340 evas_object_image_size_get(app_icon, &w, &h);
342 ic->o_icon = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
343 e_icon_alpha_set(ic->o_icon, 1);
344 e_icon_data_set(ic->o_icon, evas_object_image_data_get(app_icon, 0), w, h);
345 edje_object_part_swallow(ic->o_holder, "e.swallow.content", ic->o_icon);
346 evas_object_pass_events_set(ic->o_icon, 1);
347 evas_object_show(ic->o_icon);
349 ic->o_icon2 = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
350 e_icon_alpha_set(ic->o_icon2, 1);
351 e_icon_data_set(ic->o_icon2, evas_object_image_data_get(app_icon, 0), w, h);
352 edje_object_part_swallow(ic->o_holder2, "e.swallow.content", ic->o_icon2);
353 evas_object_pass_events_set(ic->o_icon2, 1);
354 evas_object_show(ic->o_icon2);
356 if (dummy) evas_object_del(dummy);
357 evas_object_del(app_icon);
358 _notification_box_icon_fill_label(ic);
362 _notification_box_icon_fill_label(Notification_Box_Icon *ic)
364 const char *label = NULL;
367 label = ic->border->client.netwm.name;
369 if (!label) label = e_notification_app_name_get(ic->notif);
370 edje_object_part_text_set(ic->o_holder, "e.text.label", label);
371 edje_object_part_text_set(ic->o_holder2, "e.text.label", label);
375 _notification_box_icon_empty(Notification_Box_Icon *ic)
377 if (ic->o_icon) evas_object_del(ic->o_icon);
378 if (ic->o_icon2) evas_object_del(ic->o_icon2);
379 ic->o_icon2 = ic->o_icon = NULL;
382 static Notification_Box_Icon *
383 _notification_box_icon_find(Notification_Box *b,
388 Notification_Box_Icon *ic;
390 EINA_LIST_FOREACH(b->icons, l, ic)
393 if ((ic->border == bd) || (ic->n_id == n_id))
401 _notification_box_icon_signal_emit(Notification_Box_Icon *ic,
406 edje_object_signal_emit(ic->o_holder, sig, src);
408 edje_object_signal_emit(ic->o_icon, sig, src);
410 edje_object_signal_emit(ic->o_holder2, sig, src);
412 edje_object_signal_emit(ic->o_icon2, sig, src);
416 _notification_find_source_border(E_Notification *n)
418 const char *app_name;
422 if (!(app_name = e_notification_app_name_get(n))) return NULL;
424 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
428 if ((!bd) || ((!bd->client.icccm.name) && (!bd->client.icccm.class))) continue;
429 /* We can't be sure that the app_name really match the application name.
430 * Some plugin put their name instead. But this search gives some good
433 app = strlen(app_name);
434 if (bd->client.icccm.name)
436 test = eina_strlen_bounded(bd->client.icccm.name, app + 1);
437 if (!strncasecmp(bd->client.icccm.name, app_name, (app < test) ? app : test))
440 if (bd->client.icccm.class)
442 test = eina_strlen_bounded(bd->client.icccm.class, app + 1);
443 if (!strncasecmp(bd->client.icccm.class, app_name, (app < test) ? app : test))
451 _notification_box_cb_menu_configuration(Notification_Box *b,
452 E_Menu *m __UNUSED__,
453 E_Menu_Item *mi __UNUSED__)
456 E_Config_Dialog *cfd;
458 EINA_LIST_FOREACH(notification_cfg->config_dialog, l, cfd)
460 if (cfd->data == b->inst->ci) return;
462 config_notification_box_module(b->inst->ci);
466 _notification_box_cb_empty_mouse_down(Notification_Box *b,
468 Evas_Object *obj __UNUSED__,
469 Evas_Event_Mouse_Down *ev)
476 mi = e_menu_item_new(m);
477 e_menu_item_label_set(mi, _("Settings"));
478 e_util_menu_item_theme_icon_set(mi, "preferences-system");
479 e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, b);
481 m = e_gadcon_client_util_menu_items_append(b->inst->gcc, m, 0);
482 e_gadcon_canvas_zone_geometry_get(b->inst->gcc->gadcon,
484 e_menu_activate_mouse(m,
485 e_util_zone_current_get(e_manager_current_get()),
486 cx + ev->output.x, cy + ev->output.y, 1, 1,
487 E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
488 evas_event_feed_mouse_up(b->inst->gcc->gadcon->evas, ev->button,
489 EVAS_BUTTON_NONE, ev->timestamp, NULL);
493 _notification_box_cb_icon_move(Notification_Box_Icon *ic,
495 Evas_Object *obj __UNUSED__,
496 void *event_info __UNUSED__)
500 evas_object_geometry_get(ic->o_holder, &x, &y, NULL, NULL);
501 evas_object_move(ic->o_holder2, x, y);
502 evas_object_raise(ic->o_holder2);
506 _notification_box_cb_icon_resize(Notification_Box_Icon *ic,
508 Evas_Object *obj __UNUSED__,
509 void *event_info __UNUSED__)
513 evas_object_geometry_get(ic->o_holder, NULL, NULL, &w, &h);
514 evas_object_resize(ic->o_holder2, w, h);
515 evas_object_raise(ic->o_holder2);
520 _notification_box_cb_icon_mouse_still_in(Notification_Box_Icon *ic)
522 e_notification_timeout_set(ic->notif, 0);
523 e_notification_hint_urgency_set(ic->notif, 4);
524 ic->popup = notification_popup_notify(ic->notif,
525 e_notification_id_get(ic->notif),
526 e_notification_app_name_get(ic->notif));
527 ecore_timer_del(ic->mouse_in_timer);
528 ic->mouse_in_timer = NULL;
534 _notification_box_cb_icon_mouse_in(Notification_Box_Icon *ic,
536 Evas_Object *obj __UNUSED__,
537 void *event_info __UNUSED__)
541 if ((!ic) || !ic->n_box || !ic->n_box->inst) return;
542 if (!(ci = ic->n_box->inst->ci)) return;
544 _notification_box_icon_signal_emit(ic, "e,state,focused", "e");
547 _notification_box_icon_fill_label(ic);
548 _notification_box_icon_signal_emit(ic, "e,action,show,label", "e");
550 if (ci->show_popup && !ic->popup && !ic->mouse_in_timer)
551 ic->mouse_in_timer = ecore_timer_add(0.5, (Ecore_Task_Cb)_notification_box_cb_icon_mouse_still_in, ic);
555 _notification_box_cb_icon_mouse_out(Notification_Box_Icon *ic,
557 Evas_Object *obj __UNUSED__,
558 void *event_info __UNUSED__)
560 _notification_box_icon_signal_emit(ic, "e,state,unfocused", "e");
561 if (ic->n_box->inst->ci->show_label)
562 _notification_box_icon_signal_emit(ic, "e,action,hide,label", "e");
564 if (ic->mouse_in_timer)
566 ecore_timer_del(ic->mouse_in_timer);
567 ic->mouse_in_timer = NULL;
571 notification_popup_close(e_notification_id_get(ic->notif));
577 _notification_box_cb_icon_mouse_up(Notification_Box_Icon *ic,
579 Evas_Object *obj __UNUSED__,
580 Evas_Event_Mouse_Up *ev)
585 if (ev->button != 1) return;
587 if (b->inst->ci->focus_window && ic->border)
589 e_border_uniconify(ic->border);
590 e_desk_show(ic->border->desk);
591 e_border_show(ic->border);
592 e_border_raise(ic->border);
593 e_border_focus_set(ic->border, 1, 1);
595 b->icons = eina_list_remove(b->icons, ic);
596 _notification_box_icon_free(ic);
597 _notification_box_empty_handle(b);
598 _notification_box_resize_handle(b);
599 _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
603 _notification_box_cb_icon_mouse_down(Notification_Box_Icon *ic,
605 Evas_Object *obj __UNUSED__,
606 Evas_Event_Mouse_Down *ev)
612 if (ev->button != 3) return;
615 mi = e_menu_item_new(m);
616 e_menu_item_label_set(mi, _("Settings"));
617 e_util_menu_item_theme_icon_set(mi, "preferences-system");
618 e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, ic->n_box);
620 m = e_gadcon_client_util_menu_items_append(ic->n_box->inst->gcc, m, 0);
621 e_gadcon_canvas_zone_geometry_get(ic->n_box->inst->gcc->gadcon,
623 e_menu_activate_mouse(m,
624 e_util_zone_current_get(e_manager_current_get()),
625 cx + ev->output.x, cy + ev->output.y, 1, 1,
626 E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
630 _notification_box_empty_handle(Notification_Box *b)
635 if (b->o_empty) return;
637 b->o_empty = evas_object_rectangle_add(evas_object_evas_get(b->o_box));
638 evas_object_event_callback_add(b->o_empty, EVAS_CALLBACK_MOUSE_DOWN,
639 (Evas_Object_Event_Cb)_notification_box_cb_empty_mouse_down, b);
640 evas_object_color_set(b->o_empty, 0, 0, 0, 0);
641 evas_object_show(b->o_empty);
642 e_box_pack_end(b->o_box, b->o_empty);
643 evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
644 if (e_box_orientation_get(b->o_box))
648 e_box_pack_options_set(b->o_empty,
651 0.5, 0.5, /* align */
658 evas_object_del(b->o_empty);
663 static Notification_Box_Icon *
664 _notification_box_icon_new(Notification_Box *b,
669 Notification_Box_Icon *ic;
671 ic = E_NEW(Notification_Box_Icon, 1);
672 if (bd) e_object_ref(E_OBJECT(bd));
673 e_notification_ref(n);
674 ic->label = e_notification_app_name_get(n);
679 ic->o_holder = edje_object_add(evas_object_evas_get(b->o_box));
680 e_theme_edje_object_set(ic->o_holder, "base/theme/modules/ibox",
681 "e/modules/ibox/icon");
682 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_IN,
683 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_in, ic);
684 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_OUT,
685 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_out, ic);
686 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_DOWN,
687 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_down, ic);
688 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_UP,
689 (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_up, ic);
690 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOVE,
691 (Evas_Object_Event_Cb)_notification_box_cb_icon_move, ic);
692 evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_RESIZE,
693 (Evas_Object_Event_Cb)_notification_box_cb_icon_resize, ic);
694 evas_object_show(ic->o_holder);
696 ic->o_holder2 = edje_object_add(evas_object_evas_get(b->o_box));
697 e_theme_edje_object_set(ic->o_holder2, "base/theme/modules/ibox",
698 "e/modules/ibox/icon_overlay");
699 evas_object_layer_set(ic->o_holder2, 9999);
700 evas_object_pass_events_set(ic->o_holder2, 1);
701 evas_object_show(ic->o_holder2);
703 _notification_box_icon_fill(ic, n);