From 3829bb230bb84eb98cfa923b3dfacd881ef49f95 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Wed, 21 Feb 2007 00:05:27 +0000 Subject: [PATCH] Ravenlocks 'Client List Configuration' patch. Allows users to configure different options for the Client List Menu: Grouping, Separators, Sort Order, etc, etc. SVN revision: 28406 --- src/bin/Makefile.am | 2 + src/bin/e_config.c | 25 +++- src/bin/e_config.h | 8 +- src/bin/e_configure.c | 1 + src/bin/e_includes.h | 1 + src/bin/e_int_config_clientlist.c | 137 ++++++++++++++++++ src/bin/e_int_config_clientlist.h | 26 ++++ src/bin/e_int_menus.c | 222 ++++++++++++++++++++++++------ 8 files changed, 376 insertions(+), 46 deletions(-) create mode 100644 src/bin/e_int_config_clientlist.c create mode 100644 src/bin/e_int_config_clientlist.h diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 57b3a0d8f..3e4af5a6f 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -185,6 +185,7 @@ e_filereg.h \ e_widget_desk_preview.h \ e_int_config_borders.h \ e_int_config_desk.h \ +e_int_config_clientlist.h \ e_fm_prop.h enlightenment_src = \ @@ -347,6 +348,7 @@ e_filereg.c \ e_int_config_borders.c \ e_int_config_desk.c \ e_fm_prop.c \ +e_int_config_clientlist.c \ $(ENLIGHTENMENTHEADERS) enlightenment_SOURCES = \ diff --git a/src/bin/e_config.c b/src/bin/e_config.c index 4282009fa..00c31fa1e 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -77,7 +77,8 @@ e_config_init(void) else _e_config_profile = strdup("default"); } - else _e_config_profile = strdup(_e_config_profile); + else + _e_config_profile = strdup(_e_config_profile); _e_config_gadcon_client_edd = E_CONFIG_DD_NEW("E_Config_Gadcon_Client", E_Config_Gadcon_Client); #undef T @@ -503,6 +504,12 @@ e_config_init(void) E_CONFIG_VAL(D, T, dpms_suspend_timeout, INT); E_CONFIG_VAL(D, T, dpms_off_timeout, INT); + E_CONFIG_VAL(D, T, clientlist_group_by, INT); + E_CONFIG_VAL(D, T, clientlist_separate_with, INT); + E_CONFIG_VAL(D, T, clientlist_sort_by, INT); + E_CONFIG_VAL(D, T, clientlist_separate_iconified_apps, INT); + E_CONFIG_VAL(D, T, clientlist_warp_to_iconified_desktop, INT); + E_CONFIG_VAL(D, T, border_raise_on_mouse_action, INT); E_CONFIG_VAL(D, T, border_raise_on_focus, INT); E_CONFIG_VAL(D, T, desk_flip_wrap, INT); @@ -1319,7 +1326,15 @@ e_config_init(void) e_config->screensaver_blanking = 2; e_config->screensaver_expose = 2; IFCFGEND; - + + IFCFG(0x0110); + e_config->clientlist_group_by = 0; + e_config->clientlist_separate_with = 0; + e_config->clientlist_sort_by = 0; + e_config->clientlist_separate_iconified_apps = 0; + e_config->clientlist_warp_to_iconified_desktop = 0; + IFCFGEND; + e_config->config_version = E_CONFIG_FILE_VERSION; #if 0 /* example of new config */ @@ -1432,6 +1447,12 @@ e_config_init(void) E_CONFIG_LIMIT(e_config->screensaver_blanking, 0, 2); E_CONFIG_LIMIT(e_config->screensaver_expose, 0, 2); + E_CONFIG_LIMIT(e_config->clientlist_group_by, 0, 2); + E_CONFIG_LIMIT(e_config->clientlist_separate_with, 0, 2); + E_CONFIG_LIMIT(e_config->clientlist_sort_by, 0, 3); + E_CONFIG_LIMIT(e_config->clientlist_separate_iconified_apps, 0, 2); + E_CONFIG_LIMIT(e_config->clientlist_warp_to_iconified_desktop, 0, 1); + /* FIXME: disabled auto apply because it causes problems */ e_config->cfgdlg_auto_apply = 0; /* FIXME: desklock personalized password id disabled for security reasons */ diff --git a/src/bin/e_config.h b/src/bin/e_config.h index cdcd78aca..cb98715df 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -52,7 +52,7 @@ typedef Eet_Data_Descriptor E_Config_DD; /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0x0109 +#define E_CONFIG_FILE_GENERATION 0x0110 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION) #define E_EVAS_ENGINE_DEFAULT 0 @@ -247,6 +247,12 @@ struct _E_Config int dpms_off_enable; int dpms_off_timeout; + int clientlist_group_by; + int clientlist_separate_with; + int clientlist_sort_by; + int clientlist_separate_iconified_apps; + int clientlist_warp_to_iconified_desktop; + int display_res_restore; // GUI int display_res_width; // GUI int display_res_height; // GUI diff --git a/src/bin/e_configure.c b/src/bin/e_configure.c index 7dde2e491..95a1e7955 100644 --- a/src/bin/e_configure.c +++ b/src/bin/e_configure.c @@ -431,6 +431,7 @@ _e_configure_fill_cat_list(void *data) _e_configure_item_add(cat, _("Applications Menu"), "enlightenment/applications", e_int_config_apps); #endif _e_configure_item_add(cat, _("Menu Settings"), "enlightenment/menu_settings", e_int_config_menus); + _e_configure_item_add(cat, _("Client List Menu"), "enlightenment/windows", e_int_config_clientlist); cat = _e_configure_category_add(eco, _("Language"), "enlightenment/intl"); _e_configure_item_add(cat, _("Language Settings"), "enlightenment/intl", e_int_config_intl); diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index decc03adb..8199491fe 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -161,4 +161,5 @@ #include "e_widget_desk_preview.h" #include "e_int_config_borders.h" #include "e_int_config_desk.h" +#include "e_int_config_clientlist.h" #include "e_fm_prop.h" diff --git a/src/bin/e_int_config_clientlist.c b/src/bin/e_int_config_clientlist.c new file mode 100644 index 000000000..0518ea321 --- /dev/null +++ b/src/bin/e_int_config_clientlist.c @@ -0,0 +1,137 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +static void _fill_data(E_Config_Dialog_Data *cfdata); +static void *_create_data(E_Config_Dialog *cfd); +static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static int _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); + +struct _E_Config_Dialog_Data +{ + int group_by; + int separate_with; + int sort_by; + int separate_iconified_apps; + int warp_to_iconified_desktop; +}; + +EAPI E_Config_Dialog * +e_int_config_clientlist(E_Container *con) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "_config_clientlist_dialog")) return NULL; + v = E_NEW(E_Config_Dialog_View, 1); + + v->create_cfdata = _create_data; + v->free_cfdata = _free_data; + v->basic.apply_cfdata = _basic_apply_data; + v->basic.create_widgets = _basic_create_widgets; + v->advanced.apply_cfdata = NULL; + v->advanced.create_widgets = NULL; + + cfd = e_config_dialog_new(con, _("Client List Settings"), "E", + "_config_clientlist_dialog", + "enlightenment/windows", 0, v, NULL); + return cfd; +} + +static void +_fill_data(E_Config_Dialog_Data *cfdata) +{ + cfdata->group_by = e_config->clientlist_group_by; + cfdata->separate_with = e_config->clientlist_separate_with; + cfdata->sort_by = e_config->clientlist_sort_by; + cfdata->separate_iconified_apps = e_config->clientlist_separate_iconified_apps; + cfdata->warp_to_iconified_desktop = e_config->clientlist_warp_to_iconified_desktop; +} + +static void * +_create_data(E_Config_Dialog *cfd) +{ + E_Config_Dialog_Data *cfdata; + + cfdata = E_NEW(E_Config_Dialog_Data, 1); + _fill_data(cfdata); + return cfdata; +} + +static void +_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + E_FREE(cfdata); +} + +static int +_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + e_config->clientlist_group_by = cfdata->group_by; + e_config->clientlist_separate_with = cfdata->separate_with; + e_config->clientlist_sort_by = cfdata->sort_by; + e_config->clientlist_separate_iconified_apps = cfdata->separate_iconified_apps; + e_config->clientlist_warp_to_iconified_desktop = cfdata->warp_to_iconified_desktop; + + return 1; +} + +static Evas_Object * +_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *o, *of, *ob; + E_Radio_Group *rg; + + o = e_widget_list_add(evas, 0, 0); + + of = e_widget_framelist_add(evas, _("Group By"), 0); + rg = e_widget_radio_group_new(&(cfdata->group_by)); + ob = e_widget_radio_add(evas, _("None"), E_CLIENTLIST_GROUP_NONE, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Desktop"), E_CLIENTLIST_GROUP_DESK, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Window Class"), E_CLIENTLIST_GROUP_CLASS, rg); + e_widget_framelist_object_append(of, ob); + e_widget_list_object_append(o, of, 1, 1, 0.5); + + of = e_widget_framelist_add(evas, _("Separate Groups By"), 0); + rg = e_widget_radio_group_new(&(cfdata->separate_with)); + ob = e_widget_radio_add(evas, _("None"), E_CLIENTLIST_GROUP_SEP_NONE, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Using separator bars"), E_CLIENTLIST_GROUP_SEP_BAR, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Using menus"), E_CLIENTLIST_GROUP_SEP_MENU, rg); + e_widget_framelist_object_append(of, ob); + e_widget_list_object_append(o, of, 1, 1, 0.5); + + of = e_widget_framelist_add(evas, _("Sort Order"), 0); + rg = e_widget_radio_group_new(&(cfdata->sort_by)); + ob = e_widget_radio_add(evas, _("None"), E_CLIENTLIST_SORT_NONE, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Alphabetical"), E_CLIENTLIST_SORT_ALPHA, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Most recently used"), E_CLIENTLIST_SORT_MOST_RECENT, rg); + e_widget_disabled_set(ob, 1); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Z-Order"), E_CLIENTLIST_SORT_ZORDER, rg); + e_widget_disabled_set(ob, 1); + e_widget_framelist_object_append(of, ob); + e_widget_list_object_append(o, of, 1, 1, 0.5); + + of = e_widget_framelist_add(evas, _("Iconified Windows"), 0); + rg = e_widget_radio_group_new(&(cfdata->separate_iconified_apps)); + ob = e_widget_radio_add(evas, _("Group with owning desktop"), E_CLIENTLIST_GROUPICONS_OWNER, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Group with current desktop"), E_CLIENTLIST_GROUPICONS_CURRENT, rg); + e_widget_framelist_object_append(of, ob); + ob = e_widget_radio_add(evas, _("Separate group"), E_CLIENTLIST_GROUPICONS_SEP, rg); + e_widget_disabled_set(ob, 1); + e_widget_framelist_object_append(of, ob); + ob = e_widget_check_add(evas, _("Warp to owning desktop"), &(cfdata->warp_to_iconified_desktop)); + e_widget_framelist_object_append(of, ob); + e_widget_list_object_append(o, of, 1, 1, 0.5); + + return o; +} diff --git a/src/bin/e_int_config_clientlist.h b/src/bin/e_int_config_clientlist.h new file mode 100644 index 000000000..9413b0913 --- /dev/null +++ b/src/bin/e_int_config_clientlist.h @@ -0,0 +1,26 @@ +#ifdef E_TYPEDEFS +#else +#ifndef E_INT_CONFIG_CLIENTLIST_H +#define E_INT_CONFIG_CLIENTLIST_H + +#define E_CLIENTLIST_GROUP_NONE 0 +#define E_CLIENTLIST_GROUP_DESK 1 +#define E_CLIENTLIST_GROUP_CLASS 2 + +#define E_CLIENTLIST_GROUP_SEP_NONE 0 +#define E_CLIENTLIST_GROUP_SEP_BAR 1 +#define E_CLIENTLIST_GROUP_SEP_MENU 2 + +#define E_CLIENTLIST_SORT_NONE 0 +#define E_CLIENTLIST_SORT_ALPHA 1 +#define E_CLIENTLIST_SORT_ZORDER 2 +#define E_CLIENTLIST_SORT_MOST_RECENT 3 + +#define E_CLIENTLIST_GROUPICONS_OWNER 0 +#define E_CLIENTLIST_GROUPICONS_CURRENT 1 +#define E_CLIENTLIST_GROUPICONS_SEP 2 + +EAPI E_Config_Dialog *e_int_config_clientlist(E_Container *con); + +#endif +#endif diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 90cd8b670..955002fca 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -890,7 +890,7 @@ _e_int_menus_sys_free_hook(void *obj) } static int -_e_int_menus_clients_sort_border_cb(void *d1, void *d2) +_e_int_menus_clients_group_desk_cb(void *d1, void *d2) { E_Border *bd1; E_Border *bd2; @@ -907,9 +907,152 @@ _e_int_menus_clients_sort_border_cb(void *d1, void *d2) if (j > k) return 1; if (j < k) return -1; + return -1; /* Returning '-1' on equal is intentional */ +} + +static int +_e_int_menus_clients_group_class_cb(void *d1, void *d2) +{ + E_Border *bd1; + E_Border *bd2; + + if (!d1) return 1; + if (!d2) return -1; + + bd1 = d1; + bd2 = d2; + + if (strcmp((const char*)bd1->client.icccm.class, (const char*)bd2->client.icccm.class) > 0) return 1; + if (strcmp((const char*)bd1->client.icccm.class, (const char*)bd2->client.icccm.class) < 0) return -1; + return -1; /* Returning '-1' on equal is intentional */ +} + +static int +_e_int_menus_clients_sort_alpha_cb(void *d1, void *d2) +{ + E_Border *bd1; + E_Border *bd2; + + if (!d1) return 1; + if (!d2) return -1; + + bd1 = d1; + bd2 = d2; + + if (strcasecmp(e_border_name_get(bd1), e_border_name_get(bd2)) > 0) return 1; + if (strcasecmp(e_border_name_get(bd1), e_border_name_get(bd2)) < 0) return -1; return 0; } +static void +_e_int_menus_clients_add_by_class(Evas_List *borders, E_Menu *m) +{ + Evas_List *l = NULL; + E_Menu *subm = NULL; + E_Menu_Item *mi; + char *class = NULL; + + class = strdup(""); + for (l = borders; l; l = l->next) + { + E_Border *bd; + bd = l->data; + if ( strcmp(class, bd->client.icccm.class) != 0 && e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE) + { + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) + { + if (subm && mi) + e_menu_item_submenu_set(mi, subm); + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, bd->client.icccm.class); + e_util_menu_item_edje_icon_set(mi, "enlightenment/windows"); + subm = e_menu_new(); + } + else + { + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + class = strdup(bd->client.icccm.class); + } + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) + _e_int_menus_clients_item_create(bd, subm); + else + _e_int_menus_clients_item_create(bd, m); + } + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU && subm && mi) + e_menu_item_submenu_set(mi, subm); +} + +static void +_e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Evas_List *borders, E_Menu *m) +{ + E_Desk *desk = NULL; + Evas_List *l = NULL, *alt = NULL; + E_Menu *subm; + E_Menu_Item *mi; + + /* Deal with present desk first */ + for (l = borders; l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if (bd->desk != curr_desk) + { + if (!bd->iconic || + (bd->iconic && e_config->clientlist_separate_iconified_apps == E_CLIENTLIST_GROUPICONS_OWNER)) + { + alt = evas_list_append(alt, bd); + continue; + } + } + _e_int_menus_clients_item_create(bd, m); + } + + desk = NULL; + subm = NULL; + if (evas_list_count(alt) > 0) + { + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) + { + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + + for (l = alt; l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if ( bd->desk != desk && e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE) + { + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) + { + if (subm && mi) + e_menu_item_submenu_set(mi, subm); + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, bd->desk->name); + e_util_menu_item_edje_icon_set(mi, "enlightenment/desktops"); + subm = e_menu_new(); + } + else + { + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + desk = bd->desk; + } + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) + _e_int_menus_clients_item_create(bd, subm); + else + _e_int_menus_clients_item_create(bd, m); + } + if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU && subm && mi) + e_menu_item_submenu_set(mi, subm); + } +} + static void _e_int_menus_clients_pre_cb(void *data, E_Menu *m) { @@ -922,8 +1065,7 @@ _e_int_menus_clients_pre_cb(void *data, E_Menu *m) e_menu_pre_activate_callback_set(m, NULL, NULL); /* get the current clients */ - zone = - e_zone_current_get(e_container_current_get(e_manager_current_get())); + zone = e_zone_current_get(e_container_current_get(e_manager_current_get())); desk = e_desk_current_get(zone); for (l = e_border_client_list(); l; l = l->next) { @@ -945,49 +1087,37 @@ _e_int_menus_clients_pre_cb(void *data, E_Menu *m) mi = e_menu_item_new(m); e_menu_item_label_set(mi, _("(No Windows)")); } - for (l = borders; l; l = l->next) + + if (borders) { - E_Border *bd; + if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ALPHA) + borders = evas_list_sort(borders, evas_list_count(borders), + _e_int_menus_clients_sort_alpha_cb); + + if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_DESK) + { + borders = evas_list_sort(borders, evas_list_count(borders), + _e_int_menus_clients_group_desk_cb); + _e_int_menus_clients_add_by_desk(desk, borders, m); + } + if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_CLASS) + { + borders = evas_list_sort(borders, evas_list_count(borders), + _e_int_menus_clients_group_class_cb); + _e_int_menus_clients_add_by_class(borders, m); + } + if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_NONE) + { + for (l = borders; l; l = l->next) + { + E_Border *bd; - bd = l->data; - if (bd->desk != desk) - { - alt = evas_list_append(alt, bd); - continue; + bd = l->data; + _e_int_menus_clients_item_create(bd, m); + } } - _e_int_menus_clients_item_create(bd, m); } - - alt = evas_list_sort(alt, evas_list_count(alt), - _e_int_menus_clients_sort_border_cb); - - desk = NULL; - subm = NULL; - if (evas_list_count(alt) > 0) - { - mi = e_menu_item_new(m); - e_menu_item_separator_set(mi, 1); - for (l = alt; l; l = l->next) - { - E_Border *bd; - - bd = l->data; - if (bd->desk != desk) - { - if (subm && mi) - e_menu_item_submenu_set(mi, subm); - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, bd->desk->name); - e_util_menu_item_edje_icon_set(mi, "enlightenment/desktops"); - subm = e_menu_new(); - desk = bd->desk; - } - _e_int_menus_clients_item_create(bd, subm); - } - if (subm && mi) - e_menu_item_submenu_set(mi, subm); - } - + mi = e_menu_item_new(m); e_menu_item_separator_set(mi, 1); @@ -1061,12 +1191,18 @@ _e_int_menus_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) bd = data; E_OBJECT_CHECK(bd); + if (bd->iconic) { + if (e_config->clientlist_warp_to_iconified_desktop == 1) + e_desk_show(bd->desk); + if (!bd->lock_user_iconify) e_border_uniconify(bd); } - e_desk_show(bd->desk); + + if (!bd->iconic) e_desk_show(bd->desk); + if (!bd->lock_user_stacking) e_border_raise(bd); if (!bd->lock_focus_out)