From 45894be4ff5162e1c2645398485fe8bd79087de6 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sat, 14 Sep 2024 15:31:17 -0700 Subject: [PATCH] feat(themes): add + integrate komorebi-themes lib This commit abstracts the theme-related code from komorebi-bar into a separate library which is now also consumed by komorebi. The static configuration file for komorebi has been updated to allow users to specify themes and provide palette overrides for various border styles and stackbar configuration options. In the event that both a theme and border-specific and/or stackbar-specific colours have been specified, the theme will take priority to make it as easy as possible for users who have already spent time tweaking their colours to try out themes and quickly revert back if they prefer their existing colours. This change makes it easier for users to have unified themes between komorebi and the komorebi status bar. --- Cargo.lock | 15 +- Cargo.toml | 2 +- komorebi-bar/Cargo.toml | 3 +- komorebi-bar/src/bar.rs | 151 +------ komorebi-bar/src/config.rs | 73 +--- komorebi-themes/Cargo.toml | 11 + komorebi-themes/src/lib.rs | 158 ++++++++ komorebi/Cargo.toml | 2 + komorebi/src/static_config.rs | 225 ++++++++++- schema.json | 723 +++++++++++++++++++++++++++++++++- 10 files changed, 1146 insertions(+), 217 deletions(-) create mode 100644 komorebi-themes/Cargo.toml create mode 100644 komorebi-themes/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 64a73abd..e34a1f01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2654,6 +2654,7 @@ dependencies = [ "getset", "hex_color", "hotwatch", + "komorebi-themes", "lazy_static", "miow", "nanoid", @@ -2687,8 +2688,6 @@ dependencies = [ name = "komorebi-bar" version = "0.1.0" dependencies = [ - "base16-egui-themes", - "catppuccin-egui", "chrono", "clap", "color-eyre", @@ -2700,6 +2699,7 @@ dependencies = [ "hotwatch", "image", "komorebi-client", + "komorebi-themes", "netdev", "num", "num-derive", @@ -2738,6 +2738,17 @@ dependencies = [ "windows 0.54.0", ] +[[package]] +name = "komorebi-themes" +version = "0.1.0" +dependencies = [ + "base16-egui-themes", + "catppuccin-egui", + "egui", + "schemars", + "serde", +] + [[package]] name = "komorebic" version = "0.1.29" diff --git a/Cargo.toml b/Cargo.toml index 0fbb1008..25c75454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ "komorebic", "komorebic-no-console", "komorebi-bar" -] +, "komorebi-themes"] [workspace.dependencies] color-eyre = "0.6" diff --git a/komorebi-bar/Cargo.toml b/komorebi-bar/Cargo.toml index 2e8ae280..908f2bd5 100644 --- a/komorebi-bar/Cargo.toml +++ b/komorebi-bar/Cargo.toml @@ -7,9 +7,8 @@ edition = "2021" [dependencies] komorebi-client = { path = "../komorebi-client" } +komorebi-themes = { path = "../komorebi-themes" } -base16-egui-themes = { git = "https://github.com/LGUG2Z/base16-egui-themes", rev = "a2c48f45782c5604bf5482d3873021a9fe45ea1a" } -catppuccin-egui = { version = "5.1", default-features = false, features = ["egui28"] } chrono = "0.4" clap = { version = "4", features = ["derive", "wrap_help"] } color-eyre = "0.6" diff --git a/komorebi-bar/src/bar.rs b/komorebi-bar/src/bar.rs index 4afb0219..7980331b 100644 --- a/komorebi-bar/src/bar.rs +++ b/komorebi-bar/src/bar.rs @@ -1,8 +1,5 @@ -use crate::config::Base16Value; -use crate::config::Catppuccin; -use crate::config::CatppuccinValue; use crate::config::KomobarConfig; -use crate::config::Theme; +use crate::config::KomobarTheme; use crate::komorebi::Komorebi; use crate::komorebi::KomorebiNotificationState; use crate::widget::BarWidget; @@ -21,6 +18,8 @@ use eframe::egui::Margin; use eframe::egui::Style; use font_loader::system_fonts; use font_loader::system_fonts::FontPropertyBuilder; +use komorebi_themes::catppuccin_egui; +use komorebi_themes::Catppuccin; use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; @@ -53,42 +52,14 @@ impl Komobar { self.bg_color = Style::default().visuals.panel_fill; } Some(theme) => match theme { - Theme::Catppuccin { + KomobarTheme::Catppuccin { name: catppuccin, accent: catppuccin_value, } => match catppuccin { Catppuccin::Frappe => { catppuccin_egui::set_theme(ctx, catppuccin_egui::FRAPPE); let catppuccin_value = catppuccin_value.unwrap_or_default(); - - let accent = match catppuccin_value { - CatppuccinValue::Rosewater => catppuccin_egui::FRAPPE.rosewater, - CatppuccinValue::Flamingo => catppuccin_egui::FRAPPE.flamingo, - CatppuccinValue::Pink => catppuccin_egui::FRAPPE.pink, - CatppuccinValue::Mauve => catppuccin_egui::FRAPPE.mauve, - CatppuccinValue::Red => catppuccin_egui::FRAPPE.red, - CatppuccinValue::Maroon => catppuccin_egui::FRAPPE.maroon, - CatppuccinValue::Peach => catppuccin_egui::FRAPPE.peach, - CatppuccinValue::Yellow => catppuccin_egui::FRAPPE.yellow, - CatppuccinValue::Green => catppuccin_egui::FRAPPE.green, - CatppuccinValue::Teal => catppuccin_egui::FRAPPE.teal, - CatppuccinValue::Sky => catppuccin_egui::FRAPPE.sky, - CatppuccinValue::Sapphire => catppuccin_egui::FRAPPE.sapphire, - CatppuccinValue::Blue => catppuccin_egui::FRAPPE.blue, - CatppuccinValue::Lavender => catppuccin_egui::FRAPPE.lavender, - CatppuccinValue::Text => catppuccin_egui::FRAPPE.text, - CatppuccinValue::Subtext1 => catppuccin_egui::FRAPPE.subtext1, - CatppuccinValue::Subtext0 => catppuccin_egui::FRAPPE.subtext0, - CatppuccinValue::Overlay2 => catppuccin_egui::FRAPPE.overlay2, - CatppuccinValue::Overlay1 => catppuccin_egui::FRAPPE.overlay1, - CatppuccinValue::Overlay0 => catppuccin_egui::FRAPPE.overlay0, - CatppuccinValue::Surface2 => catppuccin_egui::FRAPPE.surface2, - CatppuccinValue::Surface1 => catppuccin_egui::FRAPPE.surface1, - CatppuccinValue::Surface0 => catppuccin_egui::FRAPPE.surface0, - CatppuccinValue::Base => catppuccin_egui::FRAPPE.base, - CatppuccinValue::Mantle => catppuccin_egui::FRAPPE.mantle, - CatppuccinValue::Crust => catppuccin_egui::FRAPPE.crust, - }; + let accent = catppuccin_value.color32(catppuccin.as_theme()); ctx.style_mut(|style| { style.visuals.selection.stroke.color = accent; @@ -102,35 +73,7 @@ impl Komobar { Catppuccin::Latte => { catppuccin_egui::set_theme(ctx, catppuccin_egui::LATTE); let catppuccin_value = catppuccin_value.unwrap_or_default(); - - let accent = match catppuccin_value { - CatppuccinValue::Rosewater => catppuccin_egui::LATTE.rosewater, - CatppuccinValue::Flamingo => catppuccin_egui::LATTE.flamingo, - CatppuccinValue::Pink => catppuccin_egui::LATTE.pink, - CatppuccinValue::Mauve => catppuccin_egui::LATTE.mauve, - CatppuccinValue::Red => catppuccin_egui::LATTE.red, - CatppuccinValue::Maroon => catppuccin_egui::LATTE.maroon, - CatppuccinValue::Peach => catppuccin_egui::LATTE.peach, - CatppuccinValue::Yellow => catppuccin_egui::LATTE.yellow, - CatppuccinValue::Green => catppuccin_egui::LATTE.green, - CatppuccinValue::Teal => catppuccin_egui::LATTE.teal, - CatppuccinValue::Sky => catppuccin_egui::LATTE.sky, - CatppuccinValue::Sapphire => catppuccin_egui::LATTE.sapphire, - CatppuccinValue::Blue => catppuccin_egui::LATTE.blue, - CatppuccinValue::Lavender => catppuccin_egui::LATTE.lavender, - CatppuccinValue::Text => catppuccin_egui::LATTE.text, - CatppuccinValue::Subtext1 => catppuccin_egui::LATTE.subtext1, - CatppuccinValue::Subtext0 => catppuccin_egui::LATTE.subtext0, - CatppuccinValue::Overlay2 => catppuccin_egui::LATTE.overlay2, - CatppuccinValue::Overlay1 => catppuccin_egui::LATTE.overlay1, - CatppuccinValue::Overlay0 => catppuccin_egui::LATTE.overlay0, - CatppuccinValue::Surface2 => catppuccin_egui::LATTE.surface2, - CatppuccinValue::Surface1 => catppuccin_egui::LATTE.surface1, - CatppuccinValue::Surface0 => catppuccin_egui::LATTE.surface0, - CatppuccinValue::Base => catppuccin_egui::LATTE.base, - CatppuccinValue::Mantle => catppuccin_egui::LATTE.mantle, - CatppuccinValue::Crust => catppuccin_egui::LATTE.crust, - }; + let accent = catppuccin_value.color32(catppuccin.as_theme()); ctx.style_mut(|style| { style.visuals.selection.stroke.color = accent; @@ -144,35 +87,7 @@ impl Komobar { Catppuccin::Macchiato => { catppuccin_egui::set_theme(ctx, catppuccin_egui::MACCHIATO); let catppuccin_value = catppuccin_value.unwrap_or_default(); - - let accent = match catppuccin_value { - CatppuccinValue::Rosewater => catppuccin_egui::MACCHIATO.rosewater, - CatppuccinValue::Flamingo => catppuccin_egui::MACCHIATO.flamingo, - CatppuccinValue::Pink => catppuccin_egui::MACCHIATO.pink, - CatppuccinValue::Mauve => catppuccin_egui::MACCHIATO.mauve, - CatppuccinValue::Red => catppuccin_egui::MACCHIATO.red, - CatppuccinValue::Maroon => catppuccin_egui::MACCHIATO.maroon, - CatppuccinValue::Peach => catppuccin_egui::MACCHIATO.peach, - CatppuccinValue::Yellow => catppuccin_egui::MACCHIATO.yellow, - CatppuccinValue::Green => catppuccin_egui::MACCHIATO.green, - CatppuccinValue::Teal => catppuccin_egui::MACCHIATO.teal, - CatppuccinValue::Sky => catppuccin_egui::MACCHIATO.sky, - CatppuccinValue::Sapphire => catppuccin_egui::MACCHIATO.sapphire, - CatppuccinValue::Blue => catppuccin_egui::MACCHIATO.blue, - CatppuccinValue::Lavender => catppuccin_egui::MACCHIATO.lavender, - CatppuccinValue::Text => catppuccin_egui::MACCHIATO.text, - CatppuccinValue::Subtext1 => catppuccin_egui::MACCHIATO.subtext1, - CatppuccinValue::Subtext0 => catppuccin_egui::MACCHIATO.subtext0, - CatppuccinValue::Overlay2 => catppuccin_egui::MACCHIATO.overlay2, - CatppuccinValue::Overlay1 => catppuccin_egui::MACCHIATO.overlay1, - CatppuccinValue::Overlay0 => catppuccin_egui::MACCHIATO.overlay0, - CatppuccinValue::Surface2 => catppuccin_egui::MACCHIATO.surface2, - CatppuccinValue::Surface1 => catppuccin_egui::MACCHIATO.surface1, - CatppuccinValue::Surface0 => catppuccin_egui::MACCHIATO.surface0, - CatppuccinValue::Base => catppuccin_egui::MACCHIATO.base, - CatppuccinValue::Mantle => catppuccin_egui::MACCHIATO.mantle, - CatppuccinValue::Crust => catppuccin_egui::MACCHIATO.crust, - }; + let accent = catppuccin_value.color32(catppuccin.as_theme()); ctx.style_mut(|style| { style.visuals.selection.stroke.color = accent; @@ -186,35 +101,7 @@ impl Komobar { Catppuccin::Mocha => { catppuccin_egui::set_theme(ctx, catppuccin_egui::MOCHA); let catppuccin_value = catppuccin_value.unwrap_or_default(); - - let accent = match catppuccin_value { - CatppuccinValue::Rosewater => catppuccin_egui::MOCHA.rosewater, - CatppuccinValue::Flamingo => catppuccin_egui::MOCHA.flamingo, - CatppuccinValue::Pink => catppuccin_egui::MOCHA.pink, - CatppuccinValue::Mauve => catppuccin_egui::MOCHA.mauve, - CatppuccinValue::Red => catppuccin_egui::MOCHA.red, - CatppuccinValue::Maroon => catppuccin_egui::MOCHA.maroon, - CatppuccinValue::Peach => catppuccin_egui::MOCHA.peach, - CatppuccinValue::Yellow => catppuccin_egui::MOCHA.yellow, - CatppuccinValue::Green => catppuccin_egui::MOCHA.green, - CatppuccinValue::Teal => catppuccin_egui::MOCHA.teal, - CatppuccinValue::Sky => catppuccin_egui::MOCHA.sky, - CatppuccinValue::Sapphire => catppuccin_egui::MOCHA.sapphire, - CatppuccinValue::Blue => catppuccin_egui::MOCHA.blue, - CatppuccinValue::Lavender => catppuccin_egui::MOCHA.lavender, - CatppuccinValue::Text => catppuccin_egui::MOCHA.text, - CatppuccinValue::Subtext1 => catppuccin_egui::MOCHA.subtext1, - CatppuccinValue::Subtext0 => catppuccin_egui::MOCHA.subtext0, - CatppuccinValue::Overlay2 => catppuccin_egui::MOCHA.overlay2, - CatppuccinValue::Overlay1 => catppuccin_egui::MOCHA.overlay1, - CatppuccinValue::Overlay0 => catppuccin_egui::MOCHA.overlay0, - CatppuccinValue::Surface2 => catppuccin_egui::MOCHA.surface2, - CatppuccinValue::Surface1 => catppuccin_egui::MOCHA.surface1, - CatppuccinValue::Surface0 => catppuccin_egui::MOCHA.surface0, - CatppuccinValue::Base => catppuccin_egui::MOCHA.base, - CatppuccinValue::Mantle => catppuccin_egui::MOCHA.mantle, - CatppuccinValue::Crust => catppuccin_egui::MOCHA.crust, - }; + let accent = catppuccin_value.color32(catppuccin.as_theme()); ctx.style_mut(|style| { style.visuals.selection.stroke.color = accent; @@ -226,31 +113,13 @@ impl Komobar { self.bg_color = catppuccin_egui::MOCHA.base; } }, - Theme::Base16 { + KomobarTheme::Base16 { name: base16, accent: base16_value, } => { ctx.set_style(base16.style()); let base16_value = base16_value.unwrap_or_default(); - - let accent = match base16_value { - Base16Value::Base00 => base16.base00(), - Base16Value::Base01 => base16.base01(), - Base16Value::Base02 => base16.base02(), - Base16Value::Base03 => base16.base03(), - Base16Value::Base04 => base16.base04(), - Base16Value::Base05 => base16.base05(), - Base16Value::Base06 => base16.base06(), - Base16Value::Base07 => base16.base07(), - Base16Value::Base08 => base16.base08(), - Base16Value::Base09 => base16.base09(), - Base16Value::Base0A => base16.base0a(), - Base16Value::Base0B => base16.base0b(), - Base16Value::Base0C => base16.base0c(), - Base16Value::Base0D => base16.base0d(), - Base16Value::Base0E => base16.base0e(), - Base16Value::Base0F => base16.base0f(), - }; + let accent = base16_value.color32(base16); ctx.style_mut(|style| { style.visuals.selection.stroke.color = accent; diff --git a/komorebi-bar/src/config.rs b/komorebi-bar/src/config.rs index bc55b57f..eeeb32da 100644 --- a/komorebi-bar/src/config.rs +++ b/komorebi-bar/src/config.rs @@ -1,5 +1,4 @@ use crate::widget::WidgetConfig; -use base16_egui_themes::Base16; use eframe::egui::Pos2; use eframe::egui::TextBuffer; use eframe::egui::Vec2; @@ -20,7 +19,7 @@ pub struct KomobarConfig { /// Font family pub font_family: Option, /// Theme - pub theme: Option, + pub theme: Option, /// Left side widgets (ordered left-to-right) pub left_widgets: Vec, /// Right side widgets (ordered left-to-right) @@ -96,75 +95,15 @@ impl From for Pos2 { #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type")] -pub enum Theme { +pub enum KomobarTheme { /// A theme from catppuccin-egui Catppuccin { - name: Catppuccin, - accent: Option, + name: komorebi_themes::Catppuccin, + accent: Option, }, /// A theme from base16-egui-themes Base16 { - name: Base16, - accent: Option, + name: komorebi_themes::Base16, + accent: Option, }, } - -#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] -pub enum Base16Value { - Base00, - Base01, - Base02, - Base03, - Base04, - Base05, - #[default] - Base06, - Base07, - Base08, - Base09, - Base0A, - Base0B, - Base0C, - Base0D, - Base0E, - Base0F, -} - -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] -pub enum Catppuccin { - Frappe, - Latte, - Macchiato, - Mocha, -} - -#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] -pub enum CatppuccinValue { - Rosewater, - Flamingo, - Pink, - Mauve, - Red, - Maroon, - Peach, - Yellow, - Green, - Teal, - Sky, - Sapphire, - Blue, - Lavender, - #[default] - Text, - Subtext1, - Subtext0, - Overlay2, - Overlay1, - Overlay0, - Surface2, - Surface1, - Surface0, - Base, - Mantle, - Crust, -} diff --git a/komorebi-themes/Cargo.toml b/komorebi-themes/Cargo.toml new file mode 100644 index 00000000..44ba1e7a --- /dev/null +++ b/komorebi-themes/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "komorebi-themes" +version = "0.1.0" +edition = "2021" + +[dependencies] +base16-egui-themes = { git = "https://github.com/LGUG2Z/base16-egui-themes", rev = "a2c48f45782c5604bf5482d3873021a9fe45ea1a" } +catppuccin-egui = { version = "5.1", default-features = false, features = ["egui28"] } +egui = "0.28" +serde = { workspace = true } +schemars = { workspace = true } diff --git a/komorebi-themes/src/lib.rs b/komorebi-themes/src/lib.rs new file mode 100644 index 00000000..c042b5ab --- /dev/null +++ b/komorebi-themes/src/lib.rs @@ -0,0 +1,158 @@ +#![warn(clippy::all)] +#![allow(clippy::missing_errors_doc)] + +pub use base16_egui_themes::Base16; +use schemars::JsonSchema; +use serde::Deserialize; +use serde::Serialize; + +pub use catppuccin_egui; +use egui::Color32; + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[serde(tag = "type")] +pub enum Theme { + /// A theme from catppuccin-egui + Catppuccin { + name: Catppuccin, + accent: Option, + }, + /// A theme from base16-egui-themes + Base16 { + name: Base16, + accent: Option, + }, +} + +#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] +pub enum Base16Value { + Base00, + Base01, + Base02, + Base03, + Base04, + Base05, + #[default] + Base06, + Base07, + Base08, + Base09, + Base0A, + Base0B, + Base0C, + Base0D, + Base0E, + Base0F, +} + +impl Base16Value { + pub fn color32(&self, theme: Base16) -> Color32 { + match self { + Base16Value::Base00 => theme.base00(), + Base16Value::Base01 => theme.base01(), + Base16Value::Base02 => theme.base02(), + Base16Value::Base03 => theme.base03(), + Base16Value::Base04 => theme.base04(), + Base16Value::Base05 => theme.base05(), + Base16Value::Base06 => theme.base06(), + Base16Value::Base07 => theme.base07(), + Base16Value::Base08 => theme.base08(), + Base16Value::Base09 => theme.base09(), + Base16Value::Base0A => theme.base0a(), + Base16Value::Base0B => theme.base0b(), + Base16Value::Base0C => theme.base0c(), + Base16Value::Base0D => theme.base0d(), + Base16Value::Base0E => theme.base0e(), + Base16Value::Base0F => theme.base0f(), + } + } +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub enum Catppuccin { + Frappe, + Latte, + Macchiato, + Mocha, +} + +impl Catppuccin { + pub fn as_theme(self) -> catppuccin_egui::Theme { + self.into() + } +} + +impl From for catppuccin_egui::Theme { + fn from(val: Catppuccin) -> Self { + match val { + Catppuccin::Frappe => catppuccin_egui::FRAPPE, + Catppuccin::Latte => catppuccin_egui::LATTE, + Catppuccin::Macchiato => catppuccin_egui::MACCHIATO, + Catppuccin::Mocha => catppuccin_egui::MOCHA, + } + } +} + +#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] +pub enum CatppuccinValue { + Rosewater, + Flamingo, + Pink, + Mauve, + Red, + Maroon, + Peach, + Yellow, + Green, + Teal, + Sky, + Sapphire, + Blue, + Lavender, + #[default] + Text, + Subtext1, + Subtext0, + Overlay2, + Overlay1, + Overlay0, + Surface2, + Surface1, + Surface0, + Base, + Mantle, + Crust, +} + +impl CatppuccinValue { + pub fn color32(&self, theme: catppuccin_egui::Theme) -> Color32 { + match self { + CatppuccinValue::Rosewater => theme.rosewater, + CatppuccinValue::Flamingo => theme.flamingo, + CatppuccinValue::Pink => theme.pink, + CatppuccinValue::Mauve => theme.mauve, + CatppuccinValue::Red => theme.red, + CatppuccinValue::Maroon => theme.maroon, + CatppuccinValue::Peach => theme.peach, + CatppuccinValue::Yellow => theme.yellow, + CatppuccinValue::Green => theme.green, + CatppuccinValue::Teal => theme.teal, + CatppuccinValue::Sky => theme.sky, + CatppuccinValue::Sapphire => theme.sapphire, + CatppuccinValue::Blue => theme.blue, + CatppuccinValue::Lavender => theme.lavender, + CatppuccinValue::Text => theme.text, + CatppuccinValue::Subtext1 => theme.subtext1, + CatppuccinValue::Subtext0 => theme.subtext0, + CatppuccinValue::Overlay2 => theme.overlay2, + CatppuccinValue::Overlay1 => theme.overlay1, + CatppuccinValue::Overlay0 => theme.overlay0, + CatppuccinValue::Surface2 => theme.surface2, + CatppuccinValue::Surface1 => theme.surface1, + CatppuccinValue::Surface0 => theme.surface0, + CatppuccinValue::Base => theme.base, + CatppuccinValue::Mantle => theme.mantle, + CatppuccinValue::Crust => theme.crust, + } + } +} diff --git a/komorebi/Cargo.toml b/komorebi/Cargo.toml index e23fcaf1..3f97edac 100644 --- a/komorebi/Cargo.toml +++ b/komorebi/Cargo.toml @@ -11,6 +11,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +komorebi-themes = { path = "../komorebi-themes" } + bitflags = { version = "2", features = ["serde"] } clap = { version = "4", features = ["derive"] } color-eyre = { workspace = true } diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 690d66f9..8c0138bc 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -27,6 +27,7 @@ use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; use crate::workspace::Workspace; use crate::CrossBoundaryBehaviour; +use crate::Rgb; use crate::ANIMATION_DURATION; use crate::ANIMATION_ENABLED; use crate::ANIMATION_FPS; @@ -358,6 +359,9 @@ pub struct StaticConfig { /// Animations configuration options #[serde(skip_serializing_if = "Option::is_none")] pub animation: Option, + /// Theme configuration options + #[serde(skip_serializing_if = "Option::is_none")] + pub theme: Option, } #[derive(Debug, Serialize, Deserialize, JsonSchema)] @@ -371,6 +375,48 @@ pub struct AnimationsConfig { /// Set the animation FPS (default: 60) fps: Option, } +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[serde(tag = "type")] +pub enum KomorebiTheme { + /// A theme from catppuccin-egui + Catppuccin { + /// Name of the Catppuccin theme + name: komorebi_themes::Catppuccin, + /// Border colour when the container contains a single window (default: Blue) + single_border: Option, + /// Border colour when the container contains multiple windows (default: Green) + stack_border: Option, + /// Border colour when the container is in monocle mode (default: Pink) + monocle_border: Option, + /// Border colour when the container is unfocused (default: Base) + unfocused_border: Option, + /// Stackbar focused tab text colour (default: Green) + stackbar_focused_text: Option, + /// Stackbar unfocused tab text colour (default: Text) + stackbar_unfocused_text: Option, + /// Stackbar tab background colour (default: Base) + stackbar_background: Option, + }, + /// A theme from base16-egui-themes + Base16 { + /// Name of the Base16 theme + name: komorebi_themes::Base16, + /// Border colour when the container contains a single window (default: Base0D) + single_border: Option, + /// Border colour when the container contains multiple windows (default: Base0B) + stack_border: Option, + /// Border colour when the container is in monocle mode (default: Base0F) + monocle_border: Option, + /// Border colour when the container is unfocused (default: Base01) + unfocused_border: Option, + /// Stackbar focused tab text colour (default: Base0B) + stackbar_focused_text: Option, + /// Stackbar unfocused tab text colour (default: Base05) + stackbar_unfocused_text: Option, + /// Stackbar tab background colour (default: Base01) + stackbar_background: Option, + }, +} impl StaticConfig { pub fn aliases(raw: &str) { @@ -446,7 +492,7 @@ pub struct TabsConfig { pub struct StackbarConfig { /// Stackbar height pub height: Option, - /// Stackbar height + /// Stackbar label pub label: Option, /// Stackbar mode pub mode: Option, @@ -610,6 +656,7 @@ impl From<&WindowManager> for StaticConfig { display_index_preferences: Option::from(DISPLAY_INDEX_PREFERENCES.lock().clone()), stackbar: None, animation: None, + theme: None, } } } @@ -782,6 +829,178 @@ impl StaticConfig { } } + if let Some(theme) = &self.theme { + let ( + single_border, + stack_border, + monocle_border, + unfocused_border, + stackbar_focused_text, + stackbar_unfocused_text, + stackbar_background, + ) = match theme { + KomorebiTheme::Catppuccin { + name, + single_border, + stack_border, + monocle_border, + unfocused_border, + stackbar_focused_text, + stackbar_unfocused_text, + stackbar_background, + } => { + let single_border = single_border + .unwrap_or(komorebi_themes::CatppuccinValue::Blue) + .color32(name.as_theme()); + + let stack_border = stack_border + .unwrap_or(komorebi_themes::CatppuccinValue::Green) + .color32(name.as_theme()); + + let monocle_border = monocle_border + .unwrap_or(komorebi_themes::CatppuccinValue::Pink) + .color32(name.as_theme()); + + let unfocused_border = unfocused_border + .unwrap_or(komorebi_themes::CatppuccinValue::Base) + .color32(name.as_theme()); + + let stackbar_focused_text = stackbar_focused_text + .unwrap_or(komorebi_themes::CatppuccinValue::Green) + .color32(name.as_theme()); + + let stackbar_unfocused_text = stackbar_unfocused_text + .unwrap_or(komorebi_themes::CatppuccinValue::Text) + .color32(name.as_theme()); + + let stackbar_background = stackbar_background + .unwrap_or(komorebi_themes::CatppuccinValue::Base) + .color32(name.as_theme()); + + ( + single_border, + stack_border, + monocle_border, + unfocused_border, + stackbar_focused_text, + stackbar_unfocused_text, + stackbar_background, + ) + } + KomorebiTheme::Base16 { + name, + single_border, + stack_border, + monocle_border, + unfocused_border, + stackbar_focused_text, + stackbar_unfocused_text, + stackbar_background, + } => { + let single_border = single_border + .unwrap_or(komorebi_themes::Base16Value::Base0D) + .color32(*name); + + let stack_border = stack_border + .unwrap_or(komorebi_themes::Base16Value::Base0B) + .color32(*name); + + let monocle_border = monocle_border + .unwrap_or(komorebi_themes::Base16Value::Base0F) + .color32(*name); + + let unfocused_border = unfocused_border + .unwrap_or(komorebi_themes::Base16Value::Base01) + .color32(*name); + + let stackbar_focused_text = stackbar_focused_text + .unwrap_or(komorebi_themes::Base16Value::Base0B) + .color32(*name); + + let stackbar_unfocused_text = stackbar_unfocused_text + .unwrap_or(komorebi_themes::Base16Value::Base05) + .color32(*name); + + let stackbar_background = stackbar_background + .unwrap_or(komorebi_themes::Base16Value::Base01) + .color32(*name); + + ( + single_border, + stack_border, + monocle_border, + unfocused_border, + stackbar_focused_text, + stackbar_unfocused_text, + stackbar_background, + ) + } + }; + + border_manager::FOCUSED.store( + u32::from(Colour::Rgb(Rgb::new( + single_border.r() as u32, + single_border.g() as u32, + single_border.b() as u32, + ))), + Ordering::SeqCst, + ); + + border_manager::MONOCLE.store( + u32::from(Colour::Rgb(Rgb::new( + monocle_border.r() as u32, + monocle_border.g() as u32, + monocle_border.b() as u32, + ))), + Ordering::SeqCst, + ); + + border_manager::STACK.store( + u32::from(Colour::Rgb(Rgb::new( + stack_border.r() as u32, + stack_border.g() as u32, + stack_border.b() as u32, + ))), + Ordering::SeqCst, + ); + + border_manager::UNFOCUSED.store( + u32::from(Colour::Rgb(Rgb::new( + unfocused_border.r() as u32, + unfocused_border.g() as u32, + unfocused_border.b() as u32, + ))), + Ordering::SeqCst, + ); + + STACKBAR_TAB_BACKGROUND_COLOUR.store( + u32::from(Colour::Rgb(Rgb::new( + stackbar_background.r() as u32, + stackbar_background.g() as u32, + stackbar_background.b() as u32, + ))), + Ordering::SeqCst, + ); + + STACKBAR_FOCUSED_TEXT_COLOUR.store( + u32::from(Colour::Rgb(Rgb::new( + stackbar_focused_text.r() as u32, + stackbar_focused_text.g() as u32, + stackbar_focused_text.b() as u32, + ))), + Ordering::SeqCst, + ); + + STACKBAR_UNFOCUSED_TEXT_COLOUR.store( + u32::from(Colour::Rgb(Rgb::new( + stackbar_unfocused_text.r() as u32, + stackbar_unfocused_text.g() as u32, + stackbar_unfocused_text.b() as u32, + ))), + Ordering::SeqCst, + ); + } + if let Some(path) = &self.app_specific_configuration_path { let path = resolve_home_path(path)?; let content = std::fs::read_to_string(path)?; @@ -978,7 +1197,9 @@ impl StaticConfig { for (i, monitor) in monitors.iter().enumerate() { if let Some(m) = wm.monitors_mut().get_mut(i) { m.ensure_workspace_count(monitor.workspaces.len()); - m.set_work_area_offset(monitor.work_area_offset); + if m.work_area_offset().is_none() { + m.set_work_area_offset(monitor.work_area_offset); + } m.set_window_based_work_area_offset(monitor.window_based_work_area_offset); m.set_window_based_work_area_offset_limit( monitor.window_based_work_area_offset_limit.unwrap_or(1), diff --git a/schema.json b/schema.json index 9c453eb8..faaaa2c6 100644 --- a/schema.json +++ b/schema.json @@ -236,7 +236,7 @@ } }, "border_implementation": { - "description": "Display an active window border (default: false)", + "description": "Active window border implementation (default: Komorebi)", "oneOf": [ { "description": "Use the adjustable komorebi border implementation", @@ -383,6 +383,25 @@ "TopMost" ] }, + "cross_boundary_behaviour": { + "description": "Determine what happens when an action is called on a window at a monitor boundary (default: Monitor)", + "oneOf": [ + { + "description": "Attempt to perform actions across a workspace boundary", + "type": "string", + "enum": [ + "Workspace" + ] + }, + { + "description": "Attempt to perform actions across a monitor boundary", + "type": "string", + "enum": [ + "Monitor" + ] + } + ] + }, "cross_monitor_move_behaviour": { "description": "Determine what happens when a window is moved across a monitor boundary (default: Swap)", "oneOf": [ @@ -1138,7 +1157,7 @@ "format": "int32" }, "label": { - "description": "Stackbar height", + "description": "Stackbar label", "type": "string", "enum": [ "Process", @@ -1293,6 +1312,706 @@ } } }, + "theme": { + "description": "Theme configuration options", + "oneOf": [ + { + "description": "A theme from catppuccin-egui", + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "monocle_border": { + "description": "Border colour when the container is in monocle mode (default: Pink)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "name": { + "description": "Name of the Catppuccin theme", + "type": "string", + "enum": [ + "Frappe", + "Latte", + "Macchiato", + "Mocha" + ] + }, + "single_border": { + "description": "Border colour when the container contains a single window (default: Blue)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "stack_border": { + "description": "Border colour when the container contains multiple windows (default: Green)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "stackbar_background": { + "description": "Stackbar tab background colour (default: Base)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "stackbar_focused_text": { + "description": "Stackbar focused tab text colour (default: Green)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "stackbar_unfocused_text": { + "description": "Stackbar unfocused tab text colour (default: Text)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + }, + "type": { + "type": "string", + "enum": [ + "Catppuccin" + ] + }, + "unfocused_border": { + "description": "Border colour when the container is unfocused (default: Base)", + "type": "string", + "enum": [ + "Rosewater", + "Flamingo", + "Pink", + "Mauve", + "Red", + "Maroon", + "Peach", + "Yellow", + "Green", + "Teal", + "Sky", + "Sapphire", + "Blue", + "Lavender", + "Text", + "Subtext1", + "Subtext0", + "Overlay2", + "Overlay1", + "Overlay0", + "Surface2", + "Surface1", + "Surface0", + "Base", + "Mantle", + "Crust" + ] + } + } + }, + { + "description": "A theme from base16-egui-themes", + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "monocle_border": { + "description": "Border colour when the container is in monocle mode (default: Base0F)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "name": { + "description": "Name of the Base16 theme", + "type": "string", + "enum": [ + "3024", + "Apathy", + "Apprentice", + "Ashes", + "AtelierCaveLight", + "AtelierCave", + "AtelierDuneLight", + "AtelierDune", + "AtelierEstuaryLight", + "AtelierEstuary", + "AtelierForestLight", + "AtelierForest", + "AtelierHeathLight", + "AtelierHeath", + "AtelierLakesideLight", + "AtelierLakeside", + "AtelierPlateauLight", + "AtelierPlateau", + "AtelierSavannaLight", + "AtelierSavanna", + "AtelierSeasideLight", + "AtelierSeaside", + "AtelierSulphurpoolLight", + "AtelierSulphurpool", + "Atlas", + "AyuDark", + "AyuLight", + "AyuMirage", + "Aztec", + "Bespin", + "BlackMetalBathory", + "BlackMetalBurzum", + "BlackMetalDarkFuneral", + "BlackMetalGorgoroth", + "BlackMetalImmortal", + "BlackMetalKhold", + "BlackMetalMarduk", + "BlackMetalMayhem", + "BlackMetalNile", + "BlackMetalVenom", + "BlackMetal", + "Blueforest", + "Blueish", + "Brewer", + "Bright", + "Brogrammer", + "BrushtreesDark", + "Brushtrees", + "Caroline", + "CatppuccinFrappe", + "CatppuccinLatte", + "CatppuccinMacchiato", + "CatppuccinMocha", + "Chalk", + "Circus", + "ClassicDark", + "ClassicLight", + "Codeschool", + "Colors", + "Cupcake", + "Cupertino", + "DaOneBlack", + "DaOneGray", + "DaOneOcean", + "DaOnePaper", + "DaOneSea", + "DaOneWhite", + "DanqingLight", + "Danqing", + "Darcula", + "Darkmoss", + "Darktooth", + "Darkviolet", + "Decaf", + "DefaultDark", + "DefaultLight", + "Dirtysea", + "Dracula", + "EdgeDark", + "EdgeLight", + "Eighties", + "EmbersLight", + "Embers", + "Emil", + "EquilibriumDark", + "EquilibriumGrayDark", + "EquilibriumGrayLight", + "EquilibriumLight", + "Eris", + "Espresso", + "EvaDim", + "Eva", + "EvenokDark", + "EverforestDarkHard", + "Everforest", + "Flat", + "Framer", + "FruitSoda", + "Gigavolt", + "Github", + "GoogleDark", + "GoogleLight", + "Gotham", + "GrayscaleDark", + "GrayscaleLight", + "Greenscreen", + "Gruber", + "GruvboxDarkHard", + "GruvboxDarkMedium", + "GruvboxDarkPale", + "GruvboxDarkSoft", + "GruvboxLightHard", + "GruvboxLightMedium", + "GruvboxLightSoft", + "GruvboxMaterialDarkHard", + "GruvboxMaterialDarkMedium", + "GruvboxMaterialDarkSoft", + "GruvboxMaterialLightHard", + "GruvboxMaterialLightMedium", + "GruvboxMaterialLightSoft", + "Hardcore", + "Harmonic16Dark", + "Harmonic16Light", + "HeetchLight", + "Heetch", + "Helios", + "Hopscotch", + "HorizonDark", + "HorizonLight", + "HorizonTerminalDark", + "HorizonTerminalLight", + "HumanoidDark", + "HumanoidLight", + "IaDark", + "IaLight", + "Icy", + "Irblack", + "Isotope", + "Jabuti", + "Kanagawa", + "Katy", + "Kimber", + "Lime", + "Macintosh", + "Marrakesh", + "Materia", + "MaterialDarker", + "MaterialLighter", + "MaterialPalenight", + "MaterialVivid", + "Material", + "MeasuredDark", + "MeasuredLight", + "MellowPurple", + "MexicoLight", + "Mocha", + "Monokai", + "Moonlight", + "Mountain", + "Nebula", + "NordLight", + "Nord", + "Nova", + "Ocean", + "Oceanicnext", + "OneLight", + "OnedarkDark", + "Onedark", + "OutrunDark", + "OxocarbonDark", + "OxocarbonLight", + "Pandora", + "PapercolorDark", + "PapercolorLight", + "Paraiso", + "Pasque", + "Phd", + "Pico", + "Pinky", + "Pop", + "Porple", + "PreciousDarkEleven", + "PreciousDarkFifteen", + "PreciousLightWarm", + "PreciousLightWhite", + "PrimerDarkDimmed", + "PrimerDark", + "PrimerLight", + "Purpledream", + "Qualia", + "Railscasts", + "Rebecca", + "RosePineDawn", + "RosePineMoon", + "RosePine", + "Saga", + "Sagelight", + "Sakura", + "Sandcastle", + "SelenizedBlack", + "SelenizedDark", + "SelenizedLight", + "SelenizedWhite", + "Seti", + "ShadesOfPurple", + "ShadesmearDark", + "ShadesmearLight", + "Shapeshifter", + "SilkDark", + "SilkLight", + "Snazzy", + "SolarflareLight", + "Solarflare", + "SolarizedDark", + "SolarizedLight", + "Spaceduck", + "Spacemacs", + "Sparky", + "StandardizedDark", + "StandardizedLight", + "Stella", + "StillAlive", + "Summercamp", + "SummerfruitDark", + "SummerfruitLight", + "SynthMidnightDark", + "SynthMidnightLight", + "Tango", + "Tarot", + "Tender", + "TerracottaDark", + "Terracotta", + "TokyoCityDark", + "TokyoCityLight", + "TokyoCityTerminalDark", + "TokyoCityTerminalLight", + "TokyoNightDark", + "TokyoNightLight", + "TokyoNightMoon", + "TokyoNightStorm", + "TokyoNightTerminalDark", + "TokyoNightTerminalLight", + "TokyoNightTerminalStorm", + "TokyodarkTerminal", + "Tokyodark", + "TomorrowNightEighties", + "TomorrowNight", + "Tomorrow", + "Tube", + "Twilight", + "UnikittyDark", + "UnikittyLight", + "UnikittyReversible", + "Uwunicorn", + "Vesper", + "Vice", + "Vulcan", + "Windows10Light", + "Windows10", + "Windows95Light", + "Windows95", + "WindowsHighcontrastLight", + "WindowsHighcontrast", + "WindowsNtLight", + "WindowsNt", + "Woodland", + "XcodeDusk", + "Zenbones", + "Zenburn" + ] + }, + "single_border": { + "description": "Border colour when the container contains a single window (default: Base0D)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "stack_border": { + "description": "Border colour when the container contains multiple windows (default: Base0B)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "stackbar_background": { + "description": "Stackbar tab background colour (default: Base01)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "stackbar_focused_text": { + "description": "Stackbar focused tab text colour (default: Base0B)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "stackbar_unfocused_text": { + "description": "Stackbar unfocused tab text colour (default: Base05)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + }, + "type": { + "type": "string", + "enum": [ + "Base16" + ] + }, + "unfocused_border": { + "description": "Border colour when the container is unfocused (default: Base01)", + "type": "string", + "enum": [ + "Base00", + "Base01", + "Base02", + "Base03", + "Base04", + "Base05", + "Base06", + "Base07", + "Base08", + "Base09", + "Base0A", + "Base0B", + "Base0C", + "Base0D", + "Base0E", + "Base0F" + ] + } + } + } + ] + }, "transparency": { "description": "Add transparency to unfocused windows (default: false)", "type": "boolean"