petitboot_ps3_nc_LDADD = $(common_libs) $(libdir)/libps3-utils.so
 #petitboot_ps3_nc_LDFLAGS = -L$(libdir) -lps3-utils
 
+EXTRA_DIST = ui-guidelines.text
 
 MAINTAINERCLEANFILES = Makefile.in
 
                        "Petitboot Option Editor");
        boot_editor->scr.frame.rtitle = NULL;
        boot_editor->scr.frame.help = talloc_strdup(boot_editor,
-                       "Enter=accept");
+                       "tab=next, shift+tab=previous, x=exit, h=help");
        nc_scr_frame_draw(&boot_editor->scr);
 
        if (item) {
 
        bool handled;
 
        handled = widgetset_process_key(screen->widgetset, key);
+
+       if (!handled) {
+               switch (key) {
+               case 'x':
+               case 27: /* esc */
+                       screen->exit = true;
+                       break;
+               case 'h':
+                       screen->show_help = true;
+                       break;
+               }
+       }
+
        if (screen->exit) {
                screen->on_exit(screen->cui);
 
-       } else if (screen->show_help || (!handled && key == 'h')) {
+       } else if (screen->show_help) {
                screen->show_help = false;
                cui_show_help(screen->cui, "System Configuration",
                                config_help_text);
                        "Petitboot System Configuration");
        screen->scr.frame.rtitle = NULL;
        screen->scr.frame.help = talloc_strdup(screen,
-                       "tab=next, shift+tab=previous");
+                       "tab=next, shift+tab=previous, x=exit, h=help");
        nc_scr_frame_draw(&screen->scr);
 
        scrollok(screen->scr.sub_ncw, true);
 
        case KEY_UP:
                pmenu_move_cursor(menu, REQ_UP_ITEM);
                break;
+       case KEY_BTAB:
+               pmenu_move_cursor(menu, REQ_PREV_ITEM);
+               break;
        case KEY_DOWN:
                pmenu_move_cursor(menu, REQ_DOWN_ITEM);
                break;
+       case '\t':
+               pmenu_move_cursor(menu, REQ_NEXT_ITEM);
+               break;
        case 'e':
                if (item->on_edit)
                        item->on_edit(item);
        case 'c':
                cui_show_config(cui_from_arg(scr->ui_ctx));
                break;
+       case KEY_F(1):
        case 'h':
                if (menu->help_text)
                        cui_show_help(cui_from_arg(scr->ui_ctx),
 
 
        switch (key) {
        case 'x':
+       case 27: /* esc */
                screen->on_exit(screen->cui);
                break;
        case KEY_DOWN:
 {
        screen->help_title = title;
        screen->help_text = text;
-       screen->scr.frame.help = "x=exit h=help";
+       screen->scr.frame.help = "x=exit, h=help";
 }
 
 static int text_screen_post(struct nc_scr *scr)
 
--- /dev/null
+Petitboot ncurses UI guidelines
+
+General key bindings:
+
+ x: Exit the current screen
+ 
+    When the focus is on a text-input field, this key will be treated
+    litereally (ie, it inputs an 'x' in to the text field). Because of this,
+    we should avoid putting a text field as the first field on a screen.
+
+    We also support 'Esc' as a secondary exit key, but this can cause
+    problems with some terminals (because Esc is used to initiate an input
+    escape sequence, it causes ncurses to delay, waiting for more keys).
+    So, Esc should not be listed as a key in the UI help.
+
+ h: Show help
+
+    Same restrictions as the 'x' key with text input widgets. We support F1
+    too, but this is often used by the actual terminal emulator to show help
+    locally instead.
+
+Form key bindings:
+
+ tab: Next widget
+ shift+tab: Previous widget
+
+ down: Next widget
+ up: Previous widget
+
+Text screen key bindings:
+
+ up/down: scroll
+
+Menu key bindings:
+
+ up: Next item
+ down: Previous item
+
+ tab: Next item
+ shift+tab: Previous item
+
+ Enter: select item
+ Space: select item
+