This commit is contained in:
2026-09-14 00:55:25 +01:00
parent ec43d7b57a
commit e8c0e79bae
17 changed files with 183 additions and 46 deletions
+2
View File
@@ -16,6 +16,8 @@ tracing-subscriber = { workspace = true }
chrono = { workspace = true }
clap = {workspace = true}
toml = {workspace =true}
serde = { workspace = true }
serde_yaml = { workspace = true }
# Modules + services
modules = { path = "../modules" }
services = { path = "../services" }
+5
View File
@@ -16,6 +16,7 @@ mod args;
mod msg;
mod popup;
mod subscription;
mod theme;
mod update;
mod view;
@@ -58,6 +59,9 @@ fn main() -> Result<(), iced_layershell::Error> {
let (padding, spacing) = (disp.padding, disp.spacing);
let settings = disp.settings();
// Optional base16 theme; `None` lets iced follow the system colour scheme.
let theme = disp.theme.as_deref().map(theme::load);
daemon(
move || {
Bar::new(
@@ -76,6 +80,7 @@ fn main() -> Result<(), iced_layershell::Error> {
view::view,
)
.style(view::style)
.theme(move |_: &Bar, _: iced::window::Id| theme.clone())
.subscription(subscription::gather_subscriptions)
.settings(settings)
.run()
+60
View File
@@ -0,0 +1,60 @@
//! Base16 (`base00`..`base0F`) scheme loaded from YAML into an iced [`Theme`].
//!
//! The sixteen slots map onto iced's six-colour [`Palette`]: `base00` is the
//! background, `base05` the foreground, and the blue/green/yellow/red accents
//! become primary/success/warning/danger. The remaining slots are unused.
use std::path::Path;
use iced::theme::Palette;
use iced::{Color, Theme};
use serde::Deserialize;
/// The base16 slots the palette needs; other keys (author, base01..) are
/// ignored by serde.
#[derive(Deserialize)]
struct Base16 {
scheme: Option<String>,
base00: String,
base05: String,
base08: String,
#[serde(rename = "base0A")]
base0a: String,
#[serde(rename = "base0B")]
base0b: String,
#[serde(rename = "base0D")]
base0d: String,
}
impl Base16 {
fn into_theme(self) -> Theme {
Theme::custom(
self.scheme.unwrap_or_else(|| "base16".to_string()),
Palette {
background: hex(&self.base00),
text: hex(&self.base05),
primary: hex(&self.base0d),
success: hex(&self.base0b),
warning: hex(&self.base0a),
danger: hex(&self.base08),
},
)
}
}
/// `"RRGGBB"` (optionally `#`-prefixed) to a [`Color`].
fn hex(s: &str) -> Color {
let v = u32::from_str_radix(s.trim_start_matches('#'), 16)
.unwrap_or_else(|_| panic!("base16 colour {s:?} is not RRGGBB hex"));
Color::from_rgb8((v >> 16) as u8, (v >> 8) as u8, v as u8)
}
/// Loads a base16 YAML scheme; panics with the offending path on a read or
/// parse error, matching how the TOML config is loaded.
pub fn load(path: &Path) -> Theme {
let text = std::fs::read_to_string(path)
.unwrap_or_else(|e| panic!("cannot read theme {}: {e}", path.display()));
let scheme: Base16 = serde_yaml::from_str(&text)
.unwrap_or_else(|e| panic!("cannot parse base16 theme {}: {e}", path.display()));
scheme.into_theme()
}
+1 -1
View File
@@ -87,7 +87,7 @@ fn bar_view(bar: &Bar) -> Element<'_, Message> {
pub(crate) fn style(_bar: &Bar, theme: &Theme) -> iced::theme::Style {
use iced::theme::Style;
Style {
background_color: theme.palette().background,
background_color: iced::Color::TRANSPARENT,
text_color: theme.palette().text,
}
}