4 * TODO: Listen to EFREET_EVENT_DESKTOP_CACHE_UPDATE
7 typedef struct _Main_Data Main_Data;
16 E_Menu *enlightenment;
21 /* local subsystem functions */
22 static void _e_int_menus_main_del_hook(void *obj);
23 static void _e_int_menus_main_about(void *data, E_Menu *m, E_Menu_Item *mi);
24 //static void _e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
25 static void _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu);
26 static void _e_int_menus_apps_start(void *data, E_Menu *m);
27 static void _e_int_menus_apps_free_hook(void *obj);
28 static void _e_int_menus_apps_free_hook2(void *obj);
29 static void _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi);
30 static void _e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi);
31 static void _e_int_menus_config_pre_cb(void *data, E_Menu *m);
32 static void _e_int_menus_config_free_hook(void *obj);
33 static void _e_int_menus_clients_pre_cb(void *data, E_Menu *m);
34 static void _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m);
35 static void _e_int_menus_clients_free_hook(void *obj);
36 static void _e_int_menus_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
37 static void _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi);
38 static void _e_int_menus_clients_cleanup_cb(void *data, E_Menu *m, E_Menu_Item *mi);
39 static int _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2);
40 static int _e_int_menus_clients_group_class_cb(const void *d1, const void *d2);
41 static int _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2);
42 static int _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2);
43 static void _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m);
44 static void _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m);
45 static void _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m);
46 static void _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m);
47 static const char *_e_int_menus_clients_title_abbrv(const char *title);
48 static void _e_int_menus_virtuals_pre_cb(void *data, E_Menu *m);
49 static void _e_int_menus_virtuals_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
50 static void _e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi);
51 static void _e_int_menus_themes_about(void *data, E_Menu *m, E_Menu_Item *mi);
52 static void _e_int_menus_lost_clients_pre_cb(void *data, E_Menu *m);
53 static void _e_int_menus_lost_clients_free_hook(void *obj);
54 static void _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
55 static void _e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation);
56 static void _e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation);
57 static void _e_int_menus_shelves_pre_cb(void *data, E_Menu *m);
58 static void _e_int_menus_shelves_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
59 static void _e_int_menus_shelves_add_cb(void *data, E_Menu *m, E_Menu_Item *mi);
60 static void _e_int_menus_shelves_del_cb(void *data, E_Menu *m, E_Menu_Item *mi);
61 static void _e_int_menus_main_showhide(void *data, E_Menu *m, E_Menu_Item *mi);
62 static void _e_int_menus_main_restart(void *data, E_Menu *m, E_Menu_Item *mi);
63 static void _e_int_menus_main_exit(void *data, E_Menu *m, E_Menu_Item *mi);
64 static void _e_int_menus_desktops_free_hook(void *obj);
65 static void _e_int_menus_desk_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
66 static void _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi);
68 //static void _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__);
70 /* local subsystem globals */
71 static Eina_Hash *_e_int_menus_augmentation = NULL;
72 static Eina_List *_e_int_menus_augmentation_disabled = NULL;
75 _e_int_menus_augmentation_find(const char *key)
80 if ((!_e_int_menus_augmentation) || (!key)) return NULL;
82 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
83 if (!strcmp(data, key)) return NULL;
84 return eina_hash_find(_e_int_menus_augmentation, key);
87 /* externally accessible functions */
89 e_int_menus_main_new(void)
97 dat = calloc(1, sizeof(Main_Data));
99 e_menu_title_set(m, _("Main"));
101 e_object_data_set(E_OBJECT(m), dat);
102 e_object_del_attach_func_set(E_OBJECT(m), _e_int_menus_main_del_hook);
104 e_menu_category_set(m, "main");
106 l = _e_int_menus_augmentation_find("main/0");
107 if (l) _e_int_menus_augmentation_add(m, l);
109 if (e_config->menu_favorites_show)
111 subm = e_int_menus_favorite_apps_new();
115 mi = e_menu_item_new(m);
116 e_menu_item_label_set(mi, _("Favorite Applications"));
117 e_util_menu_item_theme_icon_set(mi, "user-bookmarks");
118 e_menu_item_submenu_set(mi, subm);
122 if (e_config->menu_apps_show)
124 subm = e_int_menus_all_apps_new();
125 dat->all_apps = subm;
126 mi = e_menu_item_new(m);
127 e_menu_item_label_set(mi, _("Applications"));
128 e_util_menu_item_theme_icon_set(mi, "preferences-applications");
129 e_menu_item_submenu_set(mi, subm);
132 l = _e_int_menus_augmentation_find("main/1");
133 if (l) _e_int_menus_augmentation_add(m, l);
135 mi = e_menu_item_new(m);
136 e_menu_item_separator_set(mi, 1);
138 l = _e_int_menus_augmentation_find("main/2");
139 if (l) _e_int_menus_augmentation_add(m, l);
141 subm = e_int_menus_desktops_new();
142 dat->desktops = subm;
143 mi = e_menu_item_new(m);
144 e_menu_item_label_set(mi, _("Desktop"));
145 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
146 e_menu_item_submenu_set(mi, subm);
148 subm = e_int_menus_clients_new();
150 mi = e_menu_item_new(m);
151 e_menu_item_label_set(mi, _("Windows"));
152 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
153 e_menu_item_submenu_set(mi, subm);
154 e_object_data_set(E_OBJECT(subm), dat);
156 #if 0 // lost windows already handled inside "Windows" from main menu.
157 subm = e_int_menus_lost_clients_new();
158 e_object_data_set(E_OBJECT(subm), dat);
159 dat->lost_clients = subm;
160 mi = e_menu_item_new(m);
161 e_menu_item_label_set(mi, _("Lost Windows"));
162 e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost");
163 e_menu_item_submenu_set(mi, subm);
166 l = _e_int_menus_augmentation_find("main/3");
167 if (l) _e_int_menus_augmentation_add(m, l);
169 mi = e_menu_item_new(m);
170 e_menu_item_separator_set(mi, 1);
172 l = _e_int_menus_augmentation_find("main/4");
173 if (l) _e_int_menus_augmentation_add(m, l);
176 dat->enlightenment = subm;
177 mi = e_menu_item_new(m);
178 e_menu_item_label_set(mi, _("Enlightenment"));
179 e_util_menu_item_theme_icon_set(mi, "enlightenment");
180 e_menu_item_submenu_set(mi, subm);
182 mi = e_menu_item_new(subm);
183 e_menu_item_label_set(mi, _("About"));
184 e_util_menu_item_theme_icon_set(mi, "help-about");
185 e_menu_item_callback_set(mi, _e_int_menus_main_about, NULL);
187 mi = e_menu_item_new(subm);
188 e_menu_item_label_set(mi, _("Theme"));
189 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-theme");
190 e_menu_item_callback_set(mi, _e_int_menus_themes_about, NULL);
192 l = _e_int_menus_augmentation_find("main/5");
193 if (l) _e_int_menus_augmentation_add(m, l);
195 mi = e_menu_item_new(subm);
196 e_menu_item_separator_set(mi, 1);
198 l = _e_int_menus_augmentation_find("main/6");
199 if (l) _e_int_menus_augmentation_add(m, l);
201 mi = e_menu_item_new(subm);
202 e_menu_item_label_set(mi, _("Restart"));
203 e_util_menu_item_theme_icon_set(mi, "system-restart");
204 e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL);
206 mi = e_menu_item_new(subm);
207 e_menu_item_label_set(mi, _("Exit"));
208 e_util_menu_item_theme_icon_set(mi, "application-exit");
209 e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL);
211 l = _e_int_menus_augmentation_find("main/7");
212 if (l) _e_int_menus_augmentation_add(m, l);
214 mi = e_menu_item_new(m);
215 e_menu_item_separator_set(mi, 1);
217 l = _e_int_menus_augmentation_find("main/8");
218 if (l) _e_int_menus_augmentation_add(m, l);
220 subm = e_int_menus_config_new();
222 mi = e_menu_item_new(m);
223 e_menu_item_label_set(mi, _("Settings"));
224 e_util_menu_item_theme_icon_set(mi, "preferences-system");
225 e_menu_item_submenu_set(mi, subm);
227 l = _e_int_menus_augmentation_find("main/9");
228 if (l) _e_int_menus_augmentation_add(m, l);
230 l = eina_hash_find(_e_int_menus_augmentation, "main/10");
234 mi = e_menu_item_new(m);
235 e_menu_item_separator_set(mi, 1);
236 _e_int_menus_augmentation_add(m, l);
239 l = eina_hash_find(_e_int_menus_augmentation, "main/11");
244 mi = e_menu_item_new(m);
245 e_menu_item_separator_set(mi, 1);
247 _e_int_menus_augmentation_add(m, l);
254 e_int_menus_apps_new(const char *dir)
259 if (dir) e_object_data_set(E_OBJECT(m), strdup(dir));
260 e_menu_pre_activate_callback_set(m, _e_int_menus_apps_start, NULL);
261 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_apps_free_hook);
266 e_int_menus_desktops_new(void)
274 mi = e_menu_item_new(m);
275 e_menu_item_label_set(mi, _("Virtual"));
276 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
277 e_menu_pre_activate_callback_set(subm, _e_int_menus_virtuals_pre_cb, NULL);
278 e_menu_item_submenu_set(mi, subm);
281 mi = e_menu_item_new(m);
282 e_menu_item_label_set(mi, _("Shelves"));
283 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
284 e_menu_pre_activate_callback_set(subm, _e_int_menus_shelves_pre_cb, NULL);
285 e_menu_item_submenu_set(mi, subm);
287 mi = e_menu_item_new(m);
288 e_menu_item_separator_set(mi, 1);
290 mi = e_menu_item_new(m);
291 e_menu_item_label_set(mi, _("Show/Hide All Windows"));
292 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
293 e_menu_item_callback_set(mi, _e_int_menus_main_showhide, NULL);
295 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_desktops_free_hook);
300 e_int_menus_favorite_apps_new(void)
305 e_user_dir_concat_static(buf, "applications/menu/favorite.menu");
306 if (ecore_file_exists(buf)) m = e_int_menus_apps_new(buf);
311 e_int_menus_all_apps_new(void)
315 m = e_int_menus_apps_new(NULL);
320 e_int_menus_config_new(void)
325 e_menu_pre_activate_callback_set(m, _e_int_menus_config_pre_cb, NULL);
330 e_int_menus_clients_new(void)
335 e_menu_pre_activate_callback_set(m, _e_int_menus_clients_pre_cb, NULL);
340 e_int_menus_lost_clients_new(void)
345 e_menu_pre_activate_callback_set(m, _e_int_menus_lost_clients_pre_cb, NULL);
349 EAPI E_Int_Menu_Augmentation *
350 e_int_menus_menu_augmentation_add_sorted(const char *menu,
351 const char *sort_key,
352 void (*func_add) (void *data, E_Menu *m),
354 void (*func_del) (void *data, E_Menu *m),
357 E_Int_Menu_Augmentation *maug;
359 Eina_Bool old = EINA_FALSE;
361 maug = E_NEW(E_Int_Menu_Augmentation, 1);
362 if (!maug) return NULL;
364 maug->sort_key = eina_stringshare_add(sort_key);
366 maug->add.func = func_add;
367 maug->add.data = data_add;
369 maug->del.func = func_del;
370 maug->del.data = data_del;
372 if (_e_int_menus_augmentation)
374 if ((l = eina_hash_find(_e_int_menus_augmentation, menu)))
379 _e_int_menus_augmentation = eina_hash_string_superfast_new(NULL);
384 if ((!l) || (!maug->sort_key))
385 l = eina_list_append(l, maug);
388 E_Int_Menu_Augmentation *m2;
391 /* keep list sorted, those missing sort_key at the end. */
392 EINA_LIST_FOREACH(l, l2, m2)
396 if (strcasecmp(maug->sort_key, m2->sort_key) < 0)
401 l = eina_list_prepend_relative_list(l, maug, l2);
403 l = eina_list_append(l, maug);
407 eina_hash_modify(_e_int_menus_augmentation, menu, l);
409 eina_hash_add(_e_int_menus_augmentation, menu, l);
414 EAPI E_Int_Menu_Augmentation *
415 e_int_menus_menu_augmentation_add(const char *menu,
416 void (*func_add) (void *data, E_Menu *m),
418 void (*func_del) (void *data, E_Menu *m),
421 return e_int_menus_menu_augmentation_add_sorted
422 (menu, NULL, func_add, data_add, func_del, data_del);
426 e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *maug)
430 if (!_e_int_menus_augmentation)
432 eina_stringshare_del(maug->sort_key);
437 l = eina_hash_find(_e_int_menus_augmentation, menu);
440 l = eina_list_remove(l, maug);
443 eina_hash_modify(_e_int_menus_augmentation, menu, l);
445 eina_hash_del_by_key(_e_int_menus_augmentation, menu);
447 eina_stringshare_del(maug->sort_key);
452 e_int_menus_menu_augmentation_point_disabled_set(const char *menu, Eina_Bool disabled)
457 _e_int_menus_augmentation_disabled =
458 eina_list_append(_e_int_menus_augmentation_disabled, menu);
462 _e_int_menus_augmentation_disabled =
463 eina_list_remove(_e_int_menus_augmentation_disabled, menu);
467 /* local subsystem functions */
469 _e_int_menus_main_del_hook(void *obj)
475 dat = e_object_data_get(E_OBJECT(obj));
476 if (dat->apps) e_object_del(E_OBJECT(dat->apps));
477 if (dat->all_apps) e_object_del(E_OBJECT(dat->all_apps));
478 if (dat->desktops) e_object_del(E_OBJECT(dat->desktops));
479 if (dat->clients) e_object_del(E_OBJECT(dat->clients));
480 if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients));
481 if (dat->enlightenment) e_object_del(E_OBJECT(dat->enlightenment));
482 if (dat->config) e_object_del(E_OBJECT(dat->config));
485 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/0"));
486 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/1"));
487 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/2"));
488 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/3"));
489 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/4"));
490 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/5"));
491 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/6"));
492 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/7"));
493 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/8"));
494 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/9"));
495 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/10"));
496 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/11"));
500 _e_int_menus_main_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
504 about = e_about_new(e_container_current_get(e_manager_current_get()));
505 if (about) e_about_show(about);
509 _e_int_menus_themes_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
511 E_Theme_About *about;
513 about = e_theme_about_new(e_container_current_get(e_manager_current_get()));
514 if (about) e_theme_about_show(about);
519 _e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
521 e_fwin_new(m->zone->container, "favorites", "/");
526 _e_int_menus_main_showhide(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
530 act = e_action_find("desk_deskshow_toggle");
531 if (act) act->func.go(E_OBJECT(m->zone), NULL);
535 _e_int_menus_main_restart(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
539 a = e_action_find("restart");
540 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
544 _e_int_menus_main_exit(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
548 a = e_action_find("exit");
549 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
553 _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu)
562 EINA_LIST_FOREACH(menu->entries, l, entry)
564 mi = e_menu_item_new(m);
566 _e_int_menus_item_label_set(entry, mi);
570 if (entry->icon[0] == '/')
571 e_menu_item_icon_file_set(mi, entry->icon);
573 e_util_menu_item_theme_icon_set(mi, entry->icon);
575 if (entry->type == EFREET_MENU_ENTRY_SEPARATOR)
576 e_menu_item_separator_set(mi, 1);
577 else if (entry->type == EFREET_MENU_ENTRY_DESKTOP)
579 e_menu_item_callback_set(mi, _e_int_menus_apps_run,
581 e_menu_item_drag_callback_set(mi, _e_int_menus_apps_drag,
584 else if (entry->type == EFREET_MENU_ENTRY_MENU)
589 e_menu_pre_activate_callback_set(subm,
590 _e_int_menus_apps_start,
592 e_menu_item_submenu_set(mi, subm);
593 e_object_free_attach_func_set(E_OBJECT(subm),
594 _e_int_menus_apps_free_hook2);
596 /* TODO: Highlight header
597 else if (entry->type == EFREET_MENU_ENTRY_HEADER)
603 mi = e_menu_item_new(m);
604 e_menu_item_label_set(mi, _("(No Applications)"));
609 _e_int_menus_apps_start(void *data, E_Menu *m)
618 dir = e_object_data_get(E_OBJECT(m));
621 menu = efreet_menu_parse(dir);
624 else menu = efreet_menu_get();
625 e_object_data_set(E_OBJECT(m), menu);
626 e_object_free_attach_func_set(E_OBJECT(m),
627 _e_int_menus_apps_free_hook2);
629 if (menu) _e_int_menus_apps_scan(m, menu);
630 e_menu_pre_activate_callback_set(m, NULL, NULL);
634 _e_int_menus_apps_free_hook(void *obj)
640 dir = e_object_data_get(E_OBJECT(m));
645 _e_int_menus_apps_free_hook2(void *obj)
649 Eina_List *l, *l_next;
653 // XXX TODO: this should be automatic in e_menu, just get references right!
654 // XXX TODO: fix references and remove me!!!
655 EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
658 e_object_del(E_OBJECT(mi->submenu));
660 menu = e_object_data_get(E_OBJECT(m));
661 if (menu) efreet_menu_free(menu);
665 _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi __UNUSED__)
667 Efreet_Desktop *desktop;
670 e_exec(m->zone, desktop, NULL, NULL, "menu/apps");
675 _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__)
677 Efreet_Desktop *desktop;
679 desktop = drag->data;
680 efreet_desktop_free(desktop);
685 _e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi)
687 Efreet_Desktop *desktop;
695 Evas_Object *o = NULL;
696 Evas_Coord x, y, w, h;
698 const char *drag_types[] = { "enlightenment/desktop" };
700 evas_object_geometry_get(mi->icon_object, &x, &y, &w, &h);
701 efreet_desktop_ref(desktop);
702 drag = e_drag_new(m->zone->container, x, y, drag_types, 1, desktop, -1,
706 o = e_util_desktop_icon_add(desktop, size, e_drag_evas_get(drag));
707 e_drag_object_set(drag, o);
708 e_drag_resize(drag, w, h);
709 e_drag_start(drag, mi->drag.x + w, mi->drag.y + h);
714 _e_int_menus_virtuals_pre_cb(void *data __UNUSED__, E_Menu *m)
719 e_menu_pre_activate_callback_set(m, NULL, NULL);
721 root = e_menu_root_get(m);
722 if ((root) && (root->zone))
728 for (i = 0; i < (zone->desk_x_count * zone->desk_y_count); i++)
732 desk = zone->desks[i];
733 mi = e_menu_item_new(m);
734 e_menu_item_radio_group_set(mi, 1);
735 e_menu_item_radio_set(mi, 1);
736 e_menu_item_label_set(mi, desk->name);
737 if (desk == e_desk_current_get(zone))
738 e_menu_item_toggle_set(mi, 1);
739 e_menu_item_callback_set(mi, _e_int_menus_virtuals_item_cb, desk);
740 e_menu_item_realize_callback_set(mi, _e_int_menus_virtuals_icon_cb, desk);
744 if (e_configure_registry_exists("screen/virtual_desktops"))
746 mi = e_menu_item_new(m);
747 e_menu_item_separator_set(mi, 1);
749 mi = e_menu_item_new(m);
750 e_menu_item_label_set(mi, _("Set Virtual Desktops"));
751 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
752 e_menu_item_callback_set(mi, _e_int_menus_desk_item_cb, NULL);
757 _e_int_menus_desktops_free_hook(void *obj)
760 Eina_List *l, *l_next;
764 // XXX TODO: this should be automatic in e_menu, just get references right!
765 // XXX TODO: fix references and remove me!!!
766 EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
769 e_object_del(E_OBJECT(mi->submenu));
774 _e_int_menus_desk_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
776 e_configure_registry_call("screen/virtual_desktops", m->zone->container, NULL);
780 _e_int_menus_virtuals_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
784 if (!(desk = data)) return;
789 _e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
797 E_OBJECT_CHECK(desk);
800 th = (tw * desk->zone->h) / desk->zone->w;
802 bgfile = e_bg_file_get(desk->zone->container->num, desk->zone->num, desk->x, desk->y);
803 o = e_thumb_icon_add(m->evas);
804 e_thumb_icon_file_set(o, bgfile, "e/desktop/background");
805 e_thumb_icon_size_set(o, tw, th);
806 e_thumb_icon_begin(o);
811 _e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
816 e_menu_pre_activate_callback_set(m, NULL, NULL);
818 l = _e_int_menus_augmentation_find("config/0");
821 _e_int_menus_augmentation_add(m, l);
822 if (_e_int_menus_augmentation_find("config/1"))
824 mi = e_menu_item_new(m);
825 e_menu_item_separator_set(mi, 1);
829 l = _e_int_menus_augmentation_find("config/1");
830 if (l) _e_int_menus_augmentation_add(m, l);
832 l = _e_int_menus_augmentation_find("config/2");
835 mi = e_menu_item_new(m);
836 e_menu_item_separator_set(mi, 1);
837 _e_int_menus_augmentation_add(m, l);
840 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_config_free_hook);
844 _e_int_menus_config_free_hook(void *obj)
849 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/0"));
850 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/1"));
851 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/2"));
855 _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2)
867 j = bd1->desk->y * 12 + bd1->desk->x;
868 k = bd2->desk->y * 12 + bd2->desk->x;
871 if (j < k) return -1;
872 return -1; /* Returning '-1' on equal is intentional */
876 _e_int_menus_clients_group_class_cb(const void *d1, const void *d2)
878 const E_Border *bd1, *bd2;
886 if (!bd1->client.icccm.class)
888 if (!bd2->client.icccm.class)
891 return (strcmp(bd1->client.icccm.class, bd2->client.icccm.class) > 0 ? 1 : -1);
895 _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2)
897 const E_Border *bd1, *bd2;
898 const char *name1, *name2;
905 name1 = e_border_name_get(bd1);
906 name2 = e_border_name_get(bd2);
908 if (strcasecmp(name1, name2) > 0) return 1;
909 if (strcasecmp(name1, name2) < 0) return -1;
914 _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2)
916 const E_Border *bd1, *bd2;
924 if (bd1->layer < bd2->layer) return 1;
925 if (bd1->layer > bd2->layer) return -1;
930 _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m)
932 if (eina_list_count(borders) > 0)
936 E_Menu_Item *mi = NULL;
938 mi = e_menu_item_new(m);
939 e_menu_item_separator_set(mi, 1);
941 EINA_LIST_FOREACH(borders, l, bd)
942 _e_int_menus_clients_item_create(bd, m);
947 _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m)
949 Eina_List *l = NULL, *ico = NULL;
952 E_Menu_Item *mi = NULL;
956 EINA_LIST_FOREACH(borders, l, bd)
959 (e_config->clientlist_separate_iconified_apps == E_CLIENTLIST_GROUPICONS_SEP))
961 ico = eina_list_append(ico, bd);
965 if (((strcmp(class, bd->client.icccm.class) != 0) &&
966 e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
968 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
970 if ((subm) && (mi)) e_menu_item_submenu_set(mi, subm);
971 mi = e_menu_item_new(m);
972 e_menu_item_label_set(mi, bd->client.icccm.class);
973 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
978 mi = e_menu_item_new(m);
979 e_menu_item_separator_set(mi, 1);
981 class = strdup(bd->client.icccm.class);
983 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
984 _e_int_menus_clients_item_create(bd, subm);
986 _e_int_menus_clients_item_create(bd, m);
989 if ((e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
991 e_menu_item_submenu_set(mi, subm);
993 _e_int_menus_clients_menu_add_iconified(ico, m);
997 _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m)
1000 Eina_List *l = NULL, *alt = NULL, *ico = NULL;
1003 E_Menu_Item *mi = NULL;
1005 /* Deal with present desk first */
1006 EINA_LIST_FOREACH(borders, l, bd)
1008 if (bd->iconic && e_config->clientlist_separate_iconified_apps && E_CLIENTLIST_GROUPICONS_SEP)
1010 ico = eina_list_append(ico, bd);
1014 if (bd->desk != curr_desk)
1016 if ((!bd->iconic) ||
1017 (bd->iconic && e_config->clientlist_separate_iconified_apps ==
1018 E_CLIENTLIST_GROUPICONS_OWNER))
1020 alt = eina_list_append(alt, bd);
1025 _e_int_menus_clients_item_create(bd, m);
1030 if (eina_list_count(alt) > 0)
1032 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1034 mi = e_menu_item_new(m);
1035 e_menu_item_separator_set(mi, 1);
1038 EINA_LIST_FOREACH(alt, l, bd)
1040 if ((bd->desk != desk) &&
1041 (e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
1043 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1045 if (subm && mi) e_menu_item_submenu_set(mi, subm);
1046 mi = e_menu_item_new(m);
1047 e_menu_item_label_set(mi, bd->desk->name);
1048 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
1049 subm = e_menu_new();
1053 mi = e_menu_item_new(m);
1054 e_menu_item_separator_set(mi, 1);
1058 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1059 _e_int_menus_clients_item_create(bd, subm);
1061 _e_int_menus_clients_item_create(bd, m);
1063 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU
1065 e_menu_item_submenu_set(mi, subm);
1068 _e_int_menus_clients_menu_add_iconified(ico, m);
1072 _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m)
1074 Eina_List *l = NULL, *ico = NULL;
1077 EINA_LIST_FOREACH(borders, l, bd)
1079 if ((bd->iconic) && (e_config->clientlist_separate_iconified_apps) &&
1080 (E_CLIENTLIST_GROUPICONS_SEP))
1082 ico = eina_list_append(ico, bd);
1085 _e_int_menus_clients_item_create(bd, m);
1087 _e_int_menus_clients_menu_add_iconified(ico, m);
1091 _e_int_menus_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1094 E_Menu_Item *mi = NULL;
1095 Eina_List *l = NULL, *borders = NULL;
1097 E_Zone *zone = NULL;
1098 E_Desk *desk = NULL;
1101 e_menu_pre_activate_callback_set(m, NULL, NULL);
1102 /* get the current clients */
1103 zone = e_zone_current_get(e_container_current_get(e_manager_current_get()));
1104 desk = e_desk_current_get(zone);
1106 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_MOST_RECENT)
1107 l = e_border_focus_stack_get();
1109 l = e_border_client_list();
1110 EINA_LIST_FOREACH(l, l, border)
1112 if (border->user_skip_winlist) continue;
1113 if ((border->zone == zone) || (border->iconic) ||
1114 (border->zone != zone && e_config->clientlist_include_all_zones))
1115 borders = eina_list_append(borders, border);
1118 dat = (Main_Data *)e_object_data_get(E_OBJECT(m));
1119 if (!dat) e_menu_title_set(m, _("Windows"));
1123 /* FIXME here we want nothing, but that crashes!!! */
1124 mi = e_menu_item_new(m);
1125 e_menu_item_label_set(mi, _("(No Windows)"));
1130 /* Sort the borders */
1131 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ALPHA)
1132 borders = eina_list_sort(borders, eina_list_count(borders),
1133 _e_int_menus_clients_sort_alpha_cb);
1135 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ZORDER)
1136 borders = eina_list_sort(borders, eina_list_count(borders),
1137 _e_int_menus_clients_sort_z_order_cb);
1139 /* Group the borders */
1140 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_DESK)
1142 borders = eina_list_sort(borders, eina_list_count(borders),
1143 _e_int_menus_clients_group_desk_cb);
1144 _e_int_menus_clients_add_by_desk(desk, borders, m);
1146 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_CLASS)
1148 borders = eina_list_sort(borders, eina_list_count(borders),
1149 _e_int_menus_clients_group_class_cb);
1150 _e_int_menus_clients_add_by_class(borders, m);
1152 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_NONE)
1153 _e_int_menus_clients_add_by_none(borders, m);
1156 mi = e_menu_item_new(m);
1157 e_menu_item_separator_set(mi, 1);
1159 mi = e_menu_item_new(m);
1160 e_menu_item_label_set(mi, _("Cleanup Windows"));
1161 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
1162 e_menu_item_callback_set(mi, _e_int_menus_clients_cleanup_cb, zone);
1166 mi = e_menu_item_new(m);
1167 e_menu_item_separator_set(mi, 1);
1169 subm = e_int_menus_lost_clients_new();
1170 e_object_data_set(E_OBJECT(subm), e_object_data_get(E_OBJECT(m)));
1171 dat->lost_clients = subm;
1172 mi = e_menu_item_new(m);
1173 e_menu_item_label_set(mi, _("Lost Windows"));
1174 e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost");
1175 e_menu_item_submenu_set(mi, subm);
1178 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_clients_free_hook);
1179 e_object_data_set(E_OBJECT(m), borders);
1183 _e_int_menus_clients_title_abbrv(const char *title)
1187 max_len = e_config->clientlist_max_caption_len;
1188 if ((e_config->clientlist_limit_caption_len) && ((int) strlen(title) > max_len))
1191 const char *left, *right;
1193 abbv = calloc(E_CLIENTLIST_MAX_CAPTION_LEN + 4, sizeof(char));
1195 right = title + (strlen(title) - (max_len / 2));
1197 strncpy(abbv, left, max_len / 2);
1198 strncat(abbv, "...", 3);
1199 strncat(abbv, right, max_len / 2);
1208 _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m)
1213 title = _e_int_menus_clients_title_abbrv(e_border_name_get(bd));
1214 mi = e_menu_item_new(m);
1215 e_menu_item_check_set(mi, 1);
1216 if ((title) && (title[0]))
1217 e_menu_item_label_set(mi, title);
1219 e_menu_item_label_set(mi, _("No name!!"));
1220 /* ref the border as we implicitly unref it in the callback */
1221 e_object_ref(E_OBJECT(bd));
1222 /* e_object_breadcrumb_add(E_OBJECT(bd), "clients_menu");*/
1223 e_menu_item_callback_set(mi, _e_int_menus_clients_item_cb, bd);
1224 e_menu_item_realize_callback_set(mi, _e_int_menus_clients_icon_cb, bd);
1225 if (!bd->iconic) e_menu_item_toggle_set(mi, 1);
1229 _e_int_menus_clients_free_hook(void *obj)
1236 borders = e_object_data_get(E_OBJECT(m));
1237 EINA_LIST_FREE(borders, bd)
1238 e_object_unref(E_OBJECT(bd));
1242 _e_int_menus_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1251 if (e_config->clientlist_warp_to_iconified_desktop == 1)
1252 e_desk_show(bd->desk);
1253 if (!bd->lock_user_iconify)
1254 e_border_uniconify(bd);
1257 if (!bd->iconic) e_desk_show(bd->desk);
1258 if (!bd->lock_user_stacking) e_border_raise(bd);
1259 if (!bd->lock_focus_out)
1261 if (e_config->focus_policy != E_FOCUS_CLICK)
1262 ecore_x_pointer_warp(bd->zone->container->win,
1263 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
1264 e_border_focus_set(bd, 1, 1);
1269 _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
1276 o = e_icon_add(m->evas);
1277 e_icon_object_set(o, e_border_icon_add(bd, m->evas));
1278 mi->icon_object = o;
1282 _e_int_menus_clients_cleanup_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1286 act = e_action_find("cleanup_windows");
1287 if (act) act->func.go(E_OBJECT(m->zone), NULL);
1291 _e_int_menus_lost_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1294 Eina_List *l, *borders = NULL;
1297 E_Zone *zone = NULL;
1299 e_menu_pre_activate_callback_set(m, NULL, NULL);
1300 root = e_menu_root_get(m);
1301 /* get the current clients */
1302 if (root) zone = root->zone;
1303 borders = e_border_lost_windows_get(zone);
1307 /* FIXME here we want nothing, but that crashes!!! */
1308 mi = e_menu_item_new(m);
1309 e_menu_item_label_set(mi, _("(No Windows)"));
1312 EINA_LIST_FOREACH(borders, l, bd)
1314 const char *title = "";
1316 title = e_border_name_get(bd);
1317 mi = e_menu_item_new(m);
1318 if ((title) && (title[0]))
1319 e_menu_item_label_set(mi, title);
1321 e_menu_item_label_set(mi, _("No name!!"));
1322 /* ref the border as we implicitly unref it in the callback */
1323 e_object_ref(E_OBJECT(bd));
1324 e_menu_item_callback_set(mi, _e_int_menus_lost_clients_item_cb, bd);
1326 e_util_desktop_menu_item_icon_add(bd->desktop, 24, mi);
1328 e_object_free_attach_func_set(E_OBJECT(m),
1329 _e_int_menus_lost_clients_free_hook);
1330 e_object_data_set(E_OBJECT(m), borders);
1334 _e_int_menus_lost_clients_free_hook(void *obj)
1341 borders = e_object_data_get(E_OBJECT(m));
1342 EINA_LIST_FREE(borders, bd)
1343 e_object_unref(E_OBJECT(bd));
1347 _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1349 E_Border *bd = data;
1352 if (bd->iconic) e_border_uniconify(bd);
1353 if (bd->desk) e_desk_show(bd->desk);
1354 e_border_center(bd);
1356 if (!bd->lock_focus_out)
1357 e_border_focus_set(bd, 1, 1);
1361 _e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation)
1363 E_Int_Menu_Augmentation *aug;
1367 if ((!augmentation) || (!m)) return;
1368 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1369 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1372 EINA_LIST_FOREACH(augmentation, l, aug)
1373 if (aug->add.func) aug->add.func(aug->add.data, m);
1377 _e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation)
1379 E_Int_Menu_Augmentation *aug;
1383 if ((!augmentation) || (!m)) return;
1384 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1385 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1388 EINA_LIST_FOREACH(augmentation, l, aug)
1389 if (aug->del.func) aug->del.func(aug->del.data, m);
1393 _e_int_menus_shelves_pre_cb(void *data __UNUSED__, E_Menu *m)
1396 Eina_List *l, *shelves = NULL;
1401 e_menu_pre_activate_callback_set(m, NULL, NULL);
1402 con = e_container_current_get(e_manager_current_get());
1403 zone = e_zone_current_get(con);
1405 /* get the current clients */
1406 shelves = e_shelf_list();
1410 /* FIXME here we want nothing, but that crashes!!! */
1411 mi = e_menu_item_new(m);
1412 e_menu_item_label_set(mi, _("(No Shelves)"));
1414 EINA_LIST_FOREACH(shelves, l, s)
1420 if (s->zone->num != zone->num) continue;
1421 if (s->cfg->container != (int) con->num) continue;
1423 name = e_shelf_orient_string_get (s);
1424 snprintf(buf, sizeof(buf), "Shelf %s", name);
1426 mi = e_menu_item_new(m);
1427 e_menu_item_label_set(mi, buf);
1428 e_menu_item_callback_set(mi, _e_int_menus_shelves_item_cb, s);
1429 switch (s->cfg->orient)
1431 case E_GADCON_ORIENT_LEFT:
1432 e_util_menu_item_theme_icon_set(mi, "preferences-position-left");
1434 case E_GADCON_ORIENT_RIGHT:
1435 e_util_menu_item_theme_icon_set(mi, "preferences-position-right");
1437 case E_GADCON_ORIENT_TOP:
1438 e_util_menu_item_theme_icon_set(mi, "preferences-position-top");
1440 case E_GADCON_ORIENT_BOTTOM:
1441 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom");
1443 case E_GADCON_ORIENT_CORNER_TL:
1444 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-left");
1446 case E_GADCON_ORIENT_CORNER_TR:
1447 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-right");
1449 case E_GADCON_ORIENT_CORNER_BL:
1450 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-left");
1452 case E_GADCON_ORIENT_CORNER_BR:
1453 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-right");
1455 case E_GADCON_ORIENT_CORNER_LT:
1456 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-top");
1458 case E_GADCON_ORIENT_CORNER_RT:
1459 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-top");
1461 case E_GADCON_ORIENT_CORNER_LB:
1462 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-bottom");
1464 case E_GADCON_ORIENT_CORNER_RB:
1465 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-bottom");
1468 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
1472 mi = e_menu_item_new(m);
1473 e_menu_item_separator_set(mi, 1);
1475 mi = e_menu_item_new(m);
1476 e_menu_item_label_set(mi, _("Add A Shelf"));
1477 e_util_menu_item_theme_icon_set(mi, "list-add");
1478 e_menu_item_callback_set(mi, _e_int_menus_shelves_add_cb, NULL);
1482 mi = e_menu_item_new(m);
1483 e_menu_item_label_set(mi, _("Delete A Shelf"));
1484 e_util_menu_item_theme_icon_set(mi, "list-remove");
1485 e_menu_item_callback_set(mi, _e_int_menus_shelves_del_cb, NULL);
1490 _e_int_menus_shelves_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1495 e_int_shelf_config(s);
1499 _e_int_menus_shelves_add_cb(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1505 con = e_container_current_get(e_manager_current_get());
1506 zone = e_zone_current_get(con);
1507 cs = E_NEW(E_Config_Shelf, 1);
1508 cs->name = eina_stringshare_add("shelf");
1509 cs->container = con->num;
1510 cs->zone = zone->id;
1513 cs->orient = E_GADCON_ORIENT_CORNER_BR;
1516 cs->style = eina_stringshare_add("default");
1519 e_config->shelves = eina_list_append(e_config->shelves, cs);
1520 e_config_save_queue();
1522 e_shelf_config_update();
1526 _e_int_menus_shelves_del_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1528 e_configure_registry_call("extensions/shelves", m->zone->container, NULL);
1532 _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi)
1534 Efreet_Desktop *desktop;
1538 if ((!entry) || (!mi)) return;
1540 desktop = entry->desktop;
1541 if ((e_config->menu_eap_name_show) && (entry->name)) opt |= 0x4;
1544 if ((e_config->menu_eap_generic_show) && (desktop->generic_name) &&
1545 (desktop->generic_name[0] != 0))
1547 if ((e_config->menu_eap_comment_show) && (desktop->comment) &&
1548 (desktop->comment[0] != 0))
1553 snprintf(label, sizeof(label), "%s (%s) [%s]", entry->name,
1554 desktop->generic_name, desktop->comment);
1555 else if (opt == 0x6)
1556 snprintf(label, sizeof(label), "%s (%s)", entry->name,
1557 desktop->generic_name);
1558 else if (opt == 0x5)
1559 snprintf(label, sizeof(label), "%s [%s]", entry->name, desktop->comment);
1560 else if (opt == 0x4)
1561 snprintf(label, sizeof(label), "%s", entry->name);
1562 else if (opt == 0x3)
1563 snprintf(label, sizeof(label), "%s [%s]", desktop->generic_name,
1565 else if (opt == 0x2)
1566 snprintf(label, sizeof(label), "%s", desktop->generic_name);
1567 else if (opt == 0x1)
1568 snprintf(label, sizeof(label), "%s", desktop->comment);
1570 snprintf(label, sizeof(label), "%s", entry->name);
1572 e_menu_item_label_set(mi, label);