mirror of
https://github.com/edera-dev/sprout.git
synced 2026-11-04 20:12:21 +00:00
fix(menu): let a key press show a hidden menu
A menu with a zero timeout or menu-hidden now waits 100 ms for a key press before booting the default entry, which is how the boot loader interface lets a user interrupt a hidden menu. menu-disabled still skips the wait.
This commit is contained in:
1 parent
590eeead5e
commit
8bb5f1132d
2 files changed
+31
-3
No files matched your search
+11
-2
@@ -410,6 +410,9 @@ fn run() -> Result<()> {
|
||||
// Whether the boot menu should wait for the user, instead of counting down.
|
||||
let mut wait_for_user = false;
|
||||
|
||||
// Whether the menu is disabled, so that a key press can't bring it up.
|
||||
let mut menu_disabled = false;
|
||||
|
||||
// Apply the chosen timeout.
|
||||
match timeout {
|
||||
BootloaderInterfaceTimeout::MenuForce => {
|
||||
@@ -424,11 +427,17 @@ fn run() -> Result<()> {
|
||||
menu_timeout = timeout;
|
||||
}
|
||||
|
||||
BootloaderInterfaceTimeout::MenuHidden | BootloaderInterfaceTimeout::MenuDisabled => {
|
||||
BootloaderInterfaceTimeout::MenuHidden => {
|
||||
// Hide the boot menu by setting the timeout to zero.
|
||||
menu_timeout = 0;
|
||||
}
|
||||
|
||||
BootloaderInterfaceTimeout::MenuDisabled => {
|
||||
// Hide the boot menu, and don't let a key press show it.
|
||||
menu_timeout = 0;
|
||||
menu_disabled = true;
|
||||
}
|
||||
|
||||
BootloaderInterfaceTimeout::Timeout(timeout) => {
|
||||
// Configure the timeout to the specified value.
|
||||
menu_timeout = timeout;
|
||||
@@ -593,7 +602,7 @@ fn run() -> Result<()> {
|
||||
let entry = match forced_entry {
|
||||
Some(entry) => entry,
|
||||
// Delegate to the menu to select an entry to boot.
|
||||
None => menu::select(&timer, menu_timeout, menu_style, &entries)
|
||||
None => menu::select(&timer, menu_timeout, menu_disabled, menu_style, &entries)
|
||||
.context("unable to select entry via boot menu")?,
|
||||
};
|
||||
|
||||
|
||||
+20
-1
@@ -31,6 +31,9 @@ mod logo;
|
||||
/// simple: A full-screen menu that selects entries with the arrow keys.
|
||||
pub mod simple;
|
||||
|
||||
/// How long a hidden menu waits for a key press before the default entry is booted.
|
||||
const HIDDEN_MENU_KEY_WAIT: Duration = Duration::from_millis(100);
|
||||
|
||||
/// The longest duration a single timer is set for. This is well within the range of
|
||||
/// the 100ns units that timers are set in, and still over a century long.
|
||||
const MAX_TIMER_DURATION: Duration = Duration::from_secs(u32::MAX as u64);
|
||||
@@ -167,13 +170,29 @@ pub fn wait_for_events(events: &[Event], timeout: Option<Duration>) -> Result<Op
|
||||
}
|
||||
|
||||
/// Shows a boot menu of the specified `style` to select a bootable entry to boot.
|
||||
/// See [BootMenu::select] for how `timeout` is handled.
|
||||
/// See [BootMenu::select] for how `timeout` is handled. A zero `timeout` hides the menu, but
|
||||
/// the menu is still shown if a key is pressed right away, unless `menu_disabled` is set.
|
||||
pub fn select<'live>(
|
||||
timer: &'live PlatformTimer,
|
||||
timeout: Option<Duration>,
|
||||
menu_disabled: bool,
|
||||
style: MenuStyle,
|
||||
entries: &'live [BootableEntry],
|
||||
) -> Result<&'live BootableEntry> {
|
||||
// A hidden menu gives the user a moment to ask for the menu with a key press.
|
||||
let timeout = if timeout.is_some_and(|timeout| timeout.is_zero()) && !menu_disabled {
|
||||
match uefi::system::with_stdin(|input| read_key(input, Some(HIDDEN_MENU_KEY_WAIT))) {
|
||||
Ok(Some(_)) => None,
|
||||
Ok(None) => timeout,
|
||||
Err(error) => {
|
||||
warn!("unable to check for a key press: {:#}", error);
|
||||
timeout
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timeout
|
||||
};
|
||||
|
||||
// Notify the bootloader interface that we are about to display the menu.
|
||||
// This is only informational, so it should not prevent booting.
|
||||
if let Err(error) = BootloaderInterface::mark_menu(timer) {
|
||||
|
||||
Reference in new issue
Block a user