fix(tui): clear footer row before rendering statusline

This commit is contained in:
liushiao
2026-05-27 11:47:03 +08:00
committed by Hunter Bown
parent 0c446bf4c5
commit 95a737b592
+42 -1
View File
@@ -11,7 +11,7 @@ use ratatui::{
layout::Rect,
style::{Color, Style},
text::{Line, Span},
widgets::{Paragraph, Widget},
widgets::{Block, Paragraph, Widget},
};
use unicode_width::UnicodeWidthStr;
@@ -573,6 +573,13 @@ impl Renderable for FooterWidget {
return;
}
// Repaint the whole footer row first so stale transcript glyphs from
// the previous frame cannot survive in cells this frame's spans do not
// touch (#2244).
Block::default()
.style(Style::default().bg(self.props.footer_bg))
.render(area, buf);
let preview_left_spans = self.left_spans(available_width);
let preview_left_width = span_width(&preview_left_spans);
let right_budget = available_width
@@ -652,6 +659,8 @@ mod tests {
use crate::palette;
use crate::tui::app::{App, AppMode, TuiOptions};
use ratatui::{
buffer::Buffer,
layout::Rect,
style::{Color, Style},
text::Span,
};
@@ -1377,4 +1386,36 @@ mod tests {
assert!(!rendered.contains("agent"));
assert!(!rendered.contains("deepseek-v4-flash"));
}
#[test]
fn render_clears_stale_cells_across_entire_footer_row() {
let app = make_app();
let widget = FooterWidget::new(idle_props_for(&app));
let area = Rect::new(0, 0, 48, 1);
let mut buf = Buffer::empty(area);
for x in area.x..area.x.saturating_add(area.width) {
buf[(x, area.y)]
.set_symbol("X")
.set_style(Style::default().fg(Color::Red).bg(Color::Blue));
}
widget.render(area, &mut buf);
let rendered: String = (area.x..area.x.saturating_add(area.width))
.map(|x| buf[(x, area.y)].symbol())
.collect();
assert!(
!rendered.contains('X'),
"footer render must clear stale row content before painting: {rendered:?}"
);
for x in area.x..area.x.saturating_add(area.width) {
assert_eq!(
buf[(x, area.y)].bg,
app.ui_theme.footer_bg,
"footer background should cover the full row"
);
}
}
}