diff --git a/agentydragon/README.md b/agentydragon/README.md index f75221ef47..1a0afefde7 100644 --- a/agentydragon/README.md +++ b/agentydragon/README.md @@ -43,6 +43,10 @@ This file documents the changes introduced on the `agentydragon` branch - Updated Markdown rendering in chat UI and logs to honor compact mode globally (diffs, docs, help messages). - Added unit tests covering H1–H6 heading spacing for both compact and default modes. +## codex-rs/tui: opaque approval dialog background +- Filled the approval dialog area with a DarkGray background to block underlying prompt text. +- Added a unit test in `tui/src/user_approval_widget.rs` to assert no transparent or sentinel background remains in the dialog region. + ## Documentation tasks Tasks live under `agentydragon/tasks/` as individual Markdown files. Please update each task’s **Status** and **Implementation** sections in place rather than maintaining a static list here. diff --git a/agentydragon/tasks/38-approval-dialog-transparent-background-fix.md b/agentydragon/tasks/38-approval-dialog-transparent-background-fix.md index 784452b2c7..fb684b3ed6 100644 --- a/agentydragon/tasks/38-approval-dialog-transparent-background-fix.md +++ b/agentydragon/tasks/38-approval-dialog-transparent-background-fix.md @@ -1,18 +1,18 @@ +++ id = "38" title = "Fix Approval Dialog Transparent Background" -status = "Not started" +status = "Done" dependencies = "" summary = "The approval dialog background is transparent, causing prompt text underneath to overlap and become unreadable." -last_updated = "2025-06-25T00:00:00Z" +last_updated = "2025-06-25T23:00:00.000000" +++ > *UI bug:* When the approval dialog appears, its background is transparent and any partially entered prompt text shows through, overlapping and confusing the dialog. ## Status -**General Status**: Not started -**Summary**: Identify the CSS/ANSI background settings for dialogs and enforce an opaque backdrop before text rendering. +**General Status**: Done +**Summary**: Identify and implement an opaque background for the approval dialog to prevent underlying text bleed-through. ## Goal @@ -25,8 +25,9 @@ Ensure the approval dialog is drawn with a solid background color (matching the ## Implementation -- Update dialog background color in TUI rendering code (`.tui` component). -- Add a test to verify no transparent cells in dialog region. +- Updated `render_ref` in `codex-rs/tui/src/user_approval_widget.rs` to fill the entire dialog area with a `DarkGray` background before drawing the border and content. +- Implemented nested loops over the dialog `Rect` calling `buf[(col, row)].set_bg(Color::DarkGray)` on each cell. +- Added unit test `render_approval_dialog_fills_background` in `tui/src/user_approval_widget.rs` to render the widget onto a buffer pre-filled with a red background and verify no cell in the dialog region remains transparent or retains the sentinel background. ## Notes diff --git a/codex-rs/tui/src/user_approval_widget.rs b/codex-rs/tui/src/user_approval_widget.rs index b763199436..90559bd365 100644 --- a/codex-rs/tui/src/user_approval_widget.rs +++ b/codex-rs/tui/src/user_approval_widget.rs @@ -406,6 +406,12 @@ impl WidgetRef for &UserApprovalWidget<'_> { } }; + // Fill the entire dialog area with a solid background to block underlying text. + for row in area.y..area.y + area.height { + for col in area.x..area.x + area.width { + buf[(col, row)].set_bg(Color::DarkGray); + } + } outer.render(area, buf); self.confirmation_prompt.clone().render(prompt_chunk, buf); Widget::render(List::new(lines), response_chunk, buf); @@ -417,6 +423,9 @@ mod tests { use super::*; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use std::sync::mpsc; + use ratatui::buffer::{Buffer, Cell}; + use ratatui::layout::Rect; + use ratatui::style::{Color, Style}; #[test] fn esc_in_input_mode_cancels_input_and_preserves_value() { @@ -466,4 +475,45 @@ mod tests { assert!(truncated.starts_with("Yes, always allow running `")); assert!(truncated.ends_with("` for this session (a)")); } + + #[test] + fn render_approval_dialog_fills_background() { + // Arrange: create a basic Exec approval widget in Select mode. + let (tx, _) = mpsc::channel(); + let app_event_tx = AppEventSender::new(tx); + let widget = UserApprovalWidget::new( + ApprovalRequest::Exec { + id: "id".into(), + command: vec!["cmd".into()], + cwd: std::env::current_dir().unwrap(), + reason: None, + }, + app_event_tx, + ); + + // Determine dialog area size. + let width = 50; + let height = widget.get_height(&Rect::new(0, 0, width, u16::MAX)); + let area = Rect::new(0, 0, width, height); + + // Pre-fill buffer with a sentinel background (red). + let mut buf = Buffer::empty(area); + for row in area.y..area.y + area.height { + for col in area.x..area.x + area.width { + buf[(col, row)].set_bg(Color::Red); + } + } + + // Act: render the widget + (&widget).render_ref(area, &mut buf); + + // Assert: no cell in dialog region remains transparent or retains the sentinel background. + for row in area.y..area.y + area.height { + for col in area.x..area.x + area.width { + let cell = buf.cell((col, row)).unwrap(); + assert_ne!(cell.bg, Color::Reset, "Found transparent cell at ({}, {})", col, row); + assert_ne!(cell.bg, Color::Red, "Found unfilled cell at ({}, {})", col, row); + } + } + } }