menu: never activate a row from an earlier frame (#574)

Nav kept the rows of the last frame that drew them. When a title click
closed the popup before its rows drew again, Enter or Space ran the
cached command with its old enabled state. Nav::load now clears the rows,
so the keys act only on rows drawn this frame under the current gate.
This commit is contained in:
Dylan M. Taylor
2026-11-03 23:06:04 -05:00
committed by GitHub
parent 4029f023a6
commit fe4e2ff3ef
2 changed files with 20 additions and 0 deletions
+3
View File
@@ -120,6 +120,9 @@ impl Nav {
if top != nav.top {
nav = Nav { top, tops: std::mem::take(&mut nav.tops), ..Default::default() };
}
// Rows hold the command and enabled state of the frame that drew them. A popup that is
// not drawn this frame (closed by a title click) must leave nothing for the keys to run.
nav.rows.clear();
nav
}
+17
View File
@@ -10,6 +10,23 @@ use crate::bar::nav::{ARROW, Nav, heading, is_open};
#[path = "bar_keys.rs"]
mod keys;
#[test]
fn rows_from_an_earlier_frame_are_never_activated() {
let ctx = egui::Context::default();
let id = Id::unique("nav");
let row = crate::bar::nav::Row {
widget: Id::unique("row"),
enabled: true,
command: Some(Builtin::Quit.command()),
rect: Rect::NOTHING,
mnemonic: None,
};
let mut stale = Nav::default();
stale.rows = vec![vec![row]];
ctx.data_mut(|d| d.insert_temp(id, stale));
assert!(Nav::load(&ctx, id).rows.is_empty(), "rows are this frame's only");
}
fn item(id: &str, label: &str) -> Item {
Item::new(id, label)
}