From f4b2428485b041220ac4de7ba1d93a3a35f9170d Mon Sep 17 00:00:00 2001 From: Su Kang Yin Date: Thu, 25 Jun 2026 17:49:10 +0800 Subject: [PATCH] fix: keep quit-confirmation dialog visible on idle frames The ConfirmQuit dialog is drawn into sugarloaf before screen.render(), but render() calls discard_frame() whenever should_present is false (no panel damage and no animation) -- which is exactly the case while the dialog is up on an idle terminal. The dialog was thrown away and only appeared on frames a cursor blink happened to force, so it flickered in and out ('sometimes cannot see it'). Add a force_present flag to render(), set while in ConfirmQuit, so the dialog frame is always presented. --- frontends/rioterm/src/application.rs | 5 ++++- frontends/rioterm/src/screen/mod.rs | 11 +++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontends/rioterm/src/application.rs b/frontends/rioterm/src/application.rs index b2a2a1bebb..fb4dc2c235 100644 --- a/frontends/rioterm/src/application.rs +++ b/frontends/rioterm/src/application.rs @@ -1842,7 +1842,10 @@ impl ApplicationHandler for Application<'_> { ); } - if let Some(window_update) = route.window.screen.render() { + let force_present = route.path == RoutePath::ConfirmQuit; + if let Some(window_update) = + route.window.screen.render(force_present) + { use crate::context::renderable::{ BackgroundState, WindowUpdate, }; diff --git a/frontends/rioterm/src/screen/mod.rs b/frontends/rioterm/src/screen/mod.rs index 2be9533595..9b87e2674c 100644 --- a/frontends/rioterm/src/screen/mod.rs +++ b/frontends/rioterm/src/screen/mod.rs @@ -3488,7 +3488,10 @@ impl Screen<'_> { } } - pub(crate) fn render(&mut self) -> Option { + pub(crate) fn render( + &mut self, + force_present: bool, + ) -> Option { let current_route = self.context_manager.current_route(); let (grid_cols, grid_rows) = { let terminal = self.context_manager.current().terminal.lock(); @@ -3537,7 +3540,11 @@ impl Screen<'_> { .renderer .run(&mut self.sugarloaf, &mut self.context_manager); let has_animation = self.renderer.needs_redraw(); - let should_present = any_panel_dirty || has_animation; + // `force_present` keeps immediate-mode overlays (e.g. the quit + // confirmation dialog) on screen: without it an idle terminal has + // no panel damage / animation, so the frame would be discarded and + // the overlay would flicker out. + let should_present = force_present || any_panel_dirty || has_animation; if self.renderer.custom_mouse_cursor { let scale = self.sugarloaf.scale_factor();