<ESC><ESC> is used to step one back in the dialogs. When lxdialog became built-in pressing <ESC> once would cause one step back and pressing <ESC><ESC> would cause two steps back. This patch - based on concept from Roman Zippel <zippel@linux-m68k.org> - makes one <ESC> a noop and pressing <ESC><ESC> will cause one step backward. In addition the final yes/no dialog now has the option to go back to the the kernel configuration. So if you get too far out you can now go back to configuring the kernel without saving and starting all over again.
Showing the changes to scripts (8 of 8 files). Show all
Unified · Split
| @@ -192,7 +192,7 @@ int dialog_checklist(const char *title, const char *prompt, int height, · 191 unmodified lines | ||
| 192 | 192 | wnoutrefresh(list); |
| 193 | 193 | doupdate(); |
| 194 | 194 | |
| 195 | − while (key != ESC) { | |
| 195 | + while (key != KEY_ESC) { | |
| 196 | 196 | key = wgetch(dialog); |
| 197 | 197 | |
| 198 | 198 | for (i = 0; i < max_choice; i++) { |
| @@ -298,8 +298,10 @@ int dialog_checklist(const char *title, const char *prompt, int height, · 99 unmodified lines | ||
| 298 | 298 | break; |
| 299 | 299 | case 'X': |
| 300 | 300 | case 'x': |
| 301 | − key = ESC; | |
| 302 | − case ESC: | |
| 301 | + key = KEY_ESC; | |
| 302 | + break; | |
| 303 | + case KEY_ESC: | |
| 304 | + key = on_key_esc(dialog); | |
| 303 | 305 | break; |
| 304 | 306 | } |
| 305 | 307 | |
| @@ -308,5 +310,5 @@ int dialog_checklist(const char *title, const char *prompt, int height, · 2 unmodified lines | ||
| 308 | 310 | } |
| 309 | 311 | delwin(list); |
| 310 | 312 | delwin(dialog); |
| 311 | − return 255; /* ESC pressed */ | |
| 313 | + return key; /* ESC pressed */ | |
| 312 | 314 | } |
| @@ -48,7 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #define TR(params) _tracef params |
| 50 | 50 | |
| 51 | −#define ESC 27 | |
| 51 | +#define KEY_ESC 27 | |
| 52 | 52 | #define TAB 9 |
| 53 | 53 | #define MAX_LEN 2048 |
| 54 | 54 | #define BUF_SIZE (10*1024) |
| @@ -179,6 +179,8 @@ int item_is_tag(char tag); · 124 unmodified lines | ||
| 179 | 179 | for (item_cur = item_head ? item_head: item_cur; \ |
| 180 | 180 | item_cur && (item_cur != &item_nil); item_cur = item_cur->next) |
| 181 | 181 | |
| 182 | +/* generic key handlers */ | |
| 183 | +int on_key_esc(WINDOW *win); | |
| 182 | 184 | |
| 183 | 185 | void init_dialog(const char *backtitle); |
| 184 | 186 | void reset_dialog(void); |
| @@ -106,7 +106,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width · 105 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | wrefresh(dialog); |
| 108 | 108 | |
| 109 | − while (key != ESC) { | |
| 109 | + while (key != KEY_ESC) { | |
| 110 | 110 | key = wgetch(dialog); |
| 111 | 111 | |
| 112 | 112 | if (button == -1) { /* Input box selected */ |
| @@ -215,12 +215,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width · 102 unmodified lines | ||
| 215 | 215 | return (button == -1 ? 0 : button); |
| 216 | 216 | case 'X': |
| 217 | 217 | case 'x': |
| 218 | − key = ESC; | |
| 219 | − case ESC: | |
| 218 | + key = KEY_ESC; | |
| 219 | + break; | |
| 220 | + case KEY_ESC: | |
| 221 | + key = on_key_esc(dialog); | |
| 220 | 222 | break; |
| 221 | 223 | } |
| 222 | 224 | } |
| 223 | 225 | |
| 224 | 226 | delwin(dialog); |
| 225 | − return 255; /* ESC pressed */ | |
| 227 | + return KEY_ESC; /* ESC pressed */ | |
| 226 | 228 | } |
| @@ -263,7 +263,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, · 262 unmodified lines | ||
| 263 | 263 | wmove(menu, choice, item_x + 1); |
| 264 | 264 | wrefresh(menu); |
| 265 | 265 | |
| 266 | − while (key != ESC) { | |
| 266 | + while (key != KEY_ESC) { | |
| 267 | 267 | key = wgetch(menu); |
| 268 | 268 | |
| 269 | 269 | if (key < 256 && isalpha(key)) |
| @@ -402,12 +402,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, · 132 unmodified lines | ||
| 402 | 402 | return button; |
| 403 | 403 | case 'e': |
| 404 | 404 | case 'x': |
| 405 | − key = ESC; | |
| 406 | − case ESC: | |
| 405 | + key = KEY_ESC; | |
| 406 | + break; | |
| 407 | + case KEY_ESC: | |
| 408 | + key = on_key_esc(menu); | |
| 407 | 409 | break; |
| 408 | 410 | } |
| 409 | 411 | } |
| 410 | 412 | delwin(menu); |
| 411 | 413 | delwin(dialog); |
| 412 | − return 255; /* ESC pressed */ | |
| 414 | + return key; /* ESC pressed */ | |
| 413 | 415 | } |
| @@ -92,7 +92,7 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width) · 91 unmodified lines | ||
| 92 | 92 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
| 93 | 93 | wrefresh(dialog); |
| 94 | 94 | |
| 95 | − while ((key != ESC) && (key != '\n')) { | |
| 95 | + while ((key != KEY_ESC) && (key != '\n')) { | |
| 96 | 96 | key = wgetch(dialog); |
| 97 | 97 | switch (key) { |
| 98 | 98 | case 'E': /* Exit */ |
| @@ -228,13 +228,14 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width) · 129 unmodified lines | ||
| 228 | 228 | wmove(dialog, cur_y, cur_x); |
| 229 | 229 | wrefresh(dialog); |
| 230 | 230 | break; |
| 231 | − case ESC: | |
| 231 | + case KEY_ESC: | |
| 232 | + key = on_key_esc(dialog); | |
| 232 | 233 | break; |
| 233 | 234 | } |
| 234 | 235 | } |
| 235 | 236 | delwin(text); |
| 236 | 237 | delwin(dialog); |
| 237 | − return 255; /* ESC pressed */ | |
| 238 | + return key; /* ESC pressed */ | |
| 238 | 239 | } |
| 239 | 240 | |
| 240 | 241 | /* |
| @@ -477,6 +477,39 @@ int first_alpha(const char *string, const char *exempt) · 476 unmodified lines | ||
| 477 | 477 | return 0; |
| 478 | 478 | } |
| 479 | 479 | |
| 480 | +/* | |
| 481 | + * ncurses uses ESC to detect escaped char sequences. This resutl in | |
| 482 | + * a small timeout before ESC is actually delivered to the application. | |
| 483 | + * lxdialog suggest <ESC> <ESC> which is correctly translated to two | |
| 484 | + * times esc. But then we need to ignore the second esc to avoid stepping | |
| 485 | + * out one menu too much. Filter away all escaped key sequences since | |
| 486 | + * keypad(FALSE) turn off ncurses support for escape sequences - and thats | |
| 487 | + * needed to make notimeout() do as expected. | |
| 488 | + */ | |
| 489 | +int on_key_esc(WINDOW *win) | |
| 490 | +{ | |
| 491 | + int key; | |
| 492 | + int key2; | |
| 493 | + int key3; | |
| 494 | + | |
| 495 | + nodelay(win, TRUE); | |
| 496 | + keypad(win, FALSE); | |
| 497 | + key = wgetch(win); | |
| 498 | + key2 = wgetch(win); | |
| 499 | + do { | |
| 500 | + key3 = wgetch(win); | |
| 501 | + } while (key3 != ERR); | |
| 502 | + nodelay(win, FALSE); | |
| 503 | + keypad(win, TRUE); | |
| 504 | + if (key == KEY_ESC && key2 == ERR) | |
| 505 | + return KEY_ESC; | |
| 506 | + else if (key != ERR && key != KEY_ESC && key2 == ERR) | |
| 507 | + ungetch(key); | |
| 508 | + | |
| 509 | + return -1; | |
| 510 | +} | |
| 511 | + | |
| 512 | + | |
| 480 | 513 | struct dialog_list *item_cur; |
| 481 | 514 | struct dialog_list item_nil; |
| 482 | 515 | struct dialog_list *item_head; |
| @@ -69,7 +69,7 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | print_buttons(dialog, height, width, 0); |
| 71 | 71 | |
| 72 | − while (key != ESC) { | |
| 72 | + while (key != KEY_ESC) { | |
| 73 | 73 | key = wgetch(dialog); |
| 74 | 74 | switch (key) { |
| 75 | 75 | case 'Y': |
| @@ -93,11 +93,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) · 17 unmodified lines | ||
| 93 | 93 | case '\n': |
| 94 | 94 | delwin(dialog); |
| 95 | 95 | return button; |
| 96 | − case ESC: | |
| 96 | + case KEY_ESC: | |
| 97 | + key = on_key_esc(dialog); | |
| 97 | 98 | break; |
| 98 | 99 | } |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | 102 | delwin(dialog); |
| 102 | − return 255; /* ESC pressed */ | |
| 103 | + return key; /* ESC pressed */ | |
| 103 | 104 | } |
| @@ -608,7 +608,7 @@ static void conf(struct menu *menu) · 607 unmodified lines | ||
| 608 | 608 | _(menu_instructions), |
| 609 | 609 | rows, cols, rows - 10, |
| 610 | 610 | active_menu, &s_scroll); |
| 611 | − if (res == 1 || res == 255) | |
| 611 | + if (res == 1 || res == KEY_ESC) | |
| 612 | 612 | break; |
| 613 | 613 | if (!item_activate_selected()) |
| 614 | 614 | continue; |
| @@ -754,7 +754,7 @@ static void conf_choice(struct menu *menu) · 139 unmodified lines | ||
| 754 | 754 | } else |
| 755 | 755 | show_help(menu); |
| 756 | 756 | break; |
| 757 | − case 255: | |
| 757 | + case KEY_ESC: | |
| 758 | 758 | return; |
| 759 | 759 | } |
| 760 | 760 | } |
| @@ -794,7 +794,7 @@ static void conf_string(struct menu *menu) · 33 unmodified lines | ||
| 794 | 794 | case 1: |
| 795 | 795 | show_help(menu); |
| 796 | 796 | break; |
| 797 | − case 255: | |
| 797 | + case KEY_ESC: | |
| 798 | 798 | return; |
| 799 | 799 | } |
| 800 | 800 | } |
| @@ -819,7 +819,7 @@ static void conf_load(void) · 18 unmodified lines | ||
| 819 | 819 | case 1: |
| 820 | 820 | show_helptext(_("Load Alternate Configuration"), load_config_help); |
| 821 | 821 | break; |
| 822 | − case 255: | |
| 822 | + case KEY_ESC: | |
| 823 | 823 | return; |
| 824 | 824 | } |
| 825 | 825 | } |
| @@ -843,7 +843,7 @@ static void conf_save(void) · 17 unmodified lines | ||
| 843 | 843 | case 1: |
| 844 | 844 | show_helptext(_("Save Alternate Configuration"), save_config_help); |
| 845 | 845 | break; |
| 846 | − case 255: | |
| 846 | + case KEY_ESC: | |
| 847 | 847 | return; |
| 848 | 848 | } |
| 849 | 849 | } |
| @@ -883,12 +883,15 @@ int main(int ac, char **av) · 33 unmodified lines | ||
| 883 | 883 | init_wsize(); |
| 884 | 884 | reset_dialog(); |
| 885 | 885 | init_dialog(menu_backtitle); |
| 886 | − conf(&rootmenu); | |
| 887 | − reset_dialog(); | |
| 888 | − res = dialog_yesno(NULL, | |
| 889 | − _("Do you wish to save your " | |
| 890 | − "new kernel configuration?"), | |
| 891 | − 5, 60); | |
| 886 | + do { | |
| 887 | + conf(&rootmenu); | |
| 888 | + reset_dialog(); | |
| 889 | + res = dialog_yesno(NULL, | |
| 890 | + _("Do you wish to save your " | |
| 891 | + "new kernel configuration?\n" | |
| 892 | + "<ESC><ESC> to continue."), | |
| 893 | + 6, 60); | |
| 894 | + } while (res == KEY_ESC); | |
| 892 | 895 | end_dialog(); |
| 893 | 896 | if (res == 0) { |
| 894 | 897 | if (conf_write(NULL)) { |