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.
This commit is contained in:
LGUG2Z
2024-09-14 16:31:39 -07:00
parent bc67936dd3
commit 45894be4ff
10 changed files with 1146 additions and 217 deletions
+2
View File
@@ -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 }
+223 -2
View File
@@ -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<AnimationsConfig>,
/// Theme configuration options
#[serde(skip_serializing_if = "Option::is_none")]
pub theme: Option<KomorebiTheme>,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
@@ -371,6 +375,48 @@ pub struct AnimationsConfig {
/// Set the animation FPS (default: 60)
fps: Option<u64>,
}
#[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<komorebi_themes::CatppuccinValue>,
/// Border colour when the container contains multiple windows (default: Green)
stack_border: Option<komorebi_themes::CatppuccinValue>,
/// Border colour when the container is in monocle mode (default: Pink)
monocle_border: Option<komorebi_themes::CatppuccinValue>,
/// Border colour when the container is unfocused (default: Base)
unfocused_border: Option<komorebi_themes::CatppuccinValue>,
/// Stackbar focused tab text colour (default: Green)
stackbar_focused_text: Option<komorebi_themes::CatppuccinValue>,
/// Stackbar unfocused tab text colour (default: Text)
stackbar_unfocused_text: Option<komorebi_themes::CatppuccinValue>,
/// Stackbar tab background colour (default: Base)
stackbar_background: Option<komorebi_themes::CatppuccinValue>,
},
/// 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<komorebi_themes::Base16Value>,
/// Border colour when the container contains multiple windows (default: Base0B)
stack_border: Option<komorebi_themes::Base16Value>,
/// Border colour when the container is in monocle mode (default: Base0F)
monocle_border: Option<komorebi_themes::Base16Value>,
/// Border colour when the container is unfocused (default: Base01)
unfocused_border: Option<komorebi_themes::Base16Value>,
/// Stackbar focused tab text colour (default: Base0B)
stackbar_focused_text: Option<komorebi_themes::Base16Value>,
/// Stackbar unfocused tab text colour (default: Base05)
stackbar_unfocused_text: Option<komorebi_themes::Base16Value>,
/// Stackbar tab background colour (default: Base01)
stackbar_background: Option<komorebi_themes::Base16Value>,
},
}
impl StaticConfig {
pub fn aliases(raw: &str) {
@@ -446,7 +492,7 @@ pub struct TabsConfig {
pub struct StackbarConfig {
/// Stackbar height
pub height: Option<i32>,
/// Stackbar height
/// Stackbar label
pub label: Option<StackbarLabel>,
/// Stackbar mode
pub mode: Option<StackbarMode>,
@@ -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),