Attached patch introduces a new environment variable hotkey_action. It can be set to select or execute, whereas the latter is the default. So the default behaviour doesn't change. With select set instead a menu entry is just selected and not executed/booted on hotkey press.

This is for example useful for long menus to directly jump to some initial and afterwards select the desired entry without going through the whole menu. One still has to explicitly mark the menu entry to jump to with the hotkey attribute. This patch only allows to change the action to take on hotkey press.

Not much code and most is inspired from grub_menu_get_timeout. Applies and works with r3991.

    Add support to the menu for changing the action on hotkey press:
    execute (default), select

    * grub-core/normal/menu.c (DEFAULT_HOTKEY_ACTION): New define.
    (run_menu): Handle hotkey_action.
    (grub_menu_get_hotkey_action): New function.
    * include/grub/menu.h (grub_menu_get_hotkey_action): New prototype.
    (grub_hotkey_action_type_t): New enum.
=== modified file 'grub-core/normal/menu.c'
--- grub-core/normal/menu.c     2012-02-18 18:59:01 +0000
+++ grub-core/normal/menu.c     2012-02-26 22:31:49 +0000
@@ -37,6 +37,10 @@
    entry failing to boot.  */
 #define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
 
+/* The default action to choose for hotkeys when nothing is explicitly
+   specified. */
+#define DEFAULT_HOTKEY_ACTION GRUB_HOTKEY_ACTION_TYPE_EXECUTE
+
 grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
                                     int nested) = NULL;
 
@@ -70,6 +74,35 @@
   return e;
 }
 
+/* Return the hotkey action. If the variable "hotkey_action" is not set
+   or invalid, return DEFAULT_HOTKEY_ACTION.  */
+grub_hotkey_action_type_t
+grub_menu_get_hotkey_action (void)
+{
+  const char *val;
+
+  val = grub_env_get ("hotkey_action");
+
+  if (val)
+  {
+    if (grub_strcasecmp (val, "execute") == 0)
+      {
+        return GRUB_HOTKEY_ACTION_TYPE_EXECUTE;
+      }
+    else if (grub_strcasecmp (val, "select") == 0)
+      {
+        return GRUB_HOTKEY_ACTION_TYPE_SELECT;
+      }
+    /* If the value is invalid, unset the variable.  */
+    else
+      {
+        grub_env_unset ("hotkey_action");
+      }
+  }
+
+  return DEFAULT_HOTKEY_ACTION;
+}
+
 /* Return the current timeout. If the variable "timeout" is not set or
    invalid, return -1.  */
 int
@@ -496,6 +529,7 @@
   grub_uint64_t saved_time;
   int default_entry, current_entry;
   int timeout;
+  grub_hotkey_action_type_t hotkey_action;
 
   default_entry = get_entry_number (menu, "default");
 
@@ -519,6 +553,7 @@
  refresh:
   menu_init (current_entry, menu, nested);
 
+  hotkey_action = grub_menu_get_hotkey_action ();
   timeout = grub_menu_get_timeout ();
 
   if (timeout > 0)
@@ -653,10 +688,21 @@
                     i++, entry = entry->next)
                  if (entry->hotkey == c)
                    {
-                     menu_fini ();
-                     *auto_boot = 0;
-                     return i;
-                   }
+             switch (hotkey_action)
+               {
+               case GRUB_HOTKEY_ACTION_TYPE_SELECT:
+                 current_entry = i;
+                 menu_set_chosen_entry (current_entry);
+                 break;
+               case GRUB_HOTKEY_ACTION_TYPE_EXECUTE:
+                 menu_fini ();
+                 *auto_boot = 0;
+                 return i;
+               default:
+                 /* Never reach here */
+                 break;
+               }
+               }
              }
              break;
            }

=== modified file 'include/grub/menu.h'
--- include/grub/menu.h 2011-01-10 22:27:58 +0000
+++ include/grub/menu.h 2012-02-26 22:31:49 +0000
@@ -91,11 +91,20 @@
 }
 *grub_menu_execute_callback_t;
 
+/* Possible actions to perform when a hotkey is pressed */
+typedef enum
+{
+  GRUB_HOTKEY_ACTION_TYPE_EXECUTE,
+  GRUB_HOTKEY_ACTION_TYPE_SELECT
+} grub_hotkey_action_type_t;
+
+
 grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
 int grub_menu_get_timeout (void);
 void grub_menu_set_timeout (int timeout);
 void grub_menu_entry_run (grub_menu_entry_t entry);
 int grub_menu_get_default_entry_index (grub_menu_t menu);
+grub_hotkey_action_type_t grub_menu_get_hotkey_action (void);
 
 void grub_menu_init (void);
 void grub_menu_fini (void);

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to