mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
fix(tui/theme): suppress OSC background probe when theme is explicit
This commit is contained in:
+36
-4
@@ -14,6 +14,7 @@ use codex_core::protocol::AskForApproval;
|
|||||||
use codex_core::protocol::SandboxPolicy;
|
use codex_core::protocol::SandboxPolicy;
|
||||||
use codex_core::config_types::ThemeColors;
|
use codex_core::config_types::ThemeColors;
|
||||||
use codex_core::config_types::ThemeName;
|
use codex_core::config_types::ThemeName;
|
||||||
|
use regex_lite::Regex;
|
||||||
use codex_login::AuthMode;
|
use codex_login::AuthMode;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_ollama::DEFAULT_OSS_MODEL;
|
use codex_ollama::DEFAULT_OSS_MODEL;
|
||||||
@@ -91,6 +92,21 @@ mod updates;
|
|||||||
|
|
||||||
pub use cli::Cli;
|
pub use cli::Cli;
|
||||||
|
|
||||||
|
fn theme_configured_in_config_file(codex_home: &std::path::Path) -> bool {
|
||||||
|
let config_path = codex_home.join("config.toml");
|
||||||
|
let Ok(contents) = std::fs::read_to_string(&config_path) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let table_pattern = Regex::new(r"(?m)^\s*\[tui\.theme\]").expect("valid regex");
|
||||||
|
if table_pattern.is_match(&contents) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let inline_pattern = Regex::new(r"(?m)^\s*tui\.theme\s*=").expect("valid regex");
|
||||||
|
inline_pattern.is_match(&contents)
|
||||||
|
}
|
||||||
|
|
||||||
// (tests access modules directly within the crate)
|
// (tests access modules directly within the crate)
|
||||||
|
|
||||||
pub async fn run_main(
|
pub async fn run_main(
|
||||||
@@ -166,6 +182,9 @@ pub async fn run_main(
|
|||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let theme_override_in_cli = cli_kv_overrides
|
||||||
|
.iter()
|
||||||
|
.any(|(path, _)| path.starts_with("tui.theme"));
|
||||||
|
|
||||||
let mut config = {
|
let mut config = {
|
||||||
// Load configuration and support CLI overrides.
|
// Load configuration and support CLI overrides.
|
||||||
@@ -184,7 +203,7 @@ pub async fn run_main(
|
|||||||
|
|
||||||
// we load config.toml here to determine project state.
|
// we load config.toml here to determine project state.
|
||||||
#[allow(clippy::print_stderr)]
|
#[allow(clippy::print_stderr)]
|
||||||
let config_toml = {
|
let (config_toml, theme_set_in_config_file) = {
|
||||||
let codex_home = match find_codex_home() {
|
let codex_home = match find_codex_home() {
|
||||||
Ok(codex_home) => codex_home,
|
Ok(codex_home) => codex_home,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -193,8 +212,10 @@ pub async fn run_main(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let theme_set_in_config_file = theme_configured_in_config_file(&codex_home);
|
||||||
|
|
||||||
match load_config_as_toml_with_cli_overrides(&codex_home, cli_kv_overrides) {
|
match load_config_as_toml_with_cli_overrides(&codex_home, cli_kv_overrides) {
|
||||||
Ok(config_toml) => config_toml,
|
Ok(config_toml) => (config_toml, theme_set_in_config_file),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Error loading config.toml: {err}");
|
eprintln!("Error loading config.toml: {err}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
@@ -202,6 +223,8 @@ pub async fn run_main(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let theme_configured_explicitly = theme_set_in_config_file || theme_override_in_cli;
|
||||||
|
|
||||||
let should_show_trust_screen = determine_repo_trust_state(
|
let should_show_trust_screen = determine_repo_trust_state(
|
||||||
&mut config,
|
&mut config,
|
||||||
&config_toml,
|
&config_toml,
|
||||||
@@ -269,6 +292,7 @@ pub async fn run_main(
|
|||||||
should_show_trust_screen,
|
should_show_trust_screen,
|
||||||
startup_footer_notice,
|
startup_footer_notice,
|
||||||
latest_upgrade_version,
|
latest_upgrade_version,
|
||||||
|
theme_configured_explicitly,
|
||||||
)
|
)
|
||||||
.map_err(|err| std::io::Error::other(err.to_string()))
|
.map_err(|err| std::io::Error::other(err.to_string()))
|
||||||
}
|
}
|
||||||
@@ -279,6 +303,7 @@ fn run_ratatui_app(
|
|||||||
should_show_trust_screen: bool,
|
should_show_trust_screen: bool,
|
||||||
startup_footer_notice: Option<String>,
|
startup_footer_notice: Option<String>,
|
||||||
latest_upgrade_version: Option<String>,
|
latest_upgrade_version: Option<String>,
|
||||||
|
theme_configured_explicitly: bool,
|
||||||
) -> color_eyre::Result<codex_core::protocol::TokenUsage> {
|
) -> color_eyre::Result<codex_core::protocol::TokenUsage> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
|
||||||
@@ -291,7 +316,7 @@ fn run_ratatui_app(
|
|||||||
tracing::error!("panic: {info}");
|
tracing::error!("panic: {info}");
|
||||||
prev_hook(info);
|
prev_hook(info);
|
||||||
}));
|
}));
|
||||||
maybe_apply_terminal_theme_detection(&mut config);
|
maybe_apply_terminal_theme_detection(&mut config, theme_configured_explicitly);
|
||||||
|
|
||||||
let (mut terminal, terminal_info) = tui::init(&config)?;
|
let (mut terminal, terminal_info) = tui::init(&config)?;
|
||||||
if config.tui.alternate_screen {
|
if config.tui.alternate_screen {
|
||||||
@@ -406,7 +431,14 @@ fn cleanup_session_worktrees_and_print() {
|
|||||||
let _ = std::fs::remove_file(&file);
|
let _ = std::fs::remove_file(&file);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_apply_terminal_theme_detection(config: &mut Config) {
|
fn maybe_apply_terminal_theme_detection(config: &mut Config, theme_configured_explicitly: bool) {
|
||||||
|
if theme_configured_explicitly {
|
||||||
|
tracing::info!(
|
||||||
|
"Terminal theme autodetect skipped due to explicit theme configuration"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let theme = &mut config.tui.theme;
|
let theme = &mut config.tui.theme;
|
||||||
|
|
||||||
let autodetect_disabled = std::env::var("CODE_DISABLE_THEME_AUTODETECT")
|
let autodetect_disabled = std::env::var("CODE_DISABLE_THEME_AUTODETECT")
|
||||||
|
|||||||
@@ -221,10 +221,45 @@ fn query_osc_background_color() -> Option<(u8, u8, u8)> {
|
|||||||
tty_w.flush().ok()?;
|
tty_w.flush().ok()?;
|
||||||
|
|
||||||
let reply = read_osc_reply(&mut tty_r, Duration::from_millis(150))?;
|
let reply = read_osc_reply(&mut tty_r, Duration::from_millis(150))?;
|
||||||
|
let _ = tty_w.write_all(b"\r\x1b[K");
|
||||||
|
let _ = tty_w.flush();
|
||||||
let reply_str = String::from_utf8_lossy(&reply);
|
let reply_str = String::from_utf8_lossy(&reply);
|
||||||
parse_osc_rgb(&reply_str)
|
parse_osc_rgb(&reply_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn osc_background_query_supported() -> bool {
|
||||||
|
if env::var("TMUX").is_ok() || env::var("STY").is_ok() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let term = env::var("TERM").unwrap_or_default();
|
||||||
|
if term.is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let term_lower = term.to_ascii_lowercase();
|
||||||
|
|
||||||
|
const UNSUPPORTED_PREFIXES: [&str; 2] = ["screen", "tmux"];
|
||||||
|
if UNSUPPORTED_PREFIXES
|
||||||
|
.iter()
|
||||||
|
.any(|prefix| term_lower.starts_with(prefix))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UNSUPPORTED_TERMS: [&str; 5] = [
|
||||||
|
"dumb",
|
||||||
|
"linux",
|
||||||
|
"vt100",
|
||||||
|
"xterm-color",
|
||||||
|
"ansi",
|
||||||
|
];
|
||||||
|
if UNSUPPORTED_TERMS.contains(&term_lower.as_str()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn xterm_color_to_rgb(idx: u32) -> Option<(u8, u8, u8)> {
|
fn xterm_color_to_rgb(idx: u32) -> Option<(u8, u8, u8)> {
|
||||||
if idx <= 15 {
|
if idx <= 15 {
|
||||||
return Some(ANSI_16_TO_RGB[idx as usize]);
|
return Some(ANSI_16_TO_RGB[idx as usize]);
|
||||||
@@ -286,8 +321,10 @@ pub fn detect_dark_terminal_background() -> Option<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rgb) = query_osc_background_color() {
|
if osc_background_query_supported() {
|
||||||
return Some(detect_dark_from_rgb(rgb));
|
if let Some(rgb) = query_osc_background_color() {
|
||||||
|
return Some(detect_dark_from_rgb(rgb));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rgb) = parse_colorfgbg_env() {
|
if let Some(rgb) = parse_colorfgbg_env() {
|
||||||
|
|||||||
Reference in New Issue
Block a user