diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index 86d741415..a97948f3e 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -236,6 +236,20 @@ impl App<'_> { self.app_event_tx.send(AppEvent::ExitRequest); } }, + KeyEvent { + code: KeyCode::Esc, + kind: KeyEventKind::Press, + .. + } => match &mut self.app_state { + AppState::Chat { widget } => { + if !widget.on_esc() { + self.dispatch_key_event(key_event); + } + } + AppState::Onboarding { .. } => { + self.dispatch_key_event(key_event); + } + }, KeyEvent { code: KeyCode::Char('z'), modifiers: crossterm::event::KeyModifiers::CONTROL, diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 8a47353cb..344f02584 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -571,6 +571,14 @@ impl ChatWidget<'_> { self.bottom_pane.on_file_search_result(query, matches); } + pub(crate) fn on_esc(&mut self) -> bool { + if self.bottom_pane.is_task_running() { + self.interrupt_running_task(); + return true; + } + false + } + /// Handle Ctrl-C key press. /// Returns CancellationEvent::Handled if the event was consumed by the UI, or /// CancellationEvent::Ignored if the caller should handle it (e.g. exit). diff --git a/codex-rs/tui/src/status_indicator_widget.rs b/codex-rs/tui/src/status_indicator_widget.rs index 513422bb4..6ef293208 100644 --- a/codex-rs/tui/src/status_indicator_widget.rs +++ b/codex-rs/tui/src/status_indicator_widget.rs @@ -231,14 +231,14 @@ impl WidgetRef for StatusIndicatorWidget { spans.extend(animated_spans); // Space between header and bracket block spans.push(Span::raw(" ")); - // Non-animated, dim bracket content, with only "Ctrl c" bold + // Non-animated, dim bracket content, with keys bold let bracket_prefix = format!("({elapsed}s • "); spans.push(Span::styled( bracket_prefix, Style::default().fg(Color::Gray).add_modifier(Modifier::DIM), )); spans.push(Span::styled( - "Ctrl C", + "Esc", Style::default() .fg(Color::Gray) .add_modifier(Modifier::DIM | Modifier::BOLD),