notification daemon
git clone https://git.lucas.co/cce-notifier.git
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;