Repository: openai/codex
File: codex-rs/tui/src/app.rs (Rust)

Code before:

    pub(crate) enhanced_keys_supported: bool,

    /// Controls the animation thread that sends CommitTick events.
    pub(crate) commit_anim_running: Arc<AtomicBool>,

    // Esc-backtracking state grouped
    pub(crate) backtrack: crate::app_backtrack::BacktrackState,
    pub(crate) feedback: codex_feedback::CodexFeedback,
    /// Set when the user confirms an update; propagated on exit.
    pub(crate) pending_update_action: Option<UpdateAction>,

    /// Ignore the next ShutdownComplete event when we're intentionally
    /// stopping a thread (e.g., before starting a new one).
    suppress_shutdown_complete: bool,

    // One-shot suppression of the next world-writable scan after user confirmation.
    skip_world_writable_scan_once: bool,

    // TODO(jif) drop once new UX is here.
    // Track external agent approvals spawned via AgentControl.
    /// Map routed approval IDs to their originating external threads and original IDs.
    external_approval_routes: HashMap<String, (ThreadId, String)>,
    /// Buffered Codex events while external approvals are pending.
    paused_codex_events: VecDeque<Event>,
}

impl App {
    pub fn chatwidget_init_for_forked_or_resumed_thread(
        &self,
        tui: &mut tui::Tui,
        cfg: codex_core::config::Config,
    ) -> crate::chatwidget::ChatWidgetInit {
        crate::chatwidget::ChatWidgetInit {
            config: cfg,
            frame_requester: tui.frame_requester(),
            app_event_tx: self.app_event_tx.clone(),
            initial_prompt: None,
            initial_images: Vec::new(),
            // Fork/resume bootstraps here don't carry any prefilled message content.
            initial_text_elements: Vec::new(),
            enhanced_keys_supported: self.enhanced_keys_supported,
            auth_manager: self.auth_manager.clone(),
            models_manager: self.server.get_models_manager(),
            feedback: self.feedback.clone(),
            is_first_run: false,
            model: Some(self.current_model.clone()),
        }
    }

    async fn shutdown_current_thread(&mut self) {

Review comment (performance):
We remove backtrack_render_pending because it was only needed for the rollback-based flow. In the old flow, we’d send ThreadRollback, then wait for
ThreadRolledBack, then set a flag so the next draw would re-render scrollback.

In the new fork-based flow:

- We wait for ConversationPathResponseEvent,
- Fork + swap threads immediately,
- Trim transcript and call render_transcript_once(tui) right there.

So there’s no deferred “render on next draw” step left. The flag becomes dead, and keeping it would just add complexity without any effect.

Code after:
    pub(crate) auth_manager: Arc<AuthManager>,
    /// Config is stored here so we can recreate ChatWidgets as needed.
    pub(crate) config: Config,
    pub(crate) active_profile: Option<String>,

    pub(crate) file_search: FileSearchManager,

    pub(crate) transcript_cells: Vec<Arc<dyn HistoryCell>>,

    // Pager overlay state (Transcript or Static like Diff)
    pub(crate) overlay: Option<Overlay>,
    pub(crate) deferred_history_lines: Vec<Line<'static>>,
    has_emitted_history_lines: bool,

    pub(crate) enhanced_keys_supported: bool,

    /// Controls the animation thread that sends CommitTick events.
    pub(crate) commit_anim_running: Arc<AtomicBool>,

    // Esc-backtracking state grouped
    pub(crate) backtrack: crate::app_backtrack::BacktrackState,
    /// When set, the next draw re-renders the transcript into terminal scrollback once.
    ///
    /// This is used after a confirmed thread rollback to ensure scrollback reflects the trimmed
    /// transcript cells.
    pub(crate) backtrack_render_pending: bool,
    pub(crate) feedback: codex_feedback::CodexFeedback,
    /// Set when the user confirms an update; propagated on exit.
    pub(crate) pending_update_action: Option<UpdateAction>,

    /// Ignore the next ShutdownComplete event when we're intentionally
    /// stopping a thread (e.g., before starting a new one).
    suppress_shutdown_complete: bool,

    windows_sandbox: WindowsSandboxState,

    // TODO(jif) drop once new UX is here.
    // Track external agent approvals spawned via AgentControl.
    /// Map routed approval IDs to their originating external threads and original IDs.
    external_approval_routes: HashMap<String, (ThreadId, String)>,
    /// Buffered Codex events while external approvals are pending.
    paused_codex_events: VecDeque<Event>,
}

#[derive(Default)]
struct WindowsSandboxState {
    setup_started_at: Option<Instant>,
    // One-shot suppression of the next world-writable scan after user confirmation.
    skip_world_writable_scan_once: bool,
}