diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index bd9150ca..f6b735b1 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -22,7 +22,6 @@ use color_eyre::eyre::WrapErr; use crossterm::event::KeyCode; use crossterm::event::KeyEvent; use crossterm::event::KeyEventKind; -use crossterm::terminal::supports_keyboard_enhancement; use ratatui::style::Stylize; use ratatui::text::Line; use std::path::PathBuf; @@ -85,7 +84,7 @@ impl App { let conversation_manager = Arc::new(ConversationManager::new(auth_manager.clone())); - let enhanced_keys_supported = supports_keyboard_enhancement().unwrap_or(false); + let enhanced_keys_supported = tui.enhanced_keys_supported(); let chat_widget = match resume_selection { ResumeSelection::StartFresh | ResumeSelection::Exit => { diff --git a/codex-rs/tui/src/tui.rs b/codex-rs/tui/src/tui.rs index cacbc716..eeabec4e 100644 --- a/codex-rs/tui/src/tui.rs +++ b/codex-rs/tui/src/tui.rs @@ -27,6 +27,7 @@ use crossterm::event::PopKeyboardEnhancementFlags; use crossterm::event::PushKeyboardEnhancementFlags; use crossterm::terminal::EnterAlternateScreen; use crossterm::terminal::LeaveAlternateScreen; +use crossterm::terminal::supports_keyboard_enhancement; use ratatui::backend::Backend; use ratatui::backend::CrosstermBackend; use ratatui::crossterm::execute; @@ -160,6 +161,7 @@ pub struct Tui { alt_screen_active: Arc, // True when terminal/tab is focused; updated internally from crossterm events terminal_focused: Arc, + enhanced_keys_supported: bool, } #[cfg(unix)] @@ -266,6 +268,10 @@ impl Tui { } }); + // Detect keyboard enhancement support before any EventStream is created so the + // crossterm poller can acquire its lock without contention. + let enhanced_keys_supported = supports_keyboard_enhancement().unwrap_or(false); + Self { frame_schedule_tx, draw_tx, @@ -278,6 +284,7 @@ impl Tui { suspend_cursor_y: Arc::new(AtomicU16::new(0)), alt_screen_active: Arc::new(AtomicBool::new(false)), terminal_focused: Arc::new(AtomicBool::new(true)), + enhanced_keys_supported, } } @@ -287,6 +294,10 @@ impl Tui { } } + pub fn enhanced_keys_supported(&self) -> bool { + self.enhanced_keys_supported + } + pub fn event_stream(&self) -> Pin + Send + 'static>> { use tokio_stream::StreamExt; let mut crossterm_events = crossterm::event::EventStream::new();