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;
178 l = _e_int_menus_augmentation_find("enlightenment/0");
179 if (l) _e_int_menus_augmentation_add(subm, l);
181 mi = e_menu_item_new(m);
182 e_menu_item_label_set(mi, _("Enlightenment"));
183 e_util_menu_item_theme_icon_set(mi, "enlightenment");
184 e_menu_item_submenu_set(mi, subm);
186 mi = e_menu_item_new(subm);
187 e_menu_item_label_set(mi, _("About"));
188 e_util_menu_item_theme_icon_set(mi, "help-about");
189 e_menu_item_callback_set(mi, _e_int_menus_main_about, NULL);
191 mi = e_menu_item_new(subm);
192 e_menu_item_label_set(mi, _("Theme"));
193 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-theme");
194 e_menu_item_callback_set(mi, _e_int_menus_themes_about, NULL);
196 l = _e_int_menus_augmentation_find("enlightenment/1");
197 if (l) _e_int_menus_augmentation_add(subm, l);
199 mi = e_menu_item_new(subm);
200 e_menu_item_separator_set(mi, 1);
202 l = _e_int_menus_augmentation_find("enlightenment/2");
203 if (l) _e_int_menus_augmentation_add(subm, l);
205 mi = e_menu_item_new(subm);
206 e_menu_item_label_set(mi, _("Restart"));
207 e_util_menu_item_theme_icon_set(mi, "system-restart");
208 e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL);
210 mi = e_menu_item_new(subm);
211 e_menu_item_label_set(mi, _("Exit"));
212 e_util_menu_item_theme_icon_set(mi, "application-exit");
213 e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL);
215 l = _e_int_menus_augmentation_find("enlightenment/3");
216 if (l) _e_int_menus_augmentation_add(subm, l);
218 l = _e_int_menus_augmentation_find("main/5");
219 if (l) _e_int_menus_augmentation_add(m, l);
221 mi = e_menu_item_new(m);
222 e_menu_item_separator_set(mi, 1);
224 l = _e_int_menus_augmentation_find("main/6");
225 if (l) _e_int_menus_augmentation_add(m, l);
227 subm = e_int_menus_config_new();
229 mi = e_menu_item_new(m);
230 e_menu_item_label_set(mi, _("Settings"));
231 e_util_menu_item_theme_icon_set(mi, "preferences-system");
232 e_menu_item_submenu_set(mi, subm);
234 l = _e_int_menus_augmentation_find("main/7");
235 if (l) _e_int_menus_augmentation_add(m, l);
237 l = eina_hash_find(_e_int_menus_augmentation, "main/8");
241 mi = e_menu_item_new(m);
242 e_menu_item_separator_set(mi, 1);
243 _e_int_menus_augmentation_add(m, l);
246 l = eina_hash_find(_e_int_menus_augmentation, "main/9");
251 mi = e_menu_item_new(m);
252 e_menu_item_separator_set(mi, 1);
254 _e_int_menus_augmentation_add(m, l);
261 e_int_menus_apps_new(const char *dir)
266 if (dir) e_object_data_set(E_OBJECT(m), strdup(dir));
267 e_menu_pre_activate_callback_set(m, _e_int_menus_apps_start, NULL);
268 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_apps_free_hook);
273 e_int_menus_desktops_new(void)
281 mi = e_menu_item_new(m);
282 e_menu_item_label_set(mi, _("Virtual"));
283 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
284 e_menu_pre_activate_callback_set(subm, _e_int_menus_virtuals_pre_cb, NULL);
285 e_menu_item_submenu_set(mi, subm);
288 mi = e_menu_item_new(m);
289 e_menu_item_label_set(mi, _("Shelves"));
290 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
291 e_menu_pre_activate_callback_set(subm, _e_int_menus_shelves_pre_cb, NULL);
292 e_menu_item_submenu_set(mi, subm);
294 mi = e_menu_item_new(m);
295 e_menu_item_separator_set(mi, 1);
297 mi = e_menu_item_new(m);
298 e_menu_item_label_set(mi, _("Show/Hide All Windows"));
299 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
300 e_menu_item_callback_set(mi, _e_int_menus_main_showhide, NULL);
302 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_desktops_free_hook);
307 e_int_menus_favorite_apps_new(void)
312 e_user_dir_concat_static(buf, "applications/menu/favorite.menu");
313 if (ecore_file_exists(buf)) m = e_int_menus_apps_new(buf);
318 e_int_menus_all_apps_new(void)
322 m = e_int_menus_apps_new(NULL);
327 e_int_menus_config_new(void)
332 e_menu_pre_activate_callback_set(m, _e_int_menus_config_pre_cb, NULL);
337 e_int_menus_clients_new(void)
342 e_menu_pre_activate_callback_set(m, _e_int_menus_clients_pre_cb, NULL);
347 e_int_menus_lost_clients_new(void)
352 e_menu_pre_activate_callback_set(m, _e_int_menus_lost_clients_pre_cb, NULL);
356 EAPI E_Int_Menu_Augmentation *
357 e_int_menus_menu_augmentation_add_sorted(const char *menu,
358 const char *sort_key,
359 void (*func_add) (void *data, E_Menu *m),
361 void (*func_del) (void *data, E_Menu *m),
364 E_Int_Menu_Augmentation *maug;
366 Eina_Bool old = EINA_FALSE;
368 maug = E_NEW(E_Int_Menu_Augmentation, 1);
369 if (!maug) return NULL;
371 maug->sort_key = eina_stringshare_add(sort_key);
373 maug->add.func = func_add;
374 maug->add.data = data_add;
376 maug->del.func = func_del;
377 maug->del.data = data_del;
379 if (_e_int_menus_augmentation)
381 if ((l = eina_hash_find(_e_int_menus_augmentation, menu)))
386 _e_int_menus_augmentation = eina_hash_string_superfast_new(NULL);
391 if ((!l) || (!maug->sort_key))
392 l = eina_list_append(l, maug);
395 E_Int_Menu_Augmentation *m2;
398 /* keep list sorted, those missing sort_key at the end. */
399 EINA_LIST_FOREACH(l, l2, m2)
403 if (strcasecmp(maug->sort_key, m2->sort_key) < 0)
408 l = eina_list_prepend_relative_list(l, maug, l2);
410 l = eina_list_append(l, maug);
414 eina_hash_modify(_e_int_menus_augmentation, menu, l);
416 eina_hash_add(_e_int_menus_augmentation, menu, l);
421 EAPI E_Int_Menu_Augmentation *
422 e_int_menus_menu_augmentation_add(const char *menu,
423 void (*func_add) (void *data, E_Menu *m),
425 void (*func_del) (void *data, E_Menu *m),
428 return e_int_menus_menu_augmentation_add_sorted
429 (menu, NULL, func_add, data_add, func_del, data_del);
433 e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *maug)
437 if (!_e_int_menus_augmentation)
439 eina_stringshare_del(maug->sort_key);
444 l = eina_hash_find(_e_int_menus_augmentation, menu);
447 l = eina_list_remove(l, maug);
450 eina_hash_modify(_e_int_menus_augmentation, menu, l);
452 eina_hash_del_by_key(_e_int_menus_augmentation, menu);
454 eina_stringshare_del(maug->sort_key);
459 e_int_menus_menu_augmentation_point_disabled_set(const char *menu, Eina_Bool disabled)
464 _e_int_menus_augmentation_disabled =
465 eina_list_append(_e_int_menus_augmentation_disabled, menu);
469 _e_int_menus_augmentation_disabled =
470 eina_list_remove(_e_int_menus_augmentation_disabled, menu);
474 /* local subsystem functions */
476 _e_int_menus_main_del_hook(void *obj)
482 dat = e_object_data_get(E_OBJECT(obj));
483 if (dat->apps) e_object_del(E_OBJECT(dat->apps));
484 if (dat->all_apps) e_object_del(E_OBJECT(dat->all_apps));
485 if (dat->desktops) e_object_del(E_OBJECT(dat->desktops));
486 if (dat->clients) e_object_del(E_OBJECT(dat->clients));
487 if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients));
488 if (dat->enlightenment) e_object_del(E_OBJECT(dat->enlightenment));
489 if (dat->config) e_object_del(E_OBJECT(dat->config));
492 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/0"));
493 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/1"));
494 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/2"));
495 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/3"));
496 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/4"));
497 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/5"));
498 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/6"));
499 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/7"));
500 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/8"));
501 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/9"));
502 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/10"));
503 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/11"));
507 _e_int_menus_main_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
511 about = e_about_new(e_container_current_get(e_manager_current_get()));
512 if (about) e_about_show(about);
516 _e_int_menus_themes_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
518 E_Theme_About *about;
520 about = e_theme_about_new(e_container_current_get(e_manager_current_get()));
521 if (about) e_theme_about_show(about);
526 _e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
528 e_fwin_new(m->zone->container, "favorites", "/");
533 _e_int_menus_main_showhide(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
537 act = e_action_find("desk_deskshow_toggle");
538 if (act) act->func.go(E_OBJECT(m->zone), NULL);
542 _e_int_menus_main_restart(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
546 a = e_action_find("restart");
547 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
551 _e_int_menus_main_exit(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
555 a = e_action_find("exit");
556 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
560 _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu)
569 EINA_LIST_FOREACH(menu->entries, l, entry)
571 mi = e_menu_item_new(m);
573 _e_int_menus_item_label_set(entry, mi);
577 if (entry->icon[0] == '/')
578 e_menu_item_icon_file_set(mi, entry->icon);
580 e_util_menu_item_theme_icon_set(mi, entry->icon);
582 if (entry->type == EFREET_MENU_ENTRY_SEPARATOR)
583 e_menu_item_separator_set(mi, 1);
584 else if (entry->type == EFREET_MENU_ENTRY_DESKTOP)
586 e_menu_item_callback_set(mi, _e_int_menus_apps_run,
588 e_menu_item_drag_callback_set(mi, _e_int_menus_apps_drag,
591 else if (entry->type == EFREET_MENU_ENTRY_MENU)
596 e_menu_pre_activate_callback_set(subm,
597 _e_int_menus_apps_start,
599 e_menu_item_submenu_set(mi, subm);
600 e_object_free_attach_func_set(E_OBJECT(subm),
601 _e_int_menus_apps_free_hook2);
603 /* TODO: Highlight header
604 else if (entry->type == EFREET_MENU_ENTRY_HEADER)
610 mi = e_menu_item_new(m);
611 e_menu_item_label_set(mi, _("(No Applications)"));
616 _e_int_menus_apps_start(void *data, E_Menu *m)
625 dir = e_object_data_get(E_OBJECT(m));
628 menu = efreet_menu_parse(dir);
631 else menu = efreet_menu_get();
632 e_object_data_set(E_OBJECT(m), menu);
633 e_object_free_attach_func_set(E_OBJECT(m),
634 _e_int_menus_apps_free_hook2);
636 if (menu) _e_int_menus_apps_scan(m, menu);
637 e_menu_pre_activate_callback_set(m, NULL, NULL);
641 _e_int_menus_apps_free_hook(void *obj)
647 dir = e_object_data_get(E_OBJECT(m));
652 _e_int_menus_apps_free_hook2(void *obj)
656 Eina_List *l, *l_next;
660 // XXX TODO: this should be automatic in e_menu, just get references right!
661 // XXX TODO: fix references and remove me!!!
662 EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
665 e_object_del(E_OBJECT(mi->submenu));
667 menu = e_object_data_get(E_OBJECT(m));
668 if (menu) efreet_menu_free(menu);
672 _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi __UNUSED__)
674 Efreet_Desktop *desktop;
677 e_exec(m->zone, desktop, NULL, NULL, "menu/apps");
682 _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__)
684 Efreet_Desktop *desktop;
686 desktop = drag->data;
687 efreet_desktop_free(desktop);
692 _e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi)
694 Efreet_Desktop *desktop;
702 Evas_Object *o = NULL;
703 Evas_Coord x, y, w, h;
705 const char *drag_types[] = { "enlightenment/desktop" };
707 evas_object_geometry_get(mi->icon_object, &x, &y, &w, &h);
708 efreet_desktop_ref(desktop);
709 drag = e_drag_new(m->zone->container, x, y, drag_types, 1, desktop, -1,
713 o = e_util_desktop_icon_add(desktop, size, e_drag_evas_get(drag));
714 e_drag_object_set(drag, o);
715 e_drag_resize(drag, w, h);
716 e_drag_start(drag, mi->drag.x + w, mi->drag.y + h);
721 _e_int_menus_virtuals_pre_cb(void *data __UNUSED__, E_Menu *m)
726 e_menu_pre_activate_callback_set(m, NULL, NULL);
728 root = e_menu_root_get(m);
729 if ((root) && (root->zone))
735 for (i = 0; i < (zone->desk_x_count * zone->desk_y_count); i++)
739 desk = zone->desks[i];
740 mi = e_menu_item_new(m);
741 e_menu_item_radio_group_set(mi, 1);
742 e_menu_item_radio_set(mi, 1);
743 e_menu_item_label_set(mi, desk->name);
744 if (desk == e_desk_current_get(zone))
745 e_menu_item_toggle_set(mi, 1);
746 e_menu_item_callback_set(mi, _e_int_menus_virtuals_item_cb, desk);
747 e_menu_item_realize_callback_set(mi, _e_int_menus_virtuals_icon_cb, desk);
751 if (e_configure_registry_exists("screen/virtual_desktops"))
753 mi = e_menu_item_new(m);
754 e_menu_item_separator_set(mi, 1);
756 mi = e_menu_item_new(m);
757 e_menu_item_label_set(mi, _("Set Virtual Desktops"));
758 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
759 e_menu_item_callback_set(mi, _e_int_menus_desk_item_cb, NULL);
764 _e_int_menus_desktops_free_hook(void *obj)
767 Eina_List *l, *l_next;
771 // XXX TODO: this should be automatic in e_menu, just get references right!
772 // XXX TODO: fix references and remove me!!!
773 EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
776 e_object_del(E_OBJECT(mi->submenu));
781 _e_int_menus_desk_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
783 e_configure_registry_call("screen/virtual_desktops", m->zone->container, NULL);
787 _e_int_menus_virtuals_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
791 if (!(desk = data)) return;
796 _e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
804 E_OBJECT_CHECK(desk);
807 th = (tw * desk->zone->h) / desk->zone->w;
809 bgfile = e_bg_file_get(desk->zone->container->num, desk->zone->num, desk->x, desk->y);
810 o = e_thumb_icon_add(m->evas);
811 e_thumb_icon_file_set(o, bgfile, "e/desktop/background");
812 e_thumb_icon_size_set(o, tw, th);
813 e_thumb_icon_begin(o);
818 _e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
823 e_menu_pre_activate_callback_set(m, NULL, NULL);
825 l = _e_int_menus_augmentation_find("config/0");
828 _e_int_menus_augmentation_add(m, l);
829 if (_e_int_menus_augmentation_find("config/1"))
831 mi = e_menu_item_new(m);
832 e_menu_item_separator_set(mi, 1);
836 l = _e_int_menus_augmentation_find("config/1");
837 if (l) _e_int_menus_augmentation_add(m, l);
839 l = _e_int_menus_augmentation_find("config/2");
842 mi = e_menu_item_new(m);
843 e_menu_item_separator_set(mi, 1);
844 _e_int_menus_augmentation_add(m, l);
847 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_config_free_hook);
851 _e_int_menus_config_free_hook(void *obj)
856 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/0"));
857 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/1"));
858 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/2"));
862 _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2)
874 j = bd1->desk->y * 12 + bd1->desk->x;
875 k = bd2->desk->y * 12 + bd2->desk->x;
878 if (j < k) return -1;
879 return -1; /* Returning '-1' on equal is intentional */
883 _e_int_menus_clients_group_class_cb(const void *d1, const void *d2)
885 const E_Border *bd1, *bd2;
893 if (!bd1->client.icccm.class)
895 if (!bd2->client.icccm.class)
898 return (strcmp(bd1->client.icccm.class, bd2->client.icccm.class) > 0 ? 1 : -1);
902 _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2)
904 const E_Border *bd1, *bd2;
905 const char *name1, *name2;
912 name1 = e_border_name_get(bd1);
913 name2 = e_border_name_get(bd2);
915 if (strcasecmp(name1, name2) > 0) return 1;
916 if (strcasecmp(name1, name2) < 0) return -1;
921 _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2)
923 const E_Border *bd1, *bd2;
931 if (bd1->layer < bd2->layer) return 1;
932 if (bd1->layer > bd2->layer) return -1;
937 _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m)
939 if (eina_list_count(borders) > 0)
943 E_Menu_Item *mi = NULL;
945 mi = e_menu_item_new(m);
946 e_menu_item_separator_set(mi, 1);
948 EINA_LIST_FOREACH(borders, l, bd)
949 _e_int_menus_clients_item_create(bd, m);
954 _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m)
956 Eina_List *l = NULL, *ico = NULL;
959 E_Menu_Item *mi = NULL;
963 EINA_LIST_FOREACH(borders, l, bd)
966 (e_config->clientlist_separate_iconified_apps == E_CLIENTLIST_GROUPICONS_SEP))
968 ico = eina_list_append(ico, bd);
972 if (((strcmp(class, bd->client.icccm.class) != 0) &&
973 e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
975 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
977 if ((subm) && (mi)) e_menu_item_submenu_set(mi, subm);
978 mi = e_menu_item_new(m);
979 e_menu_item_label_set(mi, bd->client.icccm.class);
980 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
985 mi = e_menu_item_new(m);
986 e_menu_item_separator_set(mi, 1);
988 class = strdup(bd->client.icccm.class);
990 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
991 _e_int_menus_clients_item_create(bd, subm);
993 _e_int_menus_clients_item_create(bd, m);
996 if ((e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
998 e_menu_item_submenu_set(mi, subm);
1000 _e_int_menus_clients_menu_add_iconified(ico, m);
1004 _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m)
1006 E_Desk *desk = NULL;
1007 Eina_List *l = NULL, *alt = NULL, *ico = NULL;
1010 E_Menu_Item *mi = NULL;
1012 /* Deal with present desk first */
1013 EINA_LIST_FOREACH(borders, l, bd)
1015 if (bd->iconic && e_config->clientlist_separate_iconified_apps && E_CLIENTLIST_GROUPICONS_SEP)
1017 ico = eina_list_append(ico, bd);
1021 if (bd->desk != curr_desk)
1023 if ((!bd->iconic) ||
1024 (bd->iconic && e_config->clientlist_separate_iconified_apps ==
1025 E_CLIENTLIST_GROUPICONS_OWNER))
1027 alt = eina_list_append(alt, bd);
1032 _e_int_menus_clients_item_create(bd, m);
1037 if (eina_list_count(alt) > 0)
1039 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1041 mi = e_menu_item_new(m);
1042 e_menu_item_separator_set(mi, 1);
1045 EINA_LIST_FOREACH(alt, l, bd)
1047 if ((bd->desk != desk) &&
1048 (e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
1050 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1052 if (subm && mi) e_menu_item_submenu_set(mi, subm);
1053 mi = e_menu_item_new(m);
1054 e_menu_item_label_set(mi, bd->desk->name);
1055 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
1056 subm = e_menu_new();
1060 mi = e_menu_item_new(m);
1061 e_menu_item_separator_set(mi, 1);
1065 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1066 _e_int_menus_clients_item_create(bd, subm);
1068 _e_int_menus_clients_item_create(bd, m);
1070 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU
1072 e_menu_item_submenu_set(mi, subm);
1075 _e_int_menus_clients_menu_add_iconified(ico, m);
1079 _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m)
1081 Eina_List *l = NULL, *ico = NULL;
1084 EINA_LIST_FOREACH(borders, l, bd)
1086 if ((bd->iconic) && (e_config->clientlist_separate_iconified_apps) &&
1087 (E_CLIENTLIST_GROUPICONS_SEP))
1089 ico = eina_list_append(ico, bd);
1092 _e_int_menus_clients_item_create(bd, m);
1094 _e_int_menus_clients_menu_add_iconified(ico, m);
1098 _e_int_menus_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1101 E_Menu_Item *mi = NULL;
1102 Eina_List *l = NULL, *borders = NULL;
1104 E_Zone *zone = NULL;
1105 E_Desk *desk = NULL;
1108 e_menu_pre_activate_callback_set(m, NULL, NULL);
1109 /* get the current clients */
1110 zone = e_zone_current_get(e_container_current_get(e_manager_current_get()));
1111 desk = e_desk_current_get(zone);
1113 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_MOST_RECENT)
1114 l = e_border_focus_stack_get();
1116 l = e_border_client_list();
1117 EINA_LIST_FOREACH(l, l, border)
1119 if (border->user_skip_winlist) continue;
1120 if ((border->zone == zone) || (border->iconic) ||
1121 (border->zone != zone && e_config->clientlist_include_all_zones))
1122 borders = eina_list_append(borders, border);
1125 dat = (Main_Data *)e_object_data_get(E_OBJECT(m));
1126 if (!dat) e_menu_title_set(m, _("Windows"));
1130 /* FIXME here we want nothing, but that crashes!!! */
1131 mi = e_menu_item_new(m);
1132 e_menu_item_label_set(mi, _("(No Windows)"));
1137 /* Sort the borders */
1138 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ALPHA)
1139 borders = eina_list_sort(borders, eina_list_count(borders),
1140 _e_int_menus_clients_sort_alpha_cb);
1142 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ZORDER)
1143 borders = eina_list_sort(borders, eina_list_count(borders),
1144 _e_int_menus_clients_sort_z_order_cb);
1146 /* Group the borders */
1147 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_DESK)
1149 borders = eina_list_sort(borders, eina_list_count(borders),
1150 _e_int_menus_clients_group_desk_cb);
1151 _e_int_menus_clients_add_by_desk(desk, borders, m);
1153 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_CLASS)
1155 borders = eina_list_sort(borders, eina_list_count(borders),
1156 _e_int_menus_clients_group_class_cb);
1157 _e_int_menus_clients_add_by_class(borders, m);
1159 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_NONE)
1160 _e_int_menus_clients_add_by_none(borders, m);
1163 mi = e_menu_item_new(m);
1164 e_menu_item_separator_set(mi, 1);
1166 mi = e_menu_item_new(m);
1167 e_menu_item_label_set(mi, _("Cleanup Windows"));
1168 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
1169 e_menu_item_callback_set(mi, _e_int_menus_clients_cleanup_cb, zone);
1173 mi = e_menu_item_new(m);
1174 e_menu_item_separator_set(mi, 1);
1176 subm = e_int_menus_lost_clients_new();
1177 e_object_data_set(E_OBJECT(subm), e_object_data_get(E_OBJECT(m)));
1178 dat->lost_clients = subm;
1179 mi = e_menu_item_new(m);
1180 e_menu_item_label_set(mi, _("Lost Windows"));
1181 e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost");
1182 e_menu_item_submenu_set(mi, subm);
1185 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_clients_free_hook);
1186 e_object_data_set(E_OBJECT(m), borders);
1190 _e_int_menus_clients_title_abbrv(const char *title)
1194 max_len = e_config->clientlist_max_caption_len;
1195 if ((e_config->clientlist_limit_caption_len) && ((int) strlen(title) > max_len))
1198 const char *left, *right;
1200 abbv = calloc(E_CLIENTLIST_MAX_CAPTION_LEN + 4, sizeof(char));
1202 right = title + (strlen(title) - (max_len / 2));
1204 strncpy(abbv, left, max_len / 2);
1205 strncat(abbv, "...", 3);
1206 strncat(abbv, right, max_len / 2);
1215 _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m)
1220 title = _e_int_menus_clients_title_abbrv(e_border_name_get(bd));
1221 mi = e_menu_item_new(m);
1222 e_menu_item_check_set(mi, 1);
1223 if ((title) && (title[0]))
1224 e_menu_item_label_set(mi, title);
1226 e_menu_item_label_set(mi, _("No name!!"));
1227 /* ref the border as we implicitly unref it in the callback */
1228 e_object_ref(E_OBJECT(bd));
1229 /* e_object_breadcrumb_add(E_OBJECT(bd), "clients_menu");*/
1230 e_menu_item_callback_set(mi, _e_int_menus_clients_item_cb, bd);
1231 e_menu_item_realize_callback_set(mi, _e_int_menus_clients_icon_cb, bd);
1232 if (!bd->iconic) e_menu_item_toggle_set(mi, 1);
1236 _e_int_menus_clients_free_hook(void *obj)
1243 borders = e_object_data_get(E_OBJECT(m));
1244 EINA_LIST_FREE(borders, bd)
1245 e_object_unref(E_OBJECT(bd));
1249 _e_int_menus_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1258 if (e_config->clientlist_warp_to_iconified_desktop == 1)
1259 e_desk_show(bd->desk);
1260 if (!bd->lock_user_iconify)
1261 e_border_uniconify(bd);
1264 if (!bd->iconic) e_desk_show(bd->desk);
1265 if (!bd->lock_user_stacking) e_border_raise(bd);
1266 if (!bd->lock_focus_out)
1268 if (e_config->focus_policy != E_FOCUS_CLICK)
1269 ecore_x_pointer_warp(bd->zone->container->win,
1270 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
1271 e_border_focus_set(bd, 1, 1);
1276 _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
1283 o = e_icon_add(m->evas);
1284 e_icon_object_set(o, e_border_icon_add(bd, m->evas));
1285 mi->icon_object = o;
1289 _e_int_menus_clients_cleanup_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1293 act = e_action_find("cleanup_windows");
1294 if (act) act->func.go(E_OBJECT(m->zone), NULL);
1298 _e_int_menus_lost_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1301 Eina_List *l, *borders = NULL;
1304 E_Zone *zone = NULL;
1306 e_menu_pre_activate_callback_set(m, NULL, NULL);
1307 root = e_menu_root_get(m);
1308 /* get the current clients */
1309 if (root) zone = root->zone;
1310 borders = e_border_lost_windows_get(zone);
1314 /* FIXME here we want nothing, but that crashes!!! */
1315 mi = e_menu_item_new(m);
1316 e_menu_item_label_set(mi, _("(No Windows)"));
1319 EINA_LIST_FOREACH(borders, l, bd)
1321 const char *title = "";
1323 title = e_border_name_get(bd);
1324 mi = e_menu_item_new(m);
1325 if ((title) && (title[0]))
1326 e_menu_item_label_set(mi, title);
1328 e_menu_item_label_set(mi, _("No name!!"));
1329 /* ref the border as we implicitly unref it in the callback */
1330 e_object_ref(E_OBJECT(bd));
1331 e_menu_item_callback_set(mi, _e_int_menus_lost_clients_item_cb, bd);
1333 e_util_desktop_menu_item_icon_add(bd->desktop, 24, mi);
1335 e_object_free_attach_func_set(E_OBJECT(m),
1336 _e_int_menus_lost_clients_free_hook);
1337 e_object_data_set(E_OBJECT(m), borders);
1341 _e_int_menus_lost_clients_free_hook(void *obj)
1348 borders = e_object_data_get(E_OBJECT(m));
1349 EINA_LIST_FREE(borders, bd)
1350 e_object_unref(E_OBJECT(bd));
1354 _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1356 E_Border *bd = data;
1359 if (bd->iconic) e_border_uniconify(bd);
1360 if (bd->desk) e_desk_show(bd->desk);
1361 e_border_center(bd);
1363 if (!bd->lock_focus_out)
1364 e_border_focus_set(bd, 1, 1);
1368 _e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation)
1370 E_Int_Menu_Augmentation *aug;
1374 if ((!augmentation) || (!m)) return;
1375 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1376 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1379 EINA_LIST_FOREACH(augmentation, l, aug)
1380 if (aug->add.func) aug->add.func(aug->add.data, m);
1384 _e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation)
1386 E_Int_Menu_Augmentation *aug;
1390 if ((!augmentation) || (!m)) return;
1391 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1392 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1395 EINA_LIST_FOREACH(augmentation, l, aug)
1396 if (aug->del.func) aug->del.func(aug->del.data, m);
1400 _e_int_menus_shelves_pre_cb(void *data __UNUSED__, E_Menu *m)
1403 Eina_List *l, *shelves = NULL;
1408 e_menu_pre_activate_callback_set(m, NULL, NULL);
1409 con = e_container_current_get(e_manager_current_get());
1410 zone = e_zone_current_get(con);
1412 /* get the current clients */
1413 shelves = e_shelf_list();
1417 /* FIXME here we want nothing, but that crashes!!! */
1418 mi = e_menu_item_new(m);
1419 e_menu_item_label_set(mi, _("(No Shelves)"));
1421 EINA_LIST_FOREACH(shelves, l, s)
1427 if (s->zone->num != zone->num) continue;
1428 if (s->cfg->container != (int) con->num) continue;
1430 name = e_shelf_orient_string_get (s);
1431 snprintf(buf, sizeof(buf), "Shelf %s", name);
1433 mi = e_menu_item_new(m);
1434 e_menu_item_label_set(mi, buf);
1435 e_menu_item_callback_set(mi, _e_int_menus_shelves_item_cb, s);
1436 switch (s->cfg->orient)
1438 case E_GADCON_ORIENT_LEFT:
1439 e_util_menu_item_theme_icon_set(mi, "preferences-position-left");
1441 case E_GADCON_ORIENT_RIGHT:
1442 e_util_menu_item_theme_icon_set(mi, "preferences-position-right");
1444 case E_GADCON_ORIENT_TOP:
1445 e_util_menu_item_theme_icon_set(mi, "preferences-position-top");
1447 case E_GADCON_ORIENT_BOTTOM:
1448 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom");
1450 case E_GADCON_ORIENT_CORNER_TL:
1451 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-left");
1453 case E_GADCON_ORIENT_CORNER_TR:
1454 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-right");
1456 case E_GADCON_ORIENT_CORNER_BL:
1457 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-left");
1459 case E_GADCON_ORIENT_CORNER_BR:
1460 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-right");
1462 case E_GADCON_ORIENT_CORNER_LT:
1463 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-top");
1465 case E_GADCON_ORIENT_CORNER_RT:
1466 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-top");
1468 case E_GADCON_ORIENT_CORNER_LB:
1469 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-bottom");
1471 case E_GADCON_ORIENT_CORNER_RB:
1472 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-bottom");
1475 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
1479 mi = e_menu_item_new(m);
1480 e_menu_item_separator_set(mi, 1);
1482 mi = e_menu_item_new(m);
1483 e_menu_item_label_set(mi, _("Add A Shelf"));
1484 e_util_menu_item_theme_icon_set(mi, "list-add");
1485 e_menu_item_callback_set(mi, _e_int_menus_shelves_add_cb, NULL);
1489 mi = e_menu_item_new(m);
1490 e_menu_item_label_set(mi, _("Delete A Shelf"));
1491 e_util_menu_item_theme_icon_set(mi, "list-remove");
1492 e_menu_item_callback_set(mi, _e_int_menus_shelves_del_cb, NULL);
1497 _e_int_menus_shelves_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1502 e_int_shelf_config(s);
1506 _e_int_menus_shelves_add_cb(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1512 con = e_container_current_get(e_manager_current_get());
1513 zone = e_zone_current_get(con);
1514 cs = E_NEW(E_Config_Shelf, 1);
1515 cs->name = eina_stringshare_add("shelf");
1516 cs->container = con->num;
1517 cs->zone = zone->id;
1520 cs->orient = E_GADCON_ORIENT_CORNER_BR;
1523 cs->style = eina_stringshare_add("default");
1526 e_config->shelves = eina_list_append(e_config->shelves, cs);
1527 e_config_save_queue();
1529 e_shelf_config_update();
1533 _e_int_menus_shelves_del_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1535 e_configure_registry_call("extensions/shelves", m->zone->container, NULL);
1539 _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi)
1541 Efreet_Desktop *desktop;
1545 if ((!entry) || (!mi)) return;
1547 desktop = entry->desktop;
1548 if ((e_config->menu_eap_name_show) && (entry->name)) opt |= 0x4;
1551 if ((e_config->menu_eap_generic_show) && (desktop->generic_name) &&
1552 (desktop->generic_name[0] != 0))
1554 if ((e_config->menu_eap_comment_show) && (desktop->comment) &&
1555 (desktop->comment[0] != 0))
1560 snprintf(label, sizeof(label), "%s (%s) [%s]", entry->name,
1561 desktop->generic_name, desktop->comment);
1562 else if (opt == 0x6)
1563 snprintf(label, sizeof(label), "%s (%s)", entry->name,
1564 desktop->generic_name);
1565 else if (opt == 0x5)
1566 snprintf(label, sizeof(label), "%s [%s]", entry->name, desktop->comment);
1567 else if (opt == 0x4)
1568 snprintf(label, sizeof(label), "%s", entry->name);
1569 else if (opt == 0x3)
1570 snprintf(label, sizeof(label), "%s [%s]", desktop->generic_name,
1572 else if (opt == 0x2)
1573 snprintf(label, sizeof(label), "%s", desktop->generic_name);
1574 else if (opt == 0x1)
1575 snprintf(label, sizeof(label), "%s", desktop->comment);
1577 snprintf(label, sizeof(label), "%s", entry->name);
1579 e_menu_item_label_set(mi, label);