diff --git a/TODO b/TODO index d8ac17460..58edd4ec0 100644 --- a/TODO +++ b/TODO @@ -8,9 +8,13 @@ Some of the things (in very short form) that need to be done to E17... BUGS / FIXES ------------------------------------------------------------------------------- -* BUG: right click on ibar - select "remove icon" from menu -> segv. -* BUG: adding app using "applications" dialog to a bar dir for example means - the target bar dir is emptied and only that app is put in. +* BUG: exe and options split doesnt do things quite right - it should empty + out %u/U/f whatever (parts and conver them to empty strings) but keep other + cmd-line options (eg my exe is "xterm -e mutt" should nto strip off the + options) so "exe %u" -> "exe ", "exe -f %u" -> "exe -f ", + "exe -f" -> "exe -f" +* BUG: adding app using "applications" dialog to a bar dir ends up with bmank + icons in the bar dir in the apps dialog - until a restart * BUG: smart placement seems to screw up if a shelf is at the top of the screen * BUG: e17 screen res diaolg doesnt work under xephyr - why? * BUG: "match this window only" doesnt fall back to other unused remembers @@ -27,14 +31,13 @@ Some of the things (in very short form) that need to be done to E17... ESSENTIAL FEATURES ------------------------------------------------------------------------------- -* nuke the current eap cache mechanism entirely +* nuke the current eap cache mechanism entirely (and replace with .desktop + cache) * transition config dialog needs preview. * fm2 needs way to replace or extend the right click menu (disable/enable rename/delete/refresh etc.) -* fm2 .desktop parser needs to handle i18n * fm2 needs a mime filter * fm2 needs to have a mime & filetype -> icon mapping -* eap editor is broken - segv in advanced mode * middle mouse on gadgets as a quick move/resize thing? * language packs: need to have a tool to load/setup a language pack (which means .mo compiled files from a .po, an optional font and a config file that @@ -64,7 +67,7 @@ Some of the things (in very short form) that need to be done to E17... this desktop and other desktops, sorting by recently used, separate section for iconified apps etc. etc - configurable. * cleanup windows menu item needs action wrapper -* remove a lot of ipc commands that shoudl be done via the gui now +* remove a lot of ipc commands that should be done via the gui now * remove config items marked for removal * make default set of apps .desktop files in tarball * add a installed icons dir with icons for the .desktop files @@ -81,11 +84,7 @@ Some of the things (in very short form) that need to be done to E17... * need to audit, namespace and expand text and color classes * need to specify what is NEEDED from a theme, what is optional (in terms of parts, groups and signals). etc. -* default config for shelf is screwy and needs fixing - related to gadcon - layout algorithm though. * ipc is a mess. overgrown. hard to work with. what to do? remove? -* EAP cache files can be hit and miss and have problems. move things to be - explicit reloads. * winlist should support place for window "screenshot" in list as well as app icon * winlist could divide windows up into blocks - sub-lists within a container @@ -105,8 +104,6 @@ Some of the things (in very short form) that need to be done to E17... show status then a "shutting down/rebooting now" - maybe an abort too with a countdown. * suspend/hibernate needs a "suspending/hibernating" "progress" dialog -* suspend/hibernate/shutdown/reboot need to trap errors in exec and - report (and abort). ]]] [[[ @@ -130,7 +127,6 @@ Some of the things (in very short form) that need to be done to E17... * add "osd" subsystem for things like volume controls on keybboards, etc. that overlay the screen * file icons on the desktop (people ask for it) - xdnd for these -* improve drag/resize of gadget items * pager should be able to be configured to control more than the current zone (select which zone they control) * add a dialog to allow selecting the default border from among those present diff --git a/data/themes/default_fileman.edc b/data/themes/default_fileman.edc index 79977cc90..128fc8fba 100644 --- a/data/themes/default_fileman.edc +++ b/data/themes/default_fileman.edc @@ -192,7 +192,7 @@ group { relative: 1.0 1.0; offset: 0 0; } - color: 0 0 0 255; + color: 0 0 0 64; } description { state: "visible" 0.0; @@ -867,7 +867,7 @@ group { relative: 1.0 1.0; offset: 0 0; } - color: 0 0 0 255; + color: 0 0 0 64; } description { state: "visible" 0.0; @@ -1542,7 +1542,7 @@ group { relative: 1.0 1.0; offset: 0 0; } - color: 0 0 0 255; + color: 0 0 0 64; } description { state: "visible" 0.0; @@ -2216,7 +2216,7 @@ group { relative: 1.0 1.0; offset: 0 0; } - color: 0 0 0 255; + color: 0 0 0 64; } description { state: "visible" 0.0; @@ -4404,7 +4404,7 @@ group { relative: 1.0 1.0; offset: -6 -6; } - color: 0 0 0 255; + color: 0 0 0 128; } } part { diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c index 10c4cad3c..2e87ae77f 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -1113,6 +1113,9 @@ _e_actions_menu_find(const char *name) else if (!strcmp(name, "favorites")) return e_int_menus_favorite_apps_new(); else if (!strcmp(name, "all")) return e_int_menus_all_apps_new(); else if (!strcmp(name, "clients")) return e_int_menus_clients_new(); + else if (!strcmp(name, "lost_clients")) return e_int_menus_lost_clients_new(); + else if (!strcmp(name, "configuration")) return e_int_menus_config_new(); + else if (!strcmp(name, "system")) return e_int_menus_sys_new(); return NULL; } ACT_FN_GO(menu_show) diff --git a/src/bin/e_apps.c b/src/bin/e_apps.c index 65c0f79cc..317db33a2 100644 --- a/src/bin/e_apps.c +++ b/src/bin/e_apps.c @@ -14,7 +14,7 @@ */ #define DEBUG 0 -#define APP_CACHE 1 +#define APP_CACHE 0 /* local subsystem functions */ typedef struct _E_App_Change_Info E_App_Change_Info; typedef struct _E_App_Callback E_App_Callback; diff --git a/src/bin/e_config.c b/src/bin/e_config.c index 58e4832a7..9ae87d967 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -877,7 +877,7 @@ e_config_init(void) "restart", NULL); CFG_KEYBIND(E_BINDING_CONTEXT_ANY, "Delete", E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0, - "exit", NULL); + "logout", NULL); CFG_KEYBIND(E_BINDING_CONTEXT_ANY, "Escape", E_BINDING_MODIFIER_ALT, 0, "exebuf", NULL); diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 06779563b..ee30034a1 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -12,9 +12,9 @@ struct _Main_Data E_Menu *all_apps; E_Menu *desktops; E_Menu *clients; -// E_Menu *gadgets; E_Menu *config; E_Menu *lost_clients; + E_Menu *sys; }; /* local subsystem functions */ @@ -25,6 +25,7 @@ static void _e_int_menus_main_run (void *data, E_Menu *m, E_Menu_Item static int _e_int_menus_main_lock_defer_cb (void *data); static void _e_int_menus_main_lock (void *data, E_Menu *m, E_Menu_Item*mi); static void _e_int_menus_main_restart (void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_int_menus_main_logout (void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_main_exit (void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_main_halt (void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_main_reboot (void *data, E_Menu *m, E_Menu_Item *mi); @@ -48,12 +49,12 @@ static void _e_int_menus_clients_icon_cb (void *data, E_Menu *m, E_Menu_Item static void _e_int_menus_clients_cleanup_cb (void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_desktops_pre_cb (void *data, E_Menu *m); static void _e_int_menus_desktops_item_cb (void *data, E_Menu *m, E_Menu_Item *mi); -//static void _e_int_menus_gadgets_pre_cb (void *data, E_Menu *m); -//static void _e_int_menus_gadgets_edit_mode_cb(void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_themes_about (void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_lost_clients_pre_cb (void *data, E_Menu *m); static void _e_int_menus_lost_clients_free_hook(void *obj); static void _e_int_menus_lost_clients_item_cb (void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_int_menus_sys_pre_cb (void *data, E_Menu *m); +static void _e_int_menus_sys_free_hook (void *obj); static void _e_int_menus_augmentation_add (E_Menu *m, Evas_List *augmentation); static void _e_int_menus_augmentation_del (E_Menu *m, Evas_List *augmentation); @@ -119,15 +120,6 @@ e_int_menus_main_new(void) e_util_menu_item_edje_icon_set(mi, "enlightenment/lost_windows"); e_menu_item_submenu_set(mi, subm); -/* - subm = e_int_menus_gadgets_new(); - dat->gadgets = subm; - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Gadgets")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/gadgets"); - e_menu_item_submenu_set(mi, subm); -*/ - mi = e_menu_item_new(m); e_menu_item_separator_set(mi, 1); @@ -151,52 +143,13 @@ e_int_menus_main_new(void) mi = e_menu_item_new(m); e_menu_item_separator_set(mi, 1); - if (e_sys_action_possible_get(E_SYS_HALT) || - e_sys_action_possible_get(E_SYS_REBOOT) || - e_sys_action_possible_get(E_SYS_SUSPEND) || - e_sys_action_possible_get(E_SYS_HIBERNATE)) - { - if (e_sys_action_possible_get(E_SYS_SUSPEND)) - { - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Suspend your Computer")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/suspend"); - e_menu_item_callback_set(mi, _e_int_menus_main_suspend, NULL); - } - if (e_sys_action_possible_get(E_SYS_HIBERNATE)) - { - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Hibernate your Computer")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/hibernate"); - e_menu_item_callback_set(mi, _e_int_menus_main_hibernate, NULL); - } - if (e_sys_action_possible_get(E_SYS_REBOOT)) - { - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Reboot your Computer")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/reboot"); - e_menu_item_callback_set(mi, _e_int_menus_main_reboot, NULL); - } - if (e_sys_action_possible_get(E_SYS_HALT)) - { - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Shut Down your Computer")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/halt"); - e_menu_item_callback_set(mi, _e_int_menus_main_halt, NULL); - } - mi = e_menu_item_new(m); - e_menu_item_separator_set(mi, 1); - } - + subm = e_int_menus_sys_new(); + dat->sys = subm; mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Restart Enlightenment")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/reset"); - e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL); + e_menu_item_label_set(mi, _("System")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/system"); + e_menu_item_submenu_set(mi, subm); - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Exit Enlightenment")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/exit"); - e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL); return m; } @@ -281,17 +234,7 @@ e_int_menus_clients_new(void) e_menu_pre_activate_callback_set(m, _e_int_menus_clients_pre_cb, NULL); return m; } -/* -EAPI E_Menu * -e_int_menus_gadgets_new(void) -{ - E_Menu *m; - m = e_menu_new(); - e_menu_pre_activate_callback_set(m, _e_int_menus_gadgets_pre_cb, NULL); - return m; -} -*/ EAPI E_Menu * e_int_menus_lost_clients_new(void) { @@ -302,6 +245,17 @@ e_int_menus_lost_clients_new(void) return m; } +EAPI E_Menu * +e_int_menus_sys_new(void) +{ + E_Menu *m; + + m = e_menu_new(); + e_menu_pre_activate_callback_set(m, _e_int_menus_sys_pre_cb, NULL); + + return m; +} + EAPI E_Int_Menu_Augmentation * e_int_menus_menu_augmentation_add(const char *menu, void (*func_add) (void *data, E_Menu *m), @@ -363,9 +317,9 @@ _e_int_menus_main_del_hook(void *obj) e_object_del(E_OBJECT(dat->apps)); e_object_del(E_OBJECT(dat->desktops)); e_object_del(E_OBJECT(dat->clients)); -// e_object_del(E_OBJECT(dat->gadgets)); e_object_del(E_OBJECT(dat->config)); e_object_del(E_OBJECT(dat->lost_clients)); + e_object_del(E_OBJECT(dat->sys)); free(dat); } } @@ -441,6 +395,15 @@ _e_int_menus_main_restart(void *data, E_Menu *m, E_Menu_Item *mi) if ((a) && (a->func.go)) a->func.go(NULL, NULL); } +static void +_e_int_menus_main_logout(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Action *a; + + a = e_action_find("logout"); + if ((a) && (a->func.go)) a->func.go(NULL, NULL); +} + static void _e_int_menus_main_exit(void *data, E_Menu *m, E_Menu_Item *mi) { @@ -637,11 +600,6 @@ _e_int_menus_desktops_pre_cb(void *data, E_Menu *m) e_menu_pre_activate_callback_set(m, NULL, NULL); - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Lock Screen")); - e_util_menu_item_edje_icon_set(mi, "enlightenment/desklock"); - e_menu_item_callback_set(mi, _e_int_menus_main_lock, NULL); - mi = e_menu_item_new(m); e_menu_item_label_set(mi, _("Show/Hide All Windows")); e_util_menu_item_edje_icon_set(mi, "enlightenment/showhide"); @@ -765,6 +723,99 @@ _e_int_menus_config_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) e_configure_show(m->zone->container); } +static void +_e_int_menus_sys_pre_cb(void *data, E_Menu *m) +{ + E_Menu_Item *mi; + Evas_List *l; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + + l = evas_hash_find(_e_int_menus_augmentation, "sys"); + if (l) + { + _e_int_menus_augmentation_add(m, l); + + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Lock Screen")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/desklock"); + e_menu_item_callback_set(mi, _e_int_menus_main_lock, NULL); + + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + + if (e_sys_action_possible_get(E_SYS_HALT) || + e_sys_action_possible_get(E_SYS_REBOOT) || + e_sys_action_possible_get(E_SYS_SUSPEND) || + e_sys_action_possible_get(E_SYS_HIBERNATE)) + { + if (e_sys_action_possible_get(E_SYS_SUSPEND)) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Suspend")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/suspend"); + e_menu_item_callback_set(mi, _e_int_menus_main_suspend, NULL); + } + if (e_sys_action_possible_get(E_SYS_HIBERNATE)) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Hibernate")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/hibernate"); + e_menu_item_callback_set(mi, _e_int_menus_main_hibernate, NULL); + } + if (e_sys_action_possible_get(E_SYS_REBOOT)) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Reboot")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/reboot"); + e_menu_item_callback_set(mi, _e_int_menus_main_reboot, NULL); + } + if (e_sys_action_possible_get(E_SYS_HALT)) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Shut Down")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/halt"); + e_menu_item_callback_set(mi, _e_int_menus_main_halt, NULL); + } + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Restart Enlightenment")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/reset"); + e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Exit Enlightenment")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/exit"); + e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL); + + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Logout")); + e_util_menu_item_edje_icon_set(mi, "enlightenment/logout"); + e_menu_item_callback_set(mi, _e_int_menus_main_logout, NULL); + + e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_sys_free_hook); +} + +static void +_e_int_menus_sys_free_hook(void *obj) +{ + E_Menu *m; + + m = obj; + + _e_int_menus_augmentation_del(m, evas_hash_find(_e_int_menus_augmentation, "sys")); +} + static void _e_int_menus_clients_pre_cb(void *data, E_Menu *m) { @@ -922,52 +973,7 @@ _e_int_menus_clients_cleanup_cb(void *data, E_Menu *m, E_Menu_Item *mi) zone = data; e_place_zone_region_smart_cleanup(zone); } -/* -static void -_e_int_menus_gadgets_pre_cb(void *data, E_Menu *m) -{ - E_Menu_Item *mi; - E_Menu *root; - e_menu_pre_activate_callback_set(m, NULL, NULL); - root = e_menu_root_get(m); - if ((root) && (root->zone)) - { - mi = e_menu_item_new(m); - e_menu_item_check_set(mi, 1); - if (e_gadman_mode_get(root->zone->container->gadman) == E_GADMAN_MODE_EDIT) - e_menu_item_toggle_set(mi, 1); - else - e_menu_item_toggle_set(mi, 0); - e_menu_item_label_set(mi, _("Edit Mode")); - e_menu_item_callback_set(mi, _e_int_menus_gadgets_edit_mode_cb, root->zone->container->gadman); - } - else - { - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("(Unused)")); - e_menu_item_callback_set(mi, NULL, NULL); - } -} - -static void -_e_int_menus_gadgets_edit_mode_cb(void *data, E_Menu *m, E_Menu_Item *mi) -{ - E_Gadman *gm; - - gm = data; - if (e_menu_item_toggle_get(mi)) - { -// e_gadcon_all_edit_begin(); - e_gadman_mode_set(gm, E_GADMAN_MODE_EDIT); - } - else - { -// e_gadcon_all_edit_end(); - e_gadman_mode_set(gm, E_GADMAN_MODE_NORMAL); - } -} -*/ static void _e_int_menus_lost_clients_pre_cb(void *data, E_Menu *m) { diff --git a/src/bin/e_int_menus.h b/src/bin/e_int_menus.h index 324a3f102..a00eebc88 100644 --- a/src/bin/e_int_menus.h +++ b/src/bin/e_int_menus.h @@ -12,8 +12,8 @@ typedef struct _E_Int_Menu_Augmentation E_Int_Menu_Augmentation; struct _E_Int_Menu_Augmentation { struct { - void (*func)(void *data, E_Menu *m); - void *data; + void (*func)(void *data, E_Menu *m); + void *data; } add, del; }; @@ -24,9 +24,8 @@ EAPI E_Menu *e_int_menus_apps_new(const char *dir); EAPI E_Menu *e_int_menus_favorite_apps_new(void); EAPI E_Menu *e_int_menus_all_apps_new(void); EAPI E_Menu *e_int_menus_config_new(void); -EAPI E_Menu *e_int_menus_gadgets_new(void); -EAPI E_Menu *e_int_menus_themes_new(void); EAPI E_Menu *e_int_menus_lost_clients_new(void); +EAPI E_Menu *e_int_menus_sys_new(void); EAPI E_Int_Menu_Augmentation *e_int_menus_menu_augmentation_add(const char *menu, void (*func_add) (void *data, E_Menu *m), diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index 8cf3c7296..773295568 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -1848,10 +1848,10 @@ _e_menu_reposition(E_Menu *m) m->cur.x = m->parent_item->menu->cur.x + m->parent_item->menu->cur.w; parent_item_bottom = m->parent_item->menu->cur.y + m->parent_item->y; - if(m->cur.h > m->zone->h) + if (m->cur.h > m->zone->h) { /* menu is larger than screen */ - if(parent_item_bottom > (m->zone->h / 2)) + if (parent_item_bottom > (m->zone->h / 2)) /* more is shown if menu goes up */ m->cur.y = (parent_item_bottom - (m->container_h + 1)); else @@ -1861,10 +1861,10 @@ _e_menu_reposition(E_Menu *m) else { /* menu is smaller than screen */ - if(((parent_item_bottom + m->cur.h - m->container_y) > m->zone->h) && + if (((parent_item_bottom + m->cur.h - m->container_y) > m->zone->h) && (parent_item_bottom > (m->zone->h / 2))) /* menu is partially out of screen and more is shown if menu goes up */ - m->cur.y = (parent_item_bottom - (m->container_h + 1)); + m->cur.y = (parent_item_bottom - (m->container_h + 1)) + m->parent_item->h; else m->cur.y = parent_item_bottom - m->container_y; } diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c index cd7065e91..427ec129f 100644 --- a/src/bin/e_sys.c +++ b/src/bin/e_sys.c @@ -5,9 +5,17 @@ /* local subsystem functions */ static int _e_sys_cb_exit(void *data, int type, void *event); +static void _e_sys_cb_logout_logout(void *data, E_Dialog *dia); +static void _e_sys_cb_logout_wait(void *data, E_Dialog *dia); +static void _e_sys_cb_logout_abort(void *data, E_Dialog *dia); +static int _e_sys_cb_logout_timer(void *data); +static void _e_sys_logout_after(void); +static void _e_sys_logout_begin(E_Sys_Action a_after); +static void _e_sys_current_action(void); +static void _e_sys_action_failed(void); +static int _e_sys_action_do(E_Sys_Action a, char *param); static Ecore_Event_Handler *_e_sys_exe_exit_handler = NULL; -static int _e_sys_exe_pending = 0; static Ecore_Exe *_e_sys_halt_check_exe = NULL; static Ecore_Exe *_e_sys_reboot_check_exe = NULL; static Ecore_Exe *_e_sys_suspend_check_exe = NULL; @@ -17,6 +25,12 @@ static int _e_sys_can_reboot = 0; static int _e_sys_can_suspend = 0; static int _e_sys_can_hibernate = 0; +static E_Sys_Action _e_sys_action_current = E_SYS_NONE; +static E_Sys_Action _e_sys_action_after = E_SYS_NONE; +static Ecore_Exe *_e_sys_exe = NULL; +static double _e_sys_logout_begin_time = 0.0; +static Ecore_Timer *_e_sys_logout_timer = NULL; + /* externally accessible functions */ EAPI int e_sys_init(void) @@ -26,18 +40,17 @@ e_sys_init(void) /* this is not optimal - but it does work cleanly */ _e_sys_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_sys_cb_exit, NULL); + /* exec out sys helper and ask it to test if we are allowed to do these + * things + */ snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t halt", e_prefix_bin_get()); _e_sys_halt_check_exe = ecore_exe_run(buf, NULL); - _e_sys_exe_pending++; snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t reboot", e_prefix_bin_get()); _e_sys_reboot_check_exe = ecore_exe_run(buf, NULL); - _e_sys_exe_pending++; snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t suspend", e_prefix_bin_get()); _e_sys_suspend_check_exe = ecore_exe_run(buf, NULL); - _e_sys_exe_pending++; snprintf(buf, sizeof(buf), "%s/enlightenment_sys -t hibernate", e_prefix_bin_get()); _e_sys_hibernate_check_exe = ecore_exe_run(buf, NULL); - _e_sys_exe_pending++; return 1; } @@ -82,60 +95,33 @@ e_sys_action_possible_get(E_Sys_Action a) EAPI int e_sys_action_do(E_Sys_Action a, char *param) { - char buf[4096]; + int ret; + if (_e_sys_action_current != E_SYS_NONE) + { + _e_sys_current_action(); + return 0; + } switch (a) { case E_SYS_EXIT: - if (!e_util_immortal_check()) - ecore_main_loop_quit(); - break; case E_SYS_RESTART: - restart = 1; - ecore_main_loop_quit(); - break; case E_SYS_EXIT_NOW: - exit(0); - break; case E_SYS_LOGOUT: - /* FIXME: go through to every window and if it wants delete req - ask - * it to delete, otherwise just close it. set handler for window - * deletes, and once all windows are deleted - exit, OR if a timer - * expires - pop up dialog saying something is not responding - */ + case E_SYS_SUSPEND: + case E_SYS_HIBERNATE: + ret = _e_sys_action_do(a, param); break; case E_SYS_HALT: - /* shutdown -h now */ - snprintf(buf, sizeof(buf), "%s/enlightenment_sys halt", - e_prefix_bin_get()); - ecore_exe_run(buf, NULL); - /* FIXME: track command return value and have dialog */ - break; case E_SYS_REBOOT: - /* shutdown -r now */ - snprintf(buf, sizeof(buf), "%s/enlightenment_sys reboot", - e_prefix_bin_get()); - ecore_exe_run(buf, NULL); - /* FIXME: track command return value and have dialog */ - break; - case E_SYS_SUSPEND: - /* /etc/acpi/sleep.sh force */ - snprintf(buf, sizeof(buf), "%s/enlightenment_sys suspend", - e_prefix_bin_get()); - ecore_exe_run(buf, NULL); - /* FIXME: track command return value and have dialog */ - break; - case E_SYS_HIBERNATE: - /* /etc/acpi/hibernate.sh force */ - snprintf(buf, sizeof(buf), "%s/enlightenment_sys hibernate", - e_prefix_bin_get()); - ecore_exe_run(buf, NULL); - /* FIXME: track command return value and have dialog */ + if (!e_util_immortal_check()) _e_sys_logout_begin(a); + return 1; break; default: return 0; } - return 0; + _e_sys_action_current = a; + return ret; } /* local subsystem functions */ @@ -145,14 +131,25 @@ _e_sys_cb_exit(void *data, int type, void *event) Ecore_Exe_Event_Del *ev; ev = event; + if ((_e_sys_exe) && (ev->exe == _e_sys_exe)) + { + if (ev->exit_code != 0) _e_sys_action_failed(); + _e_sys_action_current = E_SYS_NONE; + _e_sys_exe = NULL; + /* if we have a suspend or hibernate status popup/dialog - close it + * here as we have finished suspend/hibernate (and probably just + * came back out of suspend/hibernate */ + return 1; + } if ((_e_sys_halt_check_exe) && (ev->exe == _e_sys_halt_check_exe)) { + /* exit_code: 0 == OK, 5 == suid root removed, 7 == group id error + * 10 == permission denied, 20 == action undefined */ if (ev->exit_code == 0) { _e_sys_can_halt = 1; _e_sys_halt_check_exe = NULL; } - _e_sys_exe_pending--; } else if ((_e_sys_reboot_check_exe) && (ev->exe == _e_sys_reboot_check_exe)) { @@ -161,7 +158,6 @@ _e_sys_cb_exit(void *data, int type, void *event) _e_sys_can_reboot = 1; _e_sys_reboot_check_exe = NULL; } - _e_sys_exe_pending--; } else if ((_e_sys_suspend_check_exe) && (ev->exe == _e_sys_suspend_check_exe)) { @@ -170,7 +166,6 @@ _e_sys_cb_exit(void *data, int type, void *event) _e_sys_can_suspend = 1; _e_sys_suspend_check_exe = NULL; } - _e_sys_exe_pending--; } else if ((_e_sys_hibernate_check_exe) && (ev->exe == _e_sys_hibernate_check_exe)) { @@ -179,14 +174,322 @@ _e_sys_cb_exit(void *data, int type, void *event) _e_sys_can_hibernate = 1; _e_sys_hibernate_check_exe = NULL; } - _e_sys_exe_pending--; - } - - if (_e_sys_exe_pending <= 0) - { - if (_e_sys_exe_exit_handler) - ecore_event_handler_del(_e_sys_exe_exit_handler); - _e_sys_exe_exit_handler = NULL; + } + return 1; +} + +static void +_e_sys_cb_logout_logout(void *data, E_Dialog *dia) +{ + if (_e_sys_logout_timer) + { + ecore_timer_del(_e_sys_logout_timer); + _e_sys_logout_timer = NULL; + } + _e_sys_logout_begin_time = 0.0; + _e_sys_logout_after(); + e_object_del(E_OBJECT(dia)); +} + +static void +_e_sys_cb_logout_wait(void *data, E_Dialog *dia) +{ + if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer); + _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL); + _e_sys_logout_begin_time = ecore_time_get(); + e_object_del(E_OBJECT(dia)); +} + +static void +_e_sys_cb_logout_abort(void *data, E_Dialog *dia) +{ + if (_e_sys_logout_timer) + { + ecore_timer_del(_e_sys_logout_timer); + _e_sys_logout_timer = NULL; + } + _e_sys_logout_begin_time = 0.0; + e_object_del(E_OBJECT(dia)); + _e_sys_action_current = E_SYS_NONE; + _e_sys_action_after = E_SYS_NONE; +} + +static int +_e_sys_cb_logout_timer(void *data) +{ + Evas_List *l; + int pending = 0; + + for (l = e_border_client_list(); l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if (!bd->internal) pending++; + } + if (pending == 0) goto after; + else + { + /* it has taken 15 seconds of waiting and we still have apps that + * will not go away + */ + if ((ecore_time_get() - _e_sys_logout_begin_time) > 15.0) + { + E_Dialog *dia; + + dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_sys_error_logout_slow"); + if (dia) + { + e_dialog_title_set(dia, _("Logout problems")); + e_dialog_icon_set(dia, "enlightenment/logout", 64); + e_dialog_text_set(dia, + _("Logout is taking too long. Some
" + "applications refuse to close.
" + "Do you want to finish the logout
" + "anyway without closing these
" + "applications first?") + ); + e_dialog_button_add(dia, _("Logout now"), NULL, _e_sys_cb_logout_logout, NULL); + e_dialog_button_add(dia, _("Wait longer"), NULL, _e_sys_cb_logout_wait, NULL); + e_dialog_button_add(dia, _("Cancel Logout"), NULL, _e_sys_cb_logout_abort, NULL); + e_dialog_button_focus_num(dia, 1); + e_win_centered_set(dia->win, 1); + e_dialog_show(dia); + _e_sys_logout_begin_time = ecore_time_get() + (60 * 60 * 24 * 365); + } + _e_sys_logout_timer = NULL; + return 0; + } + } + return 1; + after: + _e_sys_logout_after(); + _e_sys_logout_timer = NULL; + return 0; +} + +static void +_e_sys_logout_after(void) +{ + _e_sys_action_do(_e_sys_action_after, NULL); + _e_sys_action_current = E_SYS_NONE; + _e_sys_action_after = E_SYS_NONE; +} + +static void +_e_sys_logout_begin(E_Sys_Action a_after) +{ + Evas_List *l; + + /* start logout - at end do the a_after action */ + _e_sys_action_after = a_after; + /* FIXME: go through to every window and if it wants delete req - ask + * it to delete, otherwise just close it. set handler for window + * deletes, and once all windows are deleted - exit, OR if a timer + * expires - pop up dialog saying something is not responding + */ + for (l = e_border_client_list(); l; l = l->next) + { + E_Border *bd; + + bd = l->data; + e_border_act_close_begin(bd); + } + /* and poll to see if all pending windows are gone yet every 0.5 sec */ + _e_sys_logout_begin_time = ecore_time_get(); + if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer); + _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL); +} + +static void +_e_sys_current_action(void) +{ + /* display dialog that currently an action is in progress */ + E_Dialog *dia; + + dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_sys_error_action_busy"); + if (!dia) return; + + e_dialog_title_set(dia, _("Enlightenment is busy with another request")); + e_dialog_icon_set(dia, "enlightenment/sys", 64); + switch (_e_sys_action_current) + { + case E_SYS_LOGOUT: + e_dialog_text_set(dia, + _("Enlightenment is busy logging out
" + "You cannot perform other system actions
" + "once a logout has begun.") + ); + break; + case E_SYS_HALT: + e_dialog_text_set(dia, + _("Enlightenment is shutting the system down.
" + "You cannot do any other system actions
" + "once a shutdown has been started.") + ); + break; + case E_SYS_REBOOT: + e_dialog_text_set(dia, + _("Enlightenment is rebooting the system.
" + "You cannot do any other system actions
" + "once a reboot has begun.") + ); + break; + case E_SYS_SUSPEND: + e_dialog_text_set(dia, + _("Enlightenment is suspending the system.
" + "Until suspend is complete you cannot perform
" + "any other system actions.") + ); + break; + case E_SYS_HIBERNATE: + e_dialog_text_set(dia, + _("Enlightenment is hibernating the system.
" + "You cannot perform an other system actions
" + "until this is complete.") + ); + break; + default: + e_dialog_text_set(dia, + _("EEK! This should not happen") + ); + break; + } + e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL); + e_dialog_button_focus_num(dia, 0); + e_win_centered_set(dia->win, 1); + e_dialog_show(dia); +} + +static void +_e_sys_action_failed(void) +{ + /* display dialog that the current action failed */ + E_Dialog *dia; + + dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_sys_error_action_failed"); + if (!dia) return; + + e_dialog_title_set(dia, _("Enlightenment is busy with another request")); + e_dialog_icon_set(dia, "enlightenment/sys", 64); + switch (_e_sys_action_current) + { + case E_SYS_HALT: + e_dialog_text_set(dia, + _("Shutting down of your system failed.") + ); + break; + case E_SYS_REBOOT: + e_dialog_text_set(dia, + _("Rebooting your system failed.") + ); + break; + case E_SYS_SUSPEND: + e_dialog_text_set(dia, + _("Suspend of your system failed.") + ); + break; + case E_SYS_HIBERNATE: + e_dialog_text_set(dia, + _("Hibernating your system failed.") + ); + break; + default: + e_dialog_text_set(dia, + _("EEK! This should not happen") + ); + break; + } + e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL); + e_dialog_button_focus_num(dia, 0); + e_win_centered_set(dia->win, 1); + e_dialog_show(dia); +} + +static int +_e_sys_action_do(E_Sys_Action a, char *param) +{ + char buf[4096]; + + switch (a) + { + case E_SYS_EXIT: + if (!e_util_immortal_check()) ecore_main_loop_quit(); + break; + case E_SYS_RESTART: + restart = 1; + ecore_main_loop_quit(); + break; + case E_SYS_EXIT_NOW: + exit(0); + break; + case E_SYS_LOGOUT: + _e_sys_logout_begin(E_SYS_EXIT); + break; + case E_SYS_HALT: + /* shutdown -h now */ + if (e_util_immortal_check()) return 0; + snprintf(buf, sizeof(buf), "%s/enlightenment_sys halt", + e_prefix_bin_get()); + if (_e_sys_exe) + { + _e_sys_current_action(); + return 0; + } + else + { + _e_sys_exe = ecore_exe_run(buf, NULL); + /* FIXME: display halt status */ + } + break; + case E_SYS_REBOOT: + /* shutdown -r now */ + if (e_util_immortal_check()) return 0; + snprintf(buf, sizeof(buf), "%s/enlightenment_sys reboot", + e_prefix_bin_get()); + if (_e_sys_exe) + { + _e_sys_current_action(); + return 0; + } + else + { + _e_sys_exe = ecore_exe_run(buf, NULL); + /* FIXME: display reboot status */ + } + break; + case E_SYS_SUSPEND: + /* /etc/acpi/sleep.sh force */ + snprintf(buf, sizeof(buf), "%s/enlightenment_sys suspend", + e_prefix_bin_get()); + if (_e_sys_exe) + { + _e_sys_current_action(); + return 0; + } + else + { + _e_sys_exe = ecore_exe_run(buf, NULL); + /* FIXME: display suspend status */ + } + break; + case E_SYS_HIBERNATE: + /* /etc/acpi/hibernate.sh force */ + snprintf(buf, sizeof(buf), "%s/enlightenment_sys hibernate", + e_prefix_bin_get()); + if (_e_sys_exe) + { + _e_sys_current_action(); + return 0; + } + else + { + _e_sys_exe = ecore_exe_run(buf, NULL); + /* FIXME: display hibernate status */ + } + break; + default: + return 0; } return 1; } diff --git a/src/bin/e_sys.h b/src/bin/e_sys.h index f4350cc21..4b714b6c9 100644 --- a/src/bin/e_sys.h +++ b/src/bin/e_sys.h @@ -7,6 +7,7 @@ typedef enum _E_Sys_Action E_Sys_Action; enum _E_Sys_Action { + E_SYS_NONE, E_SYS_EXIT, E_SYS_RESTART, E_SYS_EXIT_NOW,