From 4ca24302cb280ec5260e2bc0db7fcd8f6230254a Mon Sep 17 00:00:00 2001 From: Felipe Coury Date: Tue, 5 May 2026 12:20:39 -0300 Subject: [PATCH] fix(tui): clear sixel pet column artifacts --- codex-rs/tui/src/pets/ambient.rs | 3 +++ codex-rs/tui/src/pets/mod.rs | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/codex-rs/tui/src/pets/ambient.rs b/codex-rs/tui/src/pets/ambient.rs index 0d9c5bcf63..fc5ec71a66 100644 --- a/codex-rs/tui/src/pets/ambient.rs +++ b/codex-rs/tui/src/pets/ambient.rs @@ -106,6 +106,7 @@ pub(crate) struct AmbientPetDraw { pub(crate) protocol: ImageProtocol, pub(crate) x: u16, pub(crate) y: u16, + pub(crate) clear_top_y: u16, pub(crate) columns: u16, pub(crate) rows: u16, pub(crate) height_px: u16, @@ -249,6 +250,7 @@ impl AmbientPet { protocol, x, y, + clear_top_y: area.y, columns: size.columns, rows: size.rows, height_px: size.height_px, @@ -268,6 +270,7 @@ impl AmbientPet { protocol, x: area.x + area.width.saturating_sub(size.columns) / 2, y: area.y + area.height.saturating_sub(size.rows) / 2, + clear_top_y: area.y + area.height.saturating_sub(size.rows) / 2, columns: size.columns, rows: size.rows, height_px: size.height_px, diff --git a/codex-rs/tui/src/pets/mod.rs b/codex-rs/tui/src/pets/mod.rs index 2898f436ce..1db14df85a 100644 --- a/codex-rs/tui/src/pets/mod.rs +++ b/codex-rs/tui/src/pets/mod.rs @@ -99,7 +99,7 @@ fn render_pet_image( queue!(writer, SavePosition)?; if matches!(request.protocol, ImageProtocol::Sixel) { - clear_pet_cell_area(writer, &request)?; + clear_sixel_artifact_area(writer, &request)?; } queue!(writer, MoveTo(request.x, request.y))?; match payload { @@ -116,13 +116,17 @@ enum AmbientPetPayload { Bytes(Vec), } -fn clear_pet_cell_area(writer: &mut impl Write, request: &AmbientPetDraw) -> std::io::Result<()> { +fn clear_sixel_artifact_area( + writer: &mut impl Write, + request: &AmbientPetDraw, +) -> std::io::Result<()> { use crossterm::cursor::MoveTo; use crossterm::queue; let blank = " ".repeat(request.columns.into()); - for row in 0..request.rows { - queue!(writer, MoveTo(request.x, request.y.saturating_add(row)))?; + let clear_bottom_y = request.y.saturating_add(request.rows); + for row in request.clear_top_y..clear_bottom_y { + queue!(writer, MoveTo(request.x, row))?; write!(writer, "{blank}")?; } Ok(()) @@ -145,6 +149,7 @@ mod tests { protocol: ImageProtocol::Kitty, x: 2, y: 3, + clear_top_y: 3, columns: 4, rows: 5, height_px: 75, @@ -187,6 +192,7 @@ mod tests { protocol: ImageProtocol::KittyLocalFile, x: 2, y: 3, + clear_top_y: 3, columns: 4, rows: 2, height_px: 75, @@ -218,6 +224,7 @@ mod tests { protocol: ImageProtocol::Sixel, x: 2, y: 3, + clear_top_y: 1, columns: 4, rows: 2, height_px: 75, @@ -228,7 +235,7 @@ mod tests { render_ambient_pet_image(&mut output, Some(request)).unwrap(); let output = String::from_utf8(output).unwrap(); - assert!(output.contains("\x1b[4;3H \x1b[5;3H \x1b[4;3H")); + assert!(output.contains("\x1b[2;3H \x1b[3;3H \x1b[4;3H \x1b[5;3H \x1b[4;3H")); assert!(output.contains("fake-sixel")); assert!(output.contains("\x1b8")); }