mirror of
https://github.com/openai/codex.git
synced 2026-05-01 20:02:05 +03:00
Added feature switch to disable animations in TUI (#6870)
This PR adds support for a new feature flag `tui.animations`. By default, the TUI uses animations in its welcome screen, "working" spinners, and "shimmer" effects. This animations can interfere with screen readers, so it's good to provide a way to disable them. This change is inspired by [a PR](https://github.com/openai/codex/pull/4014) contributed by @Orinks. That PR has faltered a bit, but I think the core idea is sound. This version incorporates feedback from @aibrahim-oai. In particular: 1. It uses a feature flag (`tui.animations`) rather than the unqualified CLI key `no-animations`. Feature flags are the preferred way to expose boolean switches. They are also exposed via CLI command switches. 2. It includes more complete documentation. 3. It disables a few animations that the other PR omitted.
This commit is contained in:
@@ -69,6 +69,7 @@ pub(crate) struct BottomPane {
|
||||
is_task_running: bool,
|
||||
ctrl_c_quit_hint: bool,
|
||||
esc_backtrack_hint: bool,
|
||||
animations_enabled: bool,
|
||||
|
||||
/// Inline status indicator shown above the composer while a task is running.
|
||||
status: Option<StatusIndicatorWidget>,
|
||||
@@ -84,28 +85,38 @@ pub(crate) struct BottomPaneParams {
|
||||
pub(crate) enhanced_keys_supported: bool,
|
||||
pub(crate) placeholder_text: String,
|
||||
pub(crate) disable_paste_burst: bool,
|
||||
pub(crate) animations_enabled: bool,
|
||||
}
|
||||
|
||||
impl BottomPane {
|
||||
pub fn new(params: BottomPaneParams) -> Self {
|
||||
let enhanced_keys_supported = params.enhanced_keys_supported;
|
||||
let BottomPaneParams {
|
||||
app_event_tx,
|
||||
frame_requester,
|
||||
has_input_focus,
|
||||
enhanced_keys_supported,
|
||||
placeholder_text,
|
||||
disable_paste_burst,
|
||||
animations_enabled,
|
||||
} = params;
|
||||
Self {
|
||||
composer: ChatComposer::new(
|
||||
params.has_input_focus,
|
||||
params.app_event_tx.clone(),
|
||||
has_input_focus,
|
||||
app_event_tx.clone(),
|
||||
enhanced_keys_supported,
|
||||
params.placeholder_text,
|
||||
params.disable_paste_burst,
|
||||
placeholder_text,
|
||||
disable_paste_burst,
|
||||
),
|
||||
view_stack: Vec::new(),
|
||||
app_event_tx: params.app_event_tx,
|
||||
frame_requester: params.frame_requester,
|
||||
has_input_focus: params.has_input_focus,
|
||||
app_event_tx,
|
||||
frame_requester,
|
||||
has_input_focus,
|
||||
is_task_running: false,
|
||||
ctrl_c_quit_hint: false,
|
||||
status: None,
|
||||
queued_user_messages: QueuedUserMessages::new(),
|
||||
esc_backtrack_hint: false,
|
||||
animations_enabled,
|
||||
context_window_percent: None,
|
||||
}
|
||||
}
|
||||
@@ -294,6 +305,7 @@ impl BottomPane {
|
||||
self.status = Some(StatusIndicatorWidget::new(
|
||||
self.app_event_tx.clone(),
|
||||
self.frame_requester.clone(),
|
||||
self.animations_enabled,
|
||||
));
|
||||
}
|
||||
if let Some(status) = self.status.as_mut() {
|
||||
@@ -319,6 +331,7 @@ impl BottomPane {
|
||||
self.status = Some(StatusIndicatorWidget::new(
|
||||
self.app_event_tx.clone(),
|
||||
self.frame_requester.clone(),
|
||||
self.animations_enabled,
|
||||
));
|
||||
self.request_redraw();
|
||||
}
|
||||
@@ -554,6 +567,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
pane.push_approval_request(exec_request());
|
||||
assert_eq!(CancellationEvent::Handled, pane.on_ctrl_c());
|
||||
@@ -574,6 +588,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
// Create an approval modal (active view).
|
||||
@@ -605,6 +620,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
// Start a running task so the status indicator is active above the composer.
|
||||
@@ -670,6 +686,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
// Begin a task: show initial status.
|
||||
@@ -695,6 +712,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
// Activate spinner (status view replaces composer) with no live ring.
|
||||
@@ -724,6 +742,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
pane.set_task_running(true);
|
||||
@@ -750,6 +769,7 @@ mod tests {
|
||||
enhanced_keys_supported: false,
|
||||
placeholder_text: "Ask Codex to do anything".to_string(),
|
||||
disable_paste_burst: false,
|
||||
animations_enabled: true,
|
||||
});
|
||||
|
||||
pane.set_task_running(true);
|
||||
|
||||
Reference in New Issue
Block a user