From 12c891cf76b324dab20dbad7105cc112f7c526bc Mon Sep 17 00:00:00 2001 From: Himaneesh Mishra Date: Thu, 3 Apr 2025 09:53:53 -0400 Subject: [PATCH] feat(theme): add sway bar color integration --- src/config.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 14 ++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 061e90e0c0..2da30522ca 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,15 @@ use crate::formatting::config::Config as FormatConfig; use crate::icons::{Icon, Icons}; use crate::themes::{Theme, ThemeOverrides, ThemeUserConfig}; +use dirs; //used in implementing parsing logic for the sway override function + + +// === Optional sway integration === +#[derive(Deserialize, Debug)] +pub struct SwayIntegration { + pub use_sway_bar_colors: Option, +} + #[derive(Deserialize, Debug)] pub struct Config { #[serde(flatten)] @@ -31,6 +40,9 @@ pub struct Config { #[serde(default)] #[serde(rename = "block")] pub blocks: Vec, + + #[serde(default)] + pub sway_integration: Option, } #[derive(Deserialize, Debug, Clone)] @@ -115,3 +127,45 @@ where let theme = Theme::try_from(theme_config).serde_error()?; Ok(Arc::new(theme)) } + +use crate::themes::color::Color; + +pub fn try_parse_sway_bar_colors() -> Option<(Color, Color)> { + let config_path = dirs::home_dir()?.join(".config/sway/config"); + let contents = std::fs::read_to_string(config_path).ok()?; + + let mut in_bar_block = false; + let mut in_colors_block = false; + let mut background = None; + let mut statusline = None; + + for line in contents.lines() { + let trimmed = line.trim(); + if trimmed.starts_with("bar") && trimmed.ends_with("{") { + in_bar_block = true; + continue; + } + if in_bar_block && trimmed.starts_with("colors") && trimmed.ends_with("{") { + in_colors_block = true; + continue; + } + if in_colors_block { + if trimmed.starts_with("}") { + break; + } + if trimmed.starts_with("background") { + background = trimmed.split_whitespace().nth(1).map(str::to_string); + } else if trimmed.starts_with("statusline") { + statusline = trimmed.split_whitespace().nth(1).map(str::to_string); + } + } + } + + if let (Some(bg_str), Some(fg_str)) = (background, statusline) { + let bg: Color = bg_str.parse().ok()?; + let fg: Color = fg_str.parse().ok()?; + Some((bg, fg)) + } else { + None + } +} diff --git a/src/main.rs b/src/main.rs index c0dae53f95..cc451a478e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,14 @@ use clap::Parser; use i3status_rs::blocks::BlockError; -use i3status_rs::config::Config; +use i3status_rs::config::{Config, try_parse_sway_bar_colors}; use i3status_rs::errors::*; use i3status_rs::escape::Escaped; use i3status_rs::widget::{State, Widget}; use i3status_rs::{BarState, protocol, util}; +use std::sync::Arc; + #[derive(Debug, thiserror::Error)] enum ErrorMaybeInBlock { #[error(transparent)] @@ -34,6 +36,15 @@ fn main() { let config_path = util::find_file(&args.config, None, Some("toml")) .or_error(|| format!("Configuration file '{}' not found", args.config))?; let mut config: Config = util::deserialize_toml_file(&config_path)?; + + // === Inject Sway bar color override if enabled === + if let Some((bg, fg)) = try_parse_sway_bar_colors() { + let theme = Arc::make_mut(&mut config.shared.theme); + theme.idle_bg = bg; + theme.idle_fg = fg; + } + + let blocks = std::mem::take(&mut config.blocks); let mut bar = BarState::new(config); for block_config in blocks { @@ -42,6 +53,7 @@ fn main() { bar.run_event_loop(restart).await?; Ok(()) }); + if let Err(error) = result { let error_widget = Widget::new() .with_text(error.to_string().pango_escaped())