diff --git a/crates/ui-egui/src/app/playback.rs b/crates/ui-egui/src/app/playback.rs index 73e765ff7..c959829cd 100644 --- a/crates/ui-egui/src/app/playback.rs +++ b/crates/ui-egui/src/app/playback.rs @@ -144,6 +144,10 @@ impl SlideApp { let visible = show::viewport_visible(ctx); let Some(doc) = self.session.active().map(|d| d.doc.clone()) else { return }; let Some(show) = self.show.as_mut() else { return }; + if show.presenter_grid && self.services.presenter.as_ref().is_some_and(|host| !host.is_open()) { + // A web popup closed with its grid open must not hold auto-advance while this tab is hidden (#1866). + show.presenter_grid = false; + } if visible { // A visible logic-only pass (`run_logic`) carries the last full frame's input time. // Anchoring that stale time to `now` would move the hidden clock backwards if the diff --git a/crates/ui-egui/src/presenter.rs b/crates/ui-egui/src/presenter.rs index 5d99e63c8..a58878830 100644 --- a/crates/ui-egui/src/presenter.rs +++ b/crates/ui-egui/src/presenter.rs @@ -175,6 +175,10 @@ impl View { .collect::>() }); for (key, modifiers) in keys { + if snapshot.grid && matches!(key, egui::Key::Space | egui::Key::Enter) { + // A focused thumbnail takes these to choose its slide; the show ignores them while the grid is open. + continue; + } // Consume once before widgets see Space/Enter, avoiding a second button activation. ui.input_mut(|i| i.consume_key(modifiers, key)); commands.push(Command::Key { @@ -525,6 +529,9 @@ mod tests { h.get_by_label("3").click(); h.run_steps(2); assert_eq!(h.state().2, vec![Command::Goto { slide: 2 }]); + h.key_press(egui::Key::Enter); + h.run_steps(2); + assert!(!h.state().2.iter().any(|c| matches!(c, Command::Key { .. })), "Enter is left to the focused thumbnail"); } #[test]