fix(menu): keep the countdown going after a spurious key event

Some firmware signals the key event without a key being available. The
simple menu then skipped the countdown for that tick, and the basic menu
started waiting for the full timeout again, so firmware that kept
signaling the key event would never boot the default entry.

Read the key inside the wait, and when no key is available keep waiting
on the same timer.
This commit is contained in:
alex authored and Alex Zenla committed 2026-09-26 20:52:15 -07:00
1 parent 11736ccabb
commit 78bcaa79ff
3 files changed
+38 -41

No files matched your search

+2 -9
View File
@@ -1,5 +1,5 @@
use crate::entries::BootableEntry;
use crate::menu::{BootMenu, wait_for_key};
use crate::menu::{BootMenu, read_key};
use anyhow::{Context, Result};
use core::time::Duration;
use log::info;
@@ -30,15 +30,8 @@ enum MenuOperation {
/// performed.
fn read(input: &mut Input, timeout: &Duration) -> Result<MenuOperation> {
// If the timer triggered, the user did not select a numbered entry.
if !wait_for_key(input, *timeout)? {
let Some(key) = read_key(input, *timeout)? else {
return Ok(MenuOperation::Timeout);
}
// If we reach here, there is a key event.
// Some firmware signals the key event without a key being available,
// in which case there is nothing to do.
let Some(key) = input.read_key().context("unable to read key")? else {
return Ok(MenuOperation::Nop);
};
match key {
+2 -8
View File
@@ -1,5 +1,5 @@
use crate::entries::BootableEntry;
use crate::menu::{BootMenu, wait_for_key};
use crate::menu::{BootMenu, read_key};
use alloc::format;
use alloc::string::String;
use anyhow::{Context, Result, anyhow};
@@ -193,7 +193,7 @@ fn run(
// Wait for a key, waking up every tick to update the countdown.
let tick = remaining.map_or(TICK, |remaining| remaining.min(TICK));
if !wait_for_key(input, tick)? {
let Some(key) = read_key(input, tick)? else {
// Without a countdown there's nothing to do until a key is pressed.
let Some(left) = remaining else {
continue;
@@ -205,12 +205,6 @@ fn run(
}
remaining = Some(left);
continue;
}
// Some firmware signals the key event without a key being available,
// in which case there is nothing to do.
let Some(key) = input.read_key().context("unable to read key")? else {
continue;
};
// Any key stops the countdown, which leaves escape with nothing else to do.