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_config_cb(void *data, E_Menu *m, E_Menu_Item *mi);
62 static void _e_int_menus_main_showhide(void *data, E_Menu *m, E_Menu_Item *mi);
63 static void _e_int_menus_main_restart(void *data, E_Menu *m, E_Menu_Item *mi);
64 static void _e_int_menus_main_exit(void *data, E_Menu *m, E_Menu_Item *mi);
65 static void _e_int_menus_desktops_free_hook(void *obj);
66 static void _e_int_menus_desk_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
67 static void _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi);
69 //static void _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__);
71 /* local subsystem globals */
72 static Eina_Hash *_e_int_menus_augmentation = NULL;
73 static Eina_List *_e_int_menus_augmentation_disabled = NULL;
76 _e_int_menus_augmentation_find(const char *key)
81 if ((!_e_int_menus_augmentation) || (!key)) return NULL;
83 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
84 if (!strcmp(data, key)) return NULL;
85 return eina_hash_find(_e_int_menus_augmentation, key);
88 /* externally accessible functions */
90 e_int_menus_main_new(void)
98 dat = calloc(1, sizeof(Main_Data));
100 e_menu_title_set(m, _("Main"));
102 e_object_data_set(E_OBJECT(m), dat);
103 e_object_del_attach_func_set(E_OBJECT(m), _e_int_menus_main_del_hook);
105 e_menu_category_set(m, "main");
107 l = _e_int_menus_augmentation_find("main/0");
108 if (l) _e_int_menus_augmentation_add(m, l);
110 if (e_config->menu_favorites_show)
112 subm = e_int_menus_favorite_apps_new();
116 mi = e_menu_item_new(m);
117 e_menu_item_label_set(mi, _("Favorite Applications"));
118 e_util_menu_item_theme_icon_set(mi, "user-bookmarks");
119 e_menu_item_submenu_set(mi, subm);
123 if (e_config->menu_apps_show)
125 subm = e_int_menus_all_apps_new();
126 dat->all_apps = subm;
127 mi = e_menu_item_new(m);
128 e_menu_item_label_set(mi, _("Applications"));
129 e_util_menu_item_theme_icon_set(mi, "preferences-applications");
130 e_menu_item_submenu_set(mi, subm);
133 l = _e_int_menus_augmentation_find("main/1");
134 if (l) _e_int_menus_augmentation_add(m, l);
136 mi = e_menu_item_new(m);
137 e_menu_item_separator_set(mi, 1);
139 l = _e_int_menus_augmentation_find("main/2");
140 if (l) _e_int_menus_augmentation_add(m, l);
142 subm = e_int_menus_desktops_new();
143 dat->desktops = subm;
144 mi = e_menu_item_new(m);
145 e_menu_item_label_set(mi, _("Desktop"));
146 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
147 e_menu_item_submenu_set(mi, subm);
149 subm = e_int_menus_clients_new();
151 mi = e_menu_item_new(m);
152 e_menu_item_label_set(mi, _("Windows"));
153 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
154 e_menu_item_submenu_set(mi, subm);
155 e_object_data_set(E_OBJECT(subm), dat);
157 #if 0 // lost windows already handled inside "Windows" from main menu.
158 subm = e_int_menus_lost_clients_new();
159 e_object_data_set(E_OBJECT(subm), dat);
160 dat->lost_clients = subm;
161 mi = e_menu_item_new(m);
162 e_menu_item_label_set(mi, _("Lost Windows"));
163 e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost");
164 e_menu_item_submenu_set(mi, subm);
167 l = _e_int_menus_augmentation_find("main/3");
168 if (l) _e_int_menus_augmentation_add(m, l);
170 mi = e_menu_item_new(m);
171 e_menu_item_separator_set(mi, 1);
173 l = _e_int_menus_augmentation_find("main/4");
174 if (l) _e_int_menus_augmentation_add(m, l);
177 dat->enlightenment = subm;
179 l = _e_int_menus_augmentation_find("enlightenment/0");
180 if (l) _e_int_menus_augmentation_add(subm, l);
182 mi = e_menu_item_new(m);
183 e_menu_item_label_set(mi, _("Enlightenment"));
184 e_util_menu_item_theme_icon_set(mi, "enlightenment");
185 e_menu_item_submenu_set(mi, subm);
187 mi = e_menu_item_new(subm);
188 e_menu_item_label_set(mi, _("About"));
189 e_util_menu_item_theme_icon_set(mi, "help-about");
190 e_menu_item_callback_set(mi, _e_int_menus_main_about, NULL);
192 mi = e_menu_item_new(subm);
193 e_menu_item_label_set(mi, _("Theme"));
194 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-theme");
195 e_menu_item_callback_set(mi, _e_int_menus_themes_about, NULL);
197 l = _e_int_menus_augmentation_find("enlightenment/1");
198 if (l) _e_int_menus_augmentation_add(subm, l);
200 mi = e_menu_item_new(subm);
201 e_menu_item_separator_set(mi, 1);
203 l = _e_int_menus_augmentation_find("enlightenment/2");
204 if (l) _e_int_menus_augmentation_add(subm, l);
206 mi = e_menu_item_new(subm);
207 e_menu_item_label_set(mi, _("Restart"));
208 e_util_menu_item_theme_icon_set(mi, "system-restart");
209 e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL);
211 mi = e_menu_item_new(subm);
212 e_menu_item_label_set(mi, _("Exit"));
213 e_util_menu_item_theme_icon_set(mi, "application-exit");
214 e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL);
216 l = _e_int_menus_augmentation_find("enlightenment/3");
217 if (l) _e_int_menus_augmentation_add(subm, l);
219 l = _e_int_menus_augmentation_find("main/5");
220 if (l) _e_int_menus_augmentation_add(m, l);
222 mi = e_menu_item_new(m);
223 e_menu_item_separator_set(mi, 1);
225 l = _e_int_menus_augmentation_find("main/6");
226 if (l) _e_int_menus_augmentation_add(m, l);
228 subm = e_int_menus_config_new();
230 mi = e_menu_item_new(m);
231 e_menu_item_label_set(mi, _("Settings"));
232 e_menu_item_callback_set(mi, _e_int_menus_config_cb, NULL);
233 e_util_menu_item_theme_icon_set(mi, "preferences-system");
234 e_menu_item_submenu_set(mi, subm);
236 l = _e_int_menus_augmentation_find("main/7");
237 if (l) _e_int_menus_augmentation_add(m, l);
239 l = eina_hash_find(_e_int_menus_augmentation, "main/8");
243 mi = e_menu_item_new(m);
244 e_menu_item_separator_set(mi, 1);
245 _e_int_menus_augmentation_add(m, l);
248 l = eina_hash_find(_e_int_menus_augmentation, "main/9");
253 mi = e_menu_item_new(m);
254 e_menu_item_separator_set(mi, 1);
256 _e_int_menus_augmentation_add(m, l);
263 e_int_menus_apps_new(const char *dir)
268 if (dir) e_object_data_set(E_OBJECT(m), strdup(dir));
269 e_menu_pre_activate_callback_set(m, _e_int_menus_apps_start, NULL);
270 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_apps_free_hook);
275 e_int_menus_desktops_new(void)
283 mi = e_menu_item_new(m);
284 e_menu_item_label_set(mi, _("Virtual"));
285 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
286 e_menu_pre_activate_callback_set(subm, _e_int_menus_virtuals_pre_cb, NULL);
287 e_menu_item_submenu_set(mi, subm);
290 mi = e_menu_item_new(m);
291 e_menu_item_label_set(mi, _("Shelves"));
292 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
293 e_menu_pre_activate_callback_set(subm, _e_int_menus_shelves_pre_cb, NULL);
294 e_menu_item_submenu_set(mi, subm);
296 mi = e_menu_item_new(m);
297 e_menu_item_separator_set(mi, 1);
299 mi = e_menu_item_new(m);
300 e_menu_item_label_set(mi, _("Show/Hide All Windows"));
301 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
302 e_menu_item_callback_set(mi, _e_int_menus_main_showhide, NULL);
304 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_desktops_free_hook);
309 e_int_menus_favorite_apps_new(void)
314 e_user_dir_concat_static(buf, "applications/menu/favorite.menu");
315 if (ecore_file_exists(buf)) m = e_int_menus_apps_new(buf);
320 e_int_menus_all_apps_new(void)
324 m = e_int_menus_apps_new(NULL);
329 e_int_menus_config_new(void)
334 e_menu_pre_activate_callback_set(m, _e_int_menus_config_pre_cb, NULL);
339 e_int_menus_clients_new(void)
344 e_menu_pre_activate_callback_set(m, _e_int_menus_clients_pre_cb, NULL);
349 e_int_menus_lost_clients_new(void)
354 e_menu_pre_activate_callback_set(m, _e_int_menus_lost_clients_pre_cb, NULL);
358 EAPI E_Int_Menu_Augmentation *
359 e_int_menus_menu_augmentation_add_sorted(const char *menu,
360 const char *sort_key,
361 void (*func_add)(void *data, E_Menu *m),
363 void (*func_del)(void *data, E_Menu *m),
366 E_Int_Menu_Augmentation *maug;
368 Eina_Bool old = EINA_FALSE;
370 maug = E_NEW(E_Int_Menu_Augmentation, 1);
371 if (!maug) return NULL;
373 maug->sort_key = eina_stringshare_add(sort_key);
375 maug->add.func = func_add;
376 maug->add.data = data_add;
378 maug->del.func = func_del;
379 maug->del.data = data_del;
381 if (_e_int_menus_augmentation)
383 if ((l = eina_hash_find(_e_int_menus_augmentation, menu)))
388 _e_int_menus_augmentation = eina_hash_string_superfast_new(NULL);
393 if ((!l) || (!maug->sort_key))
394 l = eina_list_append(l, maug);
397 E_Int_Menu_Augmentation *m2;
400 /* keep list sorted, those missing sort_key at the end. */
401 EINA_LIST_FOREACH(l, l2, m2)
405 if (strcasecmp(maug->sort_key, m2->sort_key) < 0)
410 l = eina_list_prepend_relative_list(l, maug, l2);
412 l = eina_list_append(l, maug);
416 eina_hash_modify(_e_int_menus_augmentation, menu, l);
418 eina_hash_add(_e_int_menus_augmentation, menu, l);
423 EAPI E_Int_Menu_Augmentation *
424 e_int_menus_menu_augmentation_add(const char *menu,
425 void (*func_add)(void *data, E_Menu *m),
427 void (*func_del)(void *data, E_Menu *m),
430 return e_int_menus_menu_augmentation_add_sorted
431 (menu, NULL, func_add, data_add, func_del, data_del);
435 e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *maug)
439 if (!_e_int_menus_augmentation)
441 eina_stringshare_del(maug->sort_key);
446 l = eina_hash_find(_e_int_menus_augmentation, menu);
449 l = eina_list_remove(l, maug);
452 eina_hash_modify(_e_int_menus_augmentation, menu, l);
454 eina_hash_del_by_key(_e_int_menus_augmentation, menu);
456 eina_stringshare_del(maug->sort_key);
461 e_int_menus_menu_augmentation_point_disabled_set(const char *menu, Eina_Bool disabled)
466 _e_int_menus_augmentation_disabled =
467 eina_list_append(_e_int_menus_augmentation_disabled, menu);
471 _e_int_menus_augmentation_disabled =
472 eina_list_remove(_e_int_menus_augmentation_disabled, menu);
476 /* local subsystem functions */
478 _e_int_menus_main_del_hook(void *obj)
484 dat = e_object_data_get(E_OBJECT(obj));
485 if (dat->apps) e_object_del(E_OBJECT(dat->apps));
486 if (dat->all_apps) e_object_del(E_OBJECT(dat->all_apps));
487 if (dat->desktops) e_object_del(E_OBJECT(dat->desktops));
488 if (dat->clients) e_object_del(E_OBJECT(dat->clients));
489 if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients));
490 if (dat->enlightenment) e_object_del(E_OBJECT(dat->enlightenment));
491 if (dat->config) e_object_del(E_OBJECT(dat->config));
494 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/0"));
495 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/1"));
496 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/2"));
497 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/3"));
498 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/4"));
499 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/5"));
500 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/6"));
501 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/7"));
502 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/8"));
503 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/9"));
504 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/10"));
505 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/11"));
509 _e_int_menus_main_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
513 about = e_about_new(e_container_current_get(e_manager_current_get()));
514 if (about) e_about_show(about);
518 _e_int_menus_themes_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
520 E_Theme_About *about;
522 about = e_theme_about_new(e_container_current_get(e_manager_current_get()));
523 if (about) e_theme_about_show(about);
528 _e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
530 e_fwin_new(m->zone->container, "favorites", "/");
535 _e_int_menus_config_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
539 act = e_action_find("configuration");
540 if (act) act->func.go(E_OBJECT(m->zone), NULL);
544 _e_int_menus_main_showhide(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
548 act = e_action_find("desk_deskshow_toggle");
549 if (act) act->func.go(E_OBJECT(m->zone), NULL);
553 _e_int_menus_main_restart(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
557 a = e_action_find("restart");
558 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
562 _e_int_menus_main_exit(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
566 a = e_action_find("exit");
567 if ((a) && (a->func.go)) a->func.go(NULL, NULL);
571 _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu)
580 EINA_LIST_FOREACH(menu->entries, l, entry)
582 mi = e_menu_item_new(m);
584 _e_int_menus_item_label_set(entry, mi);
588 if (entry->icon[0] == '/')
589 e_menu_item_icon_file_set(mi, entry->icon);
591 e_util_menu_item_theme_icon_set(mi, entry->icon);
593 if (entry->type == EFREET_MENU_ENTRY_SEPARATOR)
594 e_menu_item_separator_set(mi, 1);
595 else if (entry->type == EFREET_MENU_ENTRY_DESKTOP)
597 e_menu_item_callback_set(mi, _e_int_menus_apps_run,
599 e_menu_item_drag_callback_set(mi, _e_int_menus_apps_drag,
602 else if (entry->type == EFREET_MENU_ENTRY_MENU)
607 e_menu_pre_activate_callback_set(subm,
608 _e_int_menus_apps_start,
610 e_menu_item_submenu_set(mi, subm);
611 e_object_free_attach_func_set(E_OBJECT(subm),
612 _e_int_menus_apps_free_hook2);
614 /* TODO: Highlight header
615 else if (entry->type == EFREET_MENU_ENTRY_HEADER)
621 mi = e_menu_item_new(m);
622 e_menu_item_label_set(mi, _("(No Applications)"));
627 _e_int_menus_apps_start(void *data, E_Menu *m)
636 dir = e_object_data_get(E_OBJECT(m));
639 menu = efreet_menu_parse(dir);
642 else menu = efreet_menu_get();
643 e_object_data_set(E_OBJECT(m), menu);
644 e_object_free_attach_func_set(E_OBJECT(m),
645 _e_int_menus_apps_free_hook2);
647 if (menu) _e_int_menus_apps_scan(m, menu);
648 e_menu_pre_activate_callback_set(m, NULL, NULL);
652 _e_int_menus_apps_free_hook(void *obj)
658 dir = e_object_data_get(E_OBJECT(m));
663 _e_int_menus_apps_free_hook2(void *obj)
667 Eina_List *l, *l_next;
671 // XXX TODO: this should be automatic in e_menu, just get references right!
672 // XXX TODO: fix references and remove me!!!
673 EINA_LIST_FOREACH_SAFE (m->items, l, l_next, mi)
676 e_object_del(E_OBJECT(mi->submenu));
678 menu = e_object_data_get(E_OBJECT(m));
679 if (menu) efreet_menu_free(menu);
683 _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi __UNUSED__)
685 Efreet_Desktop *desktop;
688 e_exec(m->zone, desktop, NULL, NULL, "menu/apps");
693 _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__)
695 Efreet_Desktop *desktop;
697 desktop = drag->data;
698 efreet_desktop_free(desktop);
703 _e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi)
705 Efreet_Desktop *desktop;
713 Evas_Object *o = NULL;
714 Evas_Coord x, y, w, h;
716 const char *drag_types[] = { "enlightenment/desktop" };
718 evas_object_geometry_get(mi->icon_object, &x, &y, &w, &h);
719 efreet_desktop_ref(desktop);
720 drag = e_drag_new(m->zone->container, x, y, drag_types, 1, desktop, -1,
724 o = e_util_desktop_icon_add(desktop, size, e_drag_evas_get(drag));
725 e_drag_object_set(drag, o);
726 e_drag_resize(drag, w, h);
727 e_drag_start(drag, mi->drag.x + w, mi->drag.y + h);
732 _e_int_menus_virtuals_pre_cb(void *data __UNUSED__, E_Menu *m)
737 e_menu_pre_activate_callback_set(m, NULL, NULL);
739 root = e_menu_root_get(m);
740 if ((root) && (root->zone))
746 for (i = 0; i < (zone->desk_x_count * zone->desk_y_count); i++)
750 desk = zone->desks[i];
751 mi = e_menu_item_new(m);
752 e_menu_item_radio_group_set(mi, 1);
753 e_menu_item_radio_set(mi, 1);
754 e_menu_item_label_set(mi, desk->name);
755 if (desk == e_desk_current_get(zone))
756 e_menu_item_toggle_set(mi, 1);
757 e_menu_item_callback_set(mi, _e_int_menus_virtuals_item_cb, desk);
758 e_menu_item_realize_callback_set(mi, _e_int_menus_virtuals_icon_cb, desk);
762 if (e_configure_registry_exists("screen/virtual_desktops"))
764 mi = e_menu_item_new(m);
765 e_menu_item_separator_set(mi, 1);
767 mi = e_menu_item_new(m);
768 e_menu_item_label_set(mi, _("Set Virtual Desktops"));
769 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
770 e_menu_item_callback_set(mi, _e_int_menus_desk_item_cb, NULL);
775 _e_int_menus_desktops_free_hook(void *obj)
778 Eina_List *l, *l_next;
782 // XXX TODO: this should be automatic in e_menu, just get references right!
783 // XXX TODO: fix references and remove me!!!
784 EINA_LIST_FOREACH_SAFE (m->items, l, l_next, mi)
787 e_object_del(E_OBJECT(mi->submenu));
792 _e_int_menus_desk_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
794 e_configure_registry_call("screen/virtual_desktops", m->zone->container, NULL);
798 _e_int_menus_virtuals_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
802 if (!(desk = data)) return;
807 _e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
815 E_OBJECT_CHECK(desk);
818 th = (tw * desk->zone->h) / desk->zone->w;
820 bgfile = e_bg_file_get(desk->zone->container->num, desk->zone->num, desk->x, desk->y);
821 o = e_thumb_icon_add(m->evas);
822 e_thumb_icon_file_set(o, bgfile, "e/desktop/background");
823 e_thumb_icon_size_set(o, tw, th);
824 e_thumb_icon_begin(o);
829 _e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
834 e_menu_pre_activate_callback_set(m, NULL, NULL);
836 l = _e_int_menus_augmentation_find("config/0");
839 _e_int_menus_augmentation_add(m, l);
840 if (_e_int_menus_augmentation_find("config/1"))
842 mi = e_menu_item_new(m);
843 e_menu_item_separator_set(mi, 1);
847 l = _e_int_menus_augmentation_find("config/1");
848 if (l) _e_int_menus_augmentation_add(m, l);
850 l = _e_int_menus_augmentation_find("config/2");
853 mi = e_menu_item_new(m);
854 e_menu_item_separator_set(mi, 1);
855 _e_int_menus_augmentation_add(m, l);
858 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_config_free_hook);
862 _e_int_menus_config_free_hook(void *obj)
867 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/0"));
868 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/1"));
869 _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/2"));
873 _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2)
885 j = bd1->desk->y * 12 + bd1->desk->x;
886 k = bd2->desk->y * 12 + bd2->desk->x;
889 if (j < k) return -1;
890 return -1; /* Returning '-1' on equal is intentional */
894 _e_int_menus_clients_group_class_cb(const void *d1, const void *d2)
896 const E_Border *bd1, *bd2;
904 if (!bd1->client.icccm.class)
906 if (!bd2->client.icccm.class)
909 return strcmp(bd1->client.icccm.class, bd2->client.icccm.class) > 0 ? 1 : -1;
913 _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2)
915 const E_Border *bd1, *bd2;
916 const char *name1, *name2;
923 name1 = e_border_name_get(bd1);
924 name2 = e_border_name_get(bd2);
926 if (strcasecmp(name1, name2) > 0) return 1;
927 if (strcasecmp(name1, name2) < 0) return -1;
932 _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2)
934 const E_Border *bd1, *bd2;
942 if (bd1->layer < bd2->layer) return 1;
943 if (bd1->layer > bd2->layer) return -1;
948 _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m)
950 if (eina_list_count(borders) > 0)
954 E_Menu_Item *mi = NULL;
956 mi = e_menu_item_new(m);
957 e_menu_item_separator_set(mi, 1);
959 EINA_LIST_FOREACH(borders, l, bd)
960 _e_int_menus_clients_item_create(bd, m);
965 _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m)
967 Eina_List *l = NULL, *ico = NULL;
970 E_Menu_Item *mi = NULL;
974 EINA_LIST_FOREACH(borders, l, bd)
977 (e_config->clientlist_separate_iconified_apps == E_CLIENTLIST_GROUPICONS_SEP))
979 ico = eina_list_append(ico, bd);
983 if (((strcmp(class, bd->client.icccm.class) != 0) &&
984 e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
986 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
988 if ((subm) && (mi)) e_menu_item_submenu_set(mi, subm);
989 mi = e_menu_item_new(m);
990 e_menu_item_label_set(mi, bd->client.icccm.class);
991 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
996 mi = e_menu_item_new(m);
997 e_menu_item_separator_set(mi, 1);
1000 class = strdup(bd->client.icccm.class);
1002 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1003 _e_int_menus_clients_item_create(bd, subm);
1005 _e_int_menus_clients_item_create(bd, m);
1008 if ((e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1010 e_menu_item_submenu_set(mi, subm);
1012 _e_int_menus_clients_menu_add_iconified(ico, m);
1014 if (class) free(class);
1018 _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m)
1020 E_Desk *desk = NULL;
1021 Eina_List *l = NULL, *alt = NULL, *ico = NULL;
1024 E_Menu_Item *mi = NULL;
1026 /* Deal with present desk first */
1027 EINA_LIST_FOREACH(borders, l, bd)
1029 if (bd->iconic && e_config->clientlist_separate_iconified_apps && E_CLIENTLIST_GROUPICONS_SEP)
1031 ico = eina_list_append(ico, bd);
1035 if (bd->desk != curr_desk)
1037 if ((!bd->iconic) ||
1038 (bd->iconic && e_config->clientlist_separate_iconified_apps ==
1039 E_CLIENTLIST_GROUPICONS_OWNER))
1041 alt = eina_list_append(alt, bd);
1046 _e_int_menus_clients_item_create(bd, m);
1051 if (eina_list_count(alt) > 0)
1053 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1055 mi = e_menu_item_new(m);
1056 e_menu_item_separator_set(mi, 1);
1059 EINA_LIST_FOREACH(alt, l, bd)
1061 if ((bd->desk != desk) &&
1062 (e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE))
1064 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1066 if (subm && mi) e_menu_item_submenu_set(mi, subm);
1067 mi = e_menu_item_new(m);
1068 e_menu_item_label_set(mi, bd->desk->name);
1069 e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
1070 subm = e_menu_new();
1074 mi = e_menu_item_new(m);
1075 e_menu_item_separator_set(mi, 1);
1079 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)
1080 _e_int_menus_clients_item_create(bd, subm);
1082 _e_int_menus_clients_item_create(bd, m);
1084 if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU
1086 e_menu_item_submenu_set(mi, subm);
1089 _e_int_menus_clients_menu_add_iconified(ico, m);
1093 _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m)
1095 Eina_List *l = NULL, *ico = NULL;
1098 EINA_LIST_FOREACH(borders, l, bd)
1100 if ((bd->iconic) && (e_config->clientlist_separate_iconified_apps) &&
1101 (E_CLIENTLIST_GROUPICONS_SEP))
1103 ico = eina_list_append(ico, bd);
1106 _e_int_menus_clients_item_create(bd, m);
1108 _e_int_menus_clients_menu_add_iconified(ico, m);
1112 _e_int_menus_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1115 E_Menu_Item *mi = NULL;
1116 Eina_List *l = NULL, *borders = NULL;
1118 E_Zone *zone = NULL;
1119 E_Desk *desk = NULL;
1122 e_menu_pre_activate_callback_set(m, NULL, NULL);
1123 /* get the current clients */
1124 zone = e_zone_current_get(e_container_current_get(e_manager_current_get()));
1125 desk = e_desk_current_get(zone);
1127 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_MOST_RECENT)
1128 l = e_border_focus_stack_get();
1130 l = e_border_client_list();
1131 EINA_LIST_FOREACH(l, l, border)
1133 if (border->user_skip_winlist) continue;
1134 if ((border->zone == zone) || (border->iconic) ||
1135 (border->zone != zone && e_config->clientlist_include_all_zones))
1136 borders = eina_list_append(borders, border);
1139 dat = (Main_Data *)e_object_data_get(E_OBJECT(m));
1140 if (!dat) e_menu_title_set(m, _("Windows"));
1144 /* FIXME here we want nothing, but that crashes!!! */
1145 mi = e_menu_item_new(m);
1146 e_menu_item_label_set(mi, _("(No Windows)"));
1151 /* Sort the borders */
1152 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ALPHA)
1153 borders = eina_list_sort(borders, eina_list_count(borders),
1154 _e_int_menus_clients_sort_alpha_cb);
1156 if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ZORDER)
1157 borders = eina_list_sort(borders, eina_list_count(borders),
1158 _e_int_menus_clients_sort_z_order_cb);
1160 /* Group the borders */
1161 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_DESK)
1163 borders = eina_list_sort(borders, eina_list_count(borders),
1164 _e_int_menus_clients_group_desk_cb);
1165 _e_int_menus_clients_add_by_desk(desk, borders, m);
1167 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_CLASS)
1169 borders = eina_list_sort(borders, eina_list_count(borders),
1170 _e_int_menus_clients_group_class_cb);
1171 _e_int_menus_clients_add_by_class(borders, m);
1173 if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_NONE)
1174 _e_int_menus_clients_add_by_none(borders, m);
1177 mi = e_menu_item_new(m);
1178 e_menu_item_separator_set(mi, 1);
1180 mi = e_menu_item_new(m);
1181 e_menu_item_label_set(mi, _("Cleanup Windows"));
1182 e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
1183 e_menu_item_callback_set(mi, _e_int_menus_clients_cleanup_cb, zone);
1187 mi = e_menu_item_new(m);
1188 e_menu_item_separator_set(mi, 1);
1190 subm = e_int_menus_lost_clients_new();
1191 e_object_data_set(E_OBJECT(subm), e_object_data_get(E_OBJECT(m)));
1192 dat->lost_clients = subm;
1193 mi = e_menu_item_new(m);
1194 e_menu_item_label_set(mi, _("Lost Windows"));
1195 e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost");
1196 e_menu_item_submenu_set(mi, subm);
1199 e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_clients_free_hook);
1200 e_object_data_set(E_OBJECT(m), borders);
1204 _e_int_menus_clients_title_abbrv(const char *title)
1208 max_len = e_config->clientlist_max_caption_len;
1209 if ((e_config->clientlist_limit_caption_len) && ((int)strlen(title) > max_len))
1212 const char *left, *right;
1214 abbv = calloc(E_CLIENTLIST_MAX_CAPTION_LEN + 4, sizeof(char));
1216 right = title + (strlen(title) - (max_len / 2));
1218 strncpy(abbv, left, max_len / 2);
1219 strncat(abbv, "...", 3);
1220 strncat(abbv, right, max_len / 2);
1229 _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m)
1234 title = _e_int_menus_clients_title_abbrv(e_border_name_get(bd));
1235 mi = e_menu_item_new(m);
1236 e_menu_item_check_set(mi, 1);
1237 if ((title) && (title[0]))
1238 e_menu_item_label_set(mi, title);
1240 e_menu_item_label_set(mi, _("No name!!"));
1241 /* ref the border as we implicitly unref it in the callback */
1242 e_object_ref(E_OBJECT(bd));
1243 /* e_object_breadcrumb_add(E_OBJECT(bd), "clients_menu");*/
1244 e_menu_item_callback_set(mi, _e_int_menus_clients_item_cb, bd);
1245 e_menu_item_realize_callback_set(mi, _e_int_menus_clients_icon_cb, bd);
1246 if (!bd->iconic) e_menu_item_toggle_set(mi, 1);
1250 _e_int_menus_clients_free_hook(void *obj)
1257 borders = e_object_data_get(E_OBJECT(m));
1258 EINA_LIST_FREE(borders, bd)
1259 e_object_unref(E_OBJECT(bd));
1263 _e_int_menus_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1272 if (e_config->clientlist_warp_to_iconified_desktop == 1)
1273 e_desk_show(bd->desk);
1274 if (!bd->lock_user_iconify)
1275 e_border_uniconify(bd);
1278 if (!bd->iconic) e_desk_show(bd->desk);
1279 if (!bd->lock_user_stacking) e_border_raise(bd);
1280 if (!bd->lock_focus_out)
1282 if (e_config->focus_policy != E_FOCUS_CLICK)
1283 ecore_x_pointer_warp(bd->zone->container->win,
1284 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
1285 e_border_focus_set(bd, 1, 1);
1290 _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
1296 mi->icon_object = e_border_icon_add(bd, m->evas);
1300 _e_int_menus_clients_cleanup_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1304 act = e_action_find("cleanup_windows");
1305 if (act) act->func.go(E_OBJECT(m->zone), NULL);
1309 _e_int_menus_lost_clients_pre_cb(void *data __UNUSED__, E_Menu *m)
1312 Eina_List *l, *borders = NULL;
1315 E_Zone *zone = NULL;
1317 e_menu_pre_activate_callback_set(m, NULL, NULL);
1318 root = e_menu_root_get(m);
1319 /* get the current clients */
1320 if (root) zone = root->zone;
1321 borders = e_border_lost_windows_get(zone);
1325 /* FIXME here we want nothing, but that crashes!!! */
1326 mi = e_menu_item_new(m);
1327 e_menu_item_label_set(mi, _("(No Windows)"));
1330 EINA_LIST_FOREACH(borders, l, bd)
1332 const char *title = "";
1334 title = e_border_name_get(bd);
1335 mi = e_menu_item_new(m);
1336 if ((title) && (title[0]))
1337 e_menu_item_label_set(mi, title);
1339 e_menu_item_label_set(mi, _("No name!!"));
1340 /* ref the border as we implicitly unref it in the callback */
1341 e_object_ref(E_OBJECT(bd));
1342 e_menu_item_callback_set(mi, _e_int_menus_lost_clients_item_cb, bd);
1344 e_util_desktop_menu_item_icon_add(bd->desktop, 24, mi);
1346 e_object_free_attach_func_set(E_OBJECT(m),
1347 _e_int_menus_lost_clients_free_hook);
1348 e_object_data_set(E_OBJECT(m), borders);
1352 _e_int_menus_lost_clients_free_hook(void *obj)
1359 borders = e_object_data_get(E_OBJECT(m));
1360 EINA_LIST_FREE(borders, bd)
1361 e_object_unref(E_OBJECT(bd));
1365 _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1367 E_Border *bd = data;
1370 if (bd->iconic) e_border_uniconify(bd);
1371 if (bd->desk) e_desk_show(bd->desk);
1372 e_border_center(bd);
1374 if (!bd->lock_focus_out)
1375 e_border_focus_set(bd, 1, 1);
1379 _e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation)
1381 E_Int_Menu_Augmentation *aug;
1385 if ((!augmentation) || (!m)) return;
1386 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1387 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1390 EINA_LIST_FOREACH(augmentation, l, aug)
1391 if (aug->add.func) aug->add.func(aug->add.data, m);
1395 _e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation)
1397 E_Int_Menu_Augmentation *aug;
1401 if ((!augmentation) || (!m)) return;
1402 EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
1403 if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
1406 EINA_LIST_FOREACH(augmentation, l, aug)
1407 if (aug->del.func) aug->del.func(aug->del.data, m);
1411 _e_int_menus_shelves_pre_cb(void *data __UNUSED__, E_Menu *m)
1414 Eina_List *l, *shelves = NULL;
1419 e_menu_pre_activate_callback_set(m, NULL, NULL);
1420 con = e_container_current_get(e_manager_current_get());
1421 zone = e_zone_current_get(con);
1423 /* get the current clients */
1424 shelves = e_shelf_list();
1425 EINA_LIST_FOREACH(shelves, l, es)
1431 if (es->zone->num != zone->num) continue;
1432 if (es->cfg->container != (int)con->num) continue;
1434 name = e_shelf_orient_string_get(es);
1435 snprintf(buf, sizeof(buf), "Shelf %s", name);
1437 mi = e_menu_item_new(m);
1438 e_menu_item_label_set(mi, buf);
1439 e_menu_item_callback_set(mi, _e_int_menus_shelves_item_cb, es);
1440 switch (es->cfg->orient)
1442 case E_GADCON_ORIENT_LEFT:
1443 e_util_menu_item_theme_icon_set(mi, "preferences-position-left");
1446 case E_GADCON_ORIENT_RIGHT:
1447 e_util_menu_item_theme_icon_set(mi, "preferences-position-right");
1450 case E_GADCON_ORIENT_TOP:
1451 e_util_menu_item_theme_icon_set(mi, "preferences-position-top");
1454 case E_GADCON_ORIENT_BOTTOM:
1455 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom");
1458 case E_GADCON_ORIENT_CORNER_TL:
1459 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-left");
1462 case E_GADCON_ORIENT_CORNER_TR:
1463 e_util_menu_item_theme_icon_set(mi, "preferences-position-top-right");
1466 case E_GADCON_ORIENT_CORNER_BL:
1467 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-left");
1470 case E_GADCON_ORIENT_CORNER_BR:
1471 e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-right");
1474 case E_GADCON_ORIENT_CORNER_LT:
1475 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-top");
1478 case E_GADCON_ORIENT_CORNER_RT:
1479 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-top");
1482 case E_GADCON_ORIENT_CORNER_LB:
1483 e_util_menu_item_theme_icon_set(mi, "preferences-position-left-bottom");
1486 case E_GADCON_ORIENT_CORNER_RB:
1487 e_util_menu_item_theme_icon_set(mi, "preferences-position-right-bottom");
1491 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
1497 mi = e_menu_item_new(m);
1498 e_menu_item_separator_set(mi, 1);
1501 mi = e_menu_item_new(m);
1502 e_menu_item_label_set(mi, _("Add a Shelf"));
1503 e_util_menu_item_theme_icon_set(mi, "list-add");
1504 e_menu_item_callback_set(mi, _e_int_menus_shelves_add_cb, NULL);
1508 mi = e_menu_item_new(m);
1509 e_menu_item_label_set(mi, _("Delete a Shelf"));
1510 e_util_menu_item_theme_icon_set(mi, "list-remove");
1511 e_menu_item_callback_set(mi, _e_int_menus_shelves_del_cb, NULL);
1516 _e_int_menus_shelves_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1521 e_int_shelf_config(s);
1525 _e_int_menus_shelves_add_cb(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1529 zone = e_util_zone_current_get(e_manager_current_get());
1530 e_shelf_new_dialog(zone);
1534 _e_int_menus_shelves_del_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1536 e_configure_registry_call("extensions/shelves", m->zone->container, NULL);
1540 _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi)
1542 Efreet_Desktop *desktop;
1546 if ((!entry) || (!mi)) return;
1548 desktop = entry->desktop;
1549 if ((e_config->menu_eap_name_show) && (entry->name)) opt |= 0x4;
1552 if ((e_config->menu_eap_generic_show) && (desktop->generic_name) &&
1553 (desktop->generic_name[0] != 0))
1555 if ((e_config->menu_eap_comment_show) && (desktop->comment) &&
1556 (desktop->comment[0] != 0))
1561 snprintf(label, sizeof(label), "%s (%s) [%s]", entry->name,
1562 desktop->generic_name, desktop->comment);
1563 else if (opt == 0x6)
1564 snprintf(label, sizeof(label), "%s (%s)", entry->name,
1565 desktop->generic_name);
1566 else if (opt == 0x5)
1567 snprintf(label, sizeof(label), "%s [%s]", entry->name, desktop->comment);
1568 else if (opt == 0x4)
1569 snprintf(label, sizeof(label), "%s", entry->name);
1570 else if (opt == 0x3)
1571 snprintf(label, sizeof(label), "%s [%s]", desktop->generic_name,
1573 else if (opt == 0x2)
1574 snprintf(label, sizeof(label), "%s", desktop->generic_name);
1575 else if (opt == 0x1)
1576 snprintf(label, sizeof(label), "%s", desktop->comment);
1578 snprintf(label, sizeof(label), "%s", entry->name);
1580 e_menu_item_label_set(mi, label);