use gpui::{App, Pixels, px}; mod builtins; mod geometry; mod model; mod notification; mod platform_kind; mod resolved; mod runtime; mod scrollbar_mode; pub use geometry::*; pub use model::*; pub use notification::*; pub use platform_kind::PlatformKind; pub use resolved::{ResolvedAccentRoles, ResolvedColors}; pub use runtime::Theme; pub use scrollbar_mode::*; pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0); pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0); pub const CLIENT_SIDE_DECORATION_BORDER: Pixels = px(1.0); pub(crate) const TITLEBAR_HEIGHT: Pixels = px(36.0); pub const TABBAR_HEIGHT: Pixels = px(36.0); pub const SIDEBAR_WIDTH: Pixels = px(240.); pub fn init(cx: &mut App) { for issue in ThemeRegistry::builtin().validate() { log::warn!("theme {}: {}", issue.variant_id, issue.message); } Theme::sync_system_appearance(None, cx); Theme::sync_scrollbar_appearance(cx); } /// Project the active theme onto the `gpui-base` global (focus ring, selection wash, scrollbars, backdrops). pub fn sync_base(cx: &mut App) { let Some(theme) = cx.try_global::() else { return; }; let appearance = if theme.appearance.is_dark() { gpui_base::ThemeAppearance::Dark } else { gpui_base::ThemeAppearance::Light }; let scrollbar_mode = match theme.scrollbar_mode { ScrollbarMode::Scrolling => gpui_base::ScrollbarMode::Scrolling, ScrollbarMode::Hover => gpui_base::ScrollbarMode::Hover, ScrollbarMode::Always => gpui_base::ScrollbarMode::Always, }; let colors = theme.colors; let accent = theme.accent; let font_family = theme.font_family.clone(); let base = gpui_base::Theme::global_mut(cx); base.appearance = appearance; base.scrollbar = base.scrollbar.clone().with_mode(scrollbar_mode); base.tokens.typography.sans = font_family; let tokens = &mut base.tokens.colors; tokens.background = colors.background; tokens.foreground = colors.text; tokens.surface = colors.shell; tokens.surface_foreground = colors.text; tokens.primary = accent.primary; tokens.primary_foreground = accent.on; tokens.secondary = colors.raised; tokens.secondary_foreground = colors.text; tokens.muted = colors.hover; tokens.muted_foreground = colors.text_muted; tokens.accent = accent.wash; tokens.accent_foreground = colors.text; tokens.destructive = colors.danger; tokens.destructive_foreground = accent.on_danger; tokens.border = colors.border; tokens.input = colors.input; tokens.ring = accent.primary; tokens.selection = accent.selection; } pub trait ActiveTheme { fn theme(&self) -> &Theme; } impl ActiveTheme for App { #[inline(always)] fn theme(&self) -> &Theme { Theme::global(self) } }