Make every shell color token theme-aware
Dark mode was persistent in `AppearanceSettings` but never reached any paint code: every call site in the shell read `colors::INK` etc. as a `pub const u32`, so toggling `ThemeMode::Dark` mutated state nothing sampled. Root-cause fix is to invert the contract — the design-system exports functions that resolve through a thread-local `Mode`, and the GPUI render impl sets that mode each frame. What lands: - `ely_design_system::colors::Mode` + thread-local + `set_mode` / `mode` accessors. Every ink shade, glass surface, stroke, divider, hairline, canvas, success / error chip now picks the warm-dark counterpart when the active mode is `Mode::Dark`. - `ElyShell::render` resolves `ThemeMode::System` against `Window::appearance()` and pushes the mode before traversing the tree, so widgets lower down read the right shade without owning a `Mode` parameter. - `render_wallpaper` + `panel_bg` now branch on `colors::mode()` so the gradient base, panel tint, and overlay highlights flip to warm-graphite when dark mode is active. - Mechanical conversion across 687 call sites in 55 files from `colors::FOO` constants to `colors::foo()` accessors. The `Theme` / `ELY_THEME` const surface (unused outside the design system) is removed; the function surface is the new contract.
This commit is contained in:
@@ -18,6 +18,19 @@ use super::{ElyShell, ShellState};
|
||||
|
||||
impl Render for ElyShell {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
// Resolve the active palette before anything else so every
|
||||
// `colors::ink()` etc. call lower in the tree reads the right
|
||||
// shade. `ThemeMode::System` defers to the OS preference via
|
||||
// GPUI's `Window::appearance`; explicit Light / Dark wins.
|
||||
let appearance = window.appearance();
|
||||
let theme_mode = match &self.state {
|
||||
ShellState::Ready(core) => {
|
||||
core.snapshot().map(|s| s.appearance.theme_mode()).unwrap_or_default()
|
||||
}
|
||||
ShellState::StartupError(_) => ely_domain::ThemeMode::default(),
|
||||
};
|
||||
colors::set_mode(resolve_color_mode(theme_mode, appearance));
|
||||
|
||||
match &self.state {
|
||||
ShellState::Ready(core) => match (core.snapshot(), core.active_tab().cloned()) {
|
||||
(Ok(snapshot), Ok(active_tab)) => {
|
||||
@@ -30,6 +43,24 @@ impl Render for ElyShell {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_color_mode(
|
||||
theme_mode: ely_domain::ThemeMode,
|
||||
window_appearance: gpui::WindowAppearance,
|
||||
) -> colors::Mode {
|
||||
match theme_mode {
|
||||
ely_domain::ThemeMode::Light => colors::Mode::Light,
|
||||
ely_domain::ThemeMode::Dark => colors::Mode::Dark,
|
||||
ely_domain::ThemeMode::System => match window_appearance {
|
||||
gpui::WindowAppearance::Dark | gpui::WindowAppearance::VibrantDark => {
|
||||
colors::Mode::Dark
|
||||
}
|
||||
gpui::WindowAppearance::Light | gpui::WindowAppearance::VibrantLight => {
|
||||
colors::Mode::Light
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl ElyShell {
|
||||
fn render_browser(
|
||||
&mut self,
|
||||
@@ -75,7 +106,7 @@ impl ElyShell {
|
||||
.on_mouse_up(MouseButton::Left, cx.listener(Self::on_window_mouse_up))
|
||||
.capture_key_down(cx.listener(Self::on_command_overlay_key_down))
|
||||
.font_family(SANS_FAMILY)
|
||||
.text_color(rgb(colors::INK))
|
||||
.text_color(rgb(colors::ink()))
|
||||
.child(render_wallpaper(snapshot.appearance.wallpaper()))
|
||||
.child(
|
||||
div()
|
||||
@@ -333,8 +364,8 @@ const COLLAPSE_THRESHOLD_PX: f32 = spacing::SHELL_INSET + DEFAULT_SIDEBAR_WIDTH_
|
||||
fn render_error(message: String) -> AnyElement {
|
||||
div()
|
||||
.size_full()
|
||||
.bg(rgb(colors::CANVAS))
|
||||
.text_color(rgb(colors::ERROR))
|
||||
.bg(rgb(colors::canvas()))
|
||||
.text_color(rgb(colors::error()))
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
|
||||
Reference in New Issue
Block a user