requery default colors on focus (#4673)

fixes an issue when terminals change their color scheme, e.g. dark/light
mode, the composer wouldn't update its background color.
This commit is contained in:
Jeremy Rose
2025-10-03 15:43:41 -07:00
committed by GitHub
parent 640192ac3d
commit 1b4a79f03c
2 changed files with 56 additions and 7 deletions

View File

@@ -2,6 +2,10 @@ pub fn terminal_palette() -> Option<[(u8, u8, u8); 256]> {
imp::terminal_palette() imp::terminal_palette()
} }
pub fn requery_default_colors() {
imp::requery_default_colors();
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct DefaultColors { pub struct DefaultColors {
#[allow(dead_code)] #[allow(dead_code)]
@@ -9,7 +13,7 @@ pub struct DefaultColors {
bg: (u8, u8, u8), bg: (u8, u8, u8),
} }
pub fn default_colors() -> Option<&'static DefaultColors> { pub fn default_colors() -> Option<DefaultColors> {
imp::default_colors() imp::default_colors()
} }
@@ -27,8 +31,44 @@ mod imp {
use super::DefaultColors; use super::DefaultColors;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::os::fd::RawFd; use std::os::fd::RawFd;
use std::sync::Mutex;
use std::sync::OnceLock; use std::sync::OnceLock;
struct Cache<T> {
attempted: bool,
value: Option<T>,
}
impl<T> Default for Cache<T> {
fn default() -> Self {
Self {
attempted: false,
value: None,
}
}
}
impl<T: Copy> Cache<T> {
fn get_or_init_with(&mut self, mut init: impl FnMut() -> Option<T>) -> Option<T> {
if !self.attempted {
self.value = init();
self.attempted = true;
}
self.value
}
fn refresh_with(&mut self, mut init: impl FnMut() -> Option<T>) -> Option<T> {
self.value = init();
self.attempted = true;
self.value
}
}
fn default_colors_cache() -> &'static Mutex<Cache<DefaultColors>> {
static CACHE: OnceLock<Mutex<Cache<DefaultColors>>> = OnceLock::new();
CACHE.get_or_init(|| Mutex::new(Cache::default()))
}
pub(super) fn terminal_palette() -> Option<[(u8, u8, u8); 256]> { pub(super) fn terminal_palette() -> Option<[(u8, u8, u8); 256]> {
static CACHE: OnceLock<Option<[(u8, u8, u8); 256]>> = OnceLock::new(); static CACHE: OnceLock<Option<[(u8, u8, u8); 256]>> = OnceLock::new();
*CACHE.get_or_init(|| match query_terminal_palette() { *CACHE.get_or_init(|| match query_terminal_palette() {
@@ -37,11 +77,16 @@ mod imp {
}) })
} }
pub(super) fn default_colors() -> Option<&'static DefaultColors> { pub(super) fn default_colors() -> Option<DefaultColors> {
static CACHE: OnceLock<Option<DefaultColors>> = OnceLock::new(); let cache = default_colors_cache();
CACHE let mut cache = cache.lock().ok()?;
.get_or_init(|| query_default_colors().unwrap_or_default()) cache.get_or_init_with(|| query_default_colors().unwrap_or_default())
.as_ref() }
pub(super) fn requery_default_colors() {
if let Ok(mut cache) = default_colors_cache().lock() {
cache.refresh_with(|| query_default_colors().unwrap_or_default());
}
} }
#[allow(dead_code)] #[allow(dead_code)]
@@ -392,7 +437,9 @@ mod imp {
None None
} }
pub(super) fn default_colors() -> Option<&'static DefaultColors> { pub(super) fn default_colors() -> Option<DefaultColors> {
None None
} }
pub(super) fn requery_default_colors() {}
} }

View File

@@ -362,6 +362,8 @@ impl Tui {
} }
Event::FocusGained => { Event::FocusGained => {
terminal_focused.store(true, Ordering::Relaxed); terminal_focused.store(true, Ordering::Relaxed);
crate::terminal_palette::requery_default_colors();
yield TuiEvent::Draw;
} }
Event::FocusLost => { Event::FocusLost => {
terminal_focused.store(false, Ordering::Relaxed); terminal_focused.store(false, Ordering::Relaxed);