fix rendering bug

This commit is contained in:
2026-06-04 14:05:45 +02:00
parent 7f4249dde9
commit 3164873a66
5 changed files with 487 additions and 466 deletions
+8 -103
View File
@@ -298,87 +298,6 @@ struct AlternateScreen {
scroll_bottom: usize,
}
/// Timing stats for performance debugging.
/// Only populated when the `render_timing` feature is enabled.
#[derive(Debug, Default)]
pub struct ProcessingStats {
#[cfg(feature = "render_timing")]
/// Total time spent in scroll_up operations (nanoseconds).
pub scroll_up_ns: u64,
#[cfg(feature = "render_timing")]
/// Number of scroll_up calls.
pub scroll_up_count: u32,
#[cfg(feature = "render_timing")]
/// Total time spent in scrollback operations (nanoseconds).
pub scrollback_ns: u64,
#[cfg(feature = "render_timing")]
/// Time in VecDeque pop_front.
pub pop_front_ns: u64,
#[cfg(feature = "render_timing")]
/// Time in VecDeque push_back.
pub push_back_ns: u64,
#[cfg(feature = "render_timing")]
/// Time in mem::swap.
pub swap_ns: u64,
#[cfg(feature = "render_timing")]
/// Total time spent in line clearing (nanoseconds).
pub clear_line_ns: u64,
#[cfg(feature = "render_timing")]
/// Total time spent in text handler (nanoseconds).
pub text_handler_ns: u64,
#[cfg(feature = "render_timing")]
/// Total time spent in CSI handler (nanoseconds).
pub csi_handler_ns: u64,
#[cfg(feature = "render_timing")]
/// Number of CSI sequences processed.
pub csi_count: u32,
#[cfg(feature = "render_timing")]
/// Number of characters processed.
pub chars_processed: u32,
#[cfg(feature = "render_timing")]
/// Total time spent in VT parser (consume_input) - nanoseconds.
pub vt_parser_ns: u64,
#[cfg(feature = "render_timing")]
/// Number of consume_input calls.
pub consume_input_count: u32,
}
impl ProcessingStats {
#[cfg(feature = "render_timing")]
pub fn reset(&mut self) {
*self = Self::default();
}
#[cfg(not(feature = "render_timing"))]
pub fn reset(&mut self) {}
#[cfg(feature = "render_timing")]
pub fn log_if_slow(&self, threshold_ms: u64) {
let total_ms =
(self.scroll_up_ns + self.text_handler_ns + self.csi_handler_ns)
/ 1_000_000;
if total_ms >= threshold_ms {
let vt_only_ns = self
.vt_parser_ns
.saturating_sub(self.text_handler_ns + self.csi_handler_ns);
log::info!(
"[PARSE_DETAIL] text={:.2}ms ({}chars) csi={:.2}ms ({}x) vt_only={:.2}ms ({}calls) scroll={:.2}ms ({}x)",
self.text_handler_ns as f64 / 1_000_000.0,
self.chars_processed,
self.csi_handler_ns as f64 / 1_000_000.0,
self.csi_count,
vt_only_ns as f64 / 1_000_000.0,
self.consume_input_count,
self.scroll_up_ns as f64 / 1_000_000.0,
self.scroll_up_count,
);
}
}
#[cfg(not(feature = "render_timing"))]
pub fn log_if_slow(&self, _threshold_ms: u64) {}
}
/// Kitty-style ring buffer for scrollback history.
///
/// Pre-allocates all lines upfront to avoid allocation during scrolling.
@@ -569,7 +488,7 @@ pub struct Terminal {
/// Synchronized output mode (for reducing flicker).
synchronized_output: bool,
/// Performance timing stats (for debugging).
pub stats: ProcessingStats,
/// Command queue for terminal-to-application communication.
/// Commands are added by OSC handlers and consumed by the application.
command_queue: Vec<TerminalCommand>,
@@ -587,12 +506,6 @@ impl Terminal {
/// Creates a new terminal with the given dimensions and scrollback limit.
pub fn new(cols: usize, rows: usize, scrollback_limit: usize) -> Self {
log::info!(
"Terminal::new: cols={}, rows={}, scroll_bottom={}",
cols,
rows,
rows.saturating_sub(1)
);
let grid = vec![vec![Cell::default(); cols]; rows];
let line_map: Vec<usize> = (0..rows).collect();
@@ -632,7 +545,7 @@ impl Terminal {
bracketed_paste: false,
focus_reporting: false,
synchronized_output: false,
stats: ProcessingStats::default(),
command_queue: Vec::new(),
image_storage: ImageStorage::new(),
cell_width: 10.0, // Default, will be set by renderer
@@ -668,6 +581,12 @@ impl Terminal {
}
}
/// Check if any line is dirty.
#[inline]
pub fn has_any_dirty_line(&self) -> bool {
self.dirty_lines[0] != 0 || self.dirty_lines[1] != 0 || self.dirty_lines[2] != 0 || self.dirty_lines[3] != 0
}
/// Clear all dirty line flags.
#[inline]
pub fn clear_dirty_lines(&mut self) {
@@ -789,14 +708,6 @@ impl Terminal {
return;
}
log::info!(
"Terminal::resize: {}x{} -> {}x{}",
self.cols,
self.rows,
cols,
rows
);
let old_cols = self.cols;
let old_rows = self.rows;
@@ -1692,12 +1603,6 @@ impl Handler for Terminal {
let statusline =
content.filter(|s| !s.is_empty());
log::info!(
"OSC 51: Set statusline: {:?}",
statusline
.as_ref()
.map(|s| format!("{} bytes", s.len()))
);
self.command_queue.push(
TerminalCommand::SetStatusline(statusline),
);