git.lucas.co / cce-notifier
notification daemon
git clone https://git.lucas.co/cce-notifier.git

commit70d27bfdc470f5a95283c5164ed6f0f5c73fb6df
parent6c585b04d2
authorLucas Galante <[email protected]>
date2026-06-16 12:13
Support configurable background color and opacity for notification popups

 src/main.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 9174ba5..9aafdea 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -129,6 +129,7 @@ struct NotificationApp {
     needs_rebuild: bool,
     configured: bool,
     opacity: f32,
+    bg_color: [f32; 4],
 
     app_name: String,
     summary: String,
@@ -150,6 +151,7 @@ impl NotificationApp {
         queue: wgpu::Queue,
         cache: &Cache,
         opacity: f32,
+        bg_color: [f32; 4],
     ) -> Self {
         let surface = compositor_state.create_surface(qh);
         surface.set_buffer_scale(scale as i32);
@@ -220,6 +222,7 @@ impl NotificationApp {
             needs_rebuild: true,
             configured: false,
             opacity,
+            bg_color,
             app_name: String::new(),
             summary: String::new(),
             body: String::new(),
@@ -241,9 +244,9 @@ impl NotificationApp {
             w: sw,
             h: sh,
             color: [
-                clear_ui::colors::HEADER_BG[0],
-                clear_ui::colors::HEADER_BG[1],
-                clear_ui::colors::HEADER_BG[2],
+                self.bg_color[0],
+                self.bg_color[1],
+                self.bg_color[2],
                 self.opacity,
             ],
         });
@@ -480,7 +483,7 @@ fn read_opacity_if_configured() -> f32 {
     let mut in_section = false;
     for line in content.lines() {
         let trimmed = line.trim();
-        if trimmed == "[transparency]" {
+        if trimmed == "[notifications]" {
             in_section = true;
             continue;
         }
@@ -498,6 +501,48 @@ fn read_opacity_if_configured() -> f32 {
     0.9 // default opacity
 }
 
+fn read_bg_color_if_configured() -> [f32; 4] {
+    let config_path = "/home/lsgalante/.config/cce/config.toml";
+    let content = std::fs::read_to_string(config_path).unwrap_or_default();
+    
+    let mut in_section = false;
+    for line in content.lines() {
+        let trimmed = line.trim();
+        if trimmed == "[notifications]" {
+            in_section = true;
+            continue;
+        }
+        if trimmed.starts_with('[') && in_section {
+            break;
+        }
+        if in_section && trimmed.starts_with("bg_color") {
+            if let Some(val) = trimmed.split('=').nth(1) {
+                let rest = val.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+                let hex = rest.trim_end_matches('"').trim().trim_start_matches('#');
+                if hex.len() >= 6 {
+                    if let (Ok(r), Ok(g), Ok(b)) = (
+                        u8::from_str_radix(&hex[0..2], 16),
+                        u8::from_str_radix(&hex[2..4], 16),
+                        u8::from_str_radix(&hex[4..6], 16),
+                    ) {
+                        let r_f = clear_ui::colors::srgb_to_linear(r as f32 / 255.0);
+                        let g_f = clear_ui::colors::srgb_to_linear(g as f32 / 255.0);
+                        let b_f = clear_ui::colors::srgb_to_linear(b as f32 / 255.0);
+                        return [r_f, g_f, b_f, 1.0];
+                    }
+                }
+            }
+        }
+    }
+    // Default notification background color: srgb [0.08, 0.08, 0.12]
+    [
+        clear_ui::colors::srgb_to_linear(0.08),
+        clear_ui::colors::srgb_to_linear(0.08),
+        clear_ui::colors::srgb_to_linear(0.12),
+        1.0,
+    ]
+}
+
 // ── D-Bus Events & AppState ──
 
 #[derive(Debug, Clone)]
@@ -784,6 +829,7 @@ impl AppState {
                 self.current_id += 1;
                 let active_id = self.current_id;
                 let opacity = read_opacity_if_configured();
+                let bg_color = read_bg_color_if_configured();
 
                 if self.state.is_none() {
                     println!("[cce-notification-daemon] Opening notification window: {} - {}", summary, body);
@@ -804,6 +850,7 @@ impl AppState {
                         self.wgpu_queue.clone(),
                         &self.renderer_resources.cache,
                         opacity,
+                        bg_color,
                     );
                     state.app_name = app_name;
                     state.summary = summary;
@@ -816,6 +863,7 @@ impl AppState {
                     state.summary = summary;
                     state.body = body;
                     state.opacity = opacity;
+                    state.bg_color = bg_color;
                     state.needs_rebuild = true;
                 }
                 self.redraw = true;