From 515aa9a4fb16f89544d065ac57e8ce01a2360929 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Wed, 29 Apr 2026 17:26:11 -0700 Subject: [PATCH] tui: return from side chat on Ctrl-D (#20282) ## Why Fixes #20264. Side conversations are an ephemeral layer on top of the main chat. Pressing `Ctrl+D` from an empty side-chat composer should unwind back to the parent thread, matching the existing side-return behavior, instead of falling through to the global quit shortcut and exiting Codex. ## What changed The side-return shortcut matcher now treats `Ctrl+D` the same way it already treats `Esc` and `Ctrl+C`. Because app-level side-return handling runs before the chat widget's global quit handling, this returns from `/side` while preserving normal `Ctrl+D` quit behavior outside side conversations. The existing shortcut coverage was updated to include lowercase and uppercase `Ctrl+D` key events. ## Verification - `cargo test -p codex-tui side_return_shortcuts_match_esc_ctrl_c_and_ctrl_d` - `cargo test -p codex-tui` starts successfully and the new shortcut test passes, but the broader suite later aborts in the unrelated existing test `app::tests::attach_live_thread_for_selection_rejects_unmaterialized_fallback_threads` with a stack overflow. --- codex-rs/tui/src/app/platform_actions.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/codex-rs/tui/src/app/platform_actions.rs b/codex-rs/tui/src/app/platform_actions.rs index 415318a3e..f19ed0bb6 100644 --- a/codex-rs/tui/src/app/platform_actions.rs +++ b/codex-rs/tui/src/app/platform_actions.rs @@ -65,7 +65,11 @@ pub(super) fn side_return_shortcut_matches(key_event: KeyEvent) -> bool { modifiers, kind: KeyEventKind::Press, .. - } if modifiers.contains(KeyModifiers::CONTROL) && c.eq_ignore_ascii_case(&'c') => true, + } if modifiers.contains(KeyModifiers::CONTROL) + && (c.eq_ignore_ascii_case(&'c') || c.eq_ignore_ascii_case(&'d')) => + { + true + } _ => false, } } @@ -75,7 +79,7 @@ mod tests { use super::*; #[test] - fn side_return_shortcuts_match_esc_and_ctrl_c() { + fn side_return_shortcuts_match_esc_ctrl_c_and_ctrl_d() { assert!(side_return_shortcut_matches(KeyEvent::new( KeyCode::Esc, KeyModifiers::NONE, @@ -93,10 +97,14 @@ mod tests { KeyCode::Char('C'), KeyModifiers::CONTROL, ))); - assert!(!side_return_shortcut_matches(KeyEvent::new( + assert!(side_return_shortcut_matches(KeyEvent::new( KeyCode::Char('d'), KeyModifiers::CONTROL, ))); + assert!(side_return_shortcut_matches(KeyEvent::new( + KeyCode::Char('D'), + KeyModifiers::CONTROL, + ))); assert!(!side_return_shortcut_matches(KeyEvent::new_with_kind( KeyCode::Esc, KeyModifiers::NONE,