Design refresh: new icon assets, bluetooth popover, notification urgency styling, RAM/power draw in control panel
Adds real SVG icon assets replacing the icons-needed.txt checklist, a bluetooth popover module, per-notification urgency (CSS-styled), and app-name/summary dedup in notification cards. Rounds out the control panel's stats section with RAM and power draw alongside the existing CPU/GPU/net rows.
This commit is contained in:
parent
e8d5fd5a52
commit
86432d718a
22 changed files with 625 additions and 185 deletions
|
|
@ -11,10 +11,29 @@ pub enum NotifEvent {
|
|||
summary: String,
|
||||
body: String,
|
||||
timeout_ms: u32,
|
||||
urgency: Urgency,
|
||||
},
|
||||
Close(u32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Urgency {
|
||||
Low,
|
||||
Normal,
|
||||
Critical,
|
||||
}
|
||||
|
||||
impl Urgency {
|
||||
/// CSS class suffix for `.notification-card.urgency-<kind>`.
|
||||
pub fn css_class(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Urgency::Low => None,
|
||||
Urgency::Normal => Some("urgency-normal"),
|
||||
Urgency::Critical => Some("urgency-critical"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NotifServer {
|
||||
tx: mpsc::Sender<NotifEvent>,
|
||||
next_id: AtomicU32,
|
||||
|
|
@ -32,7 +51,7 @@ impl NotifServer {
|
|||
summary: &str,
|
||||
body: &str,
|
||||
_actions: Vec<String>,
|
||||
_hints: std::collections::HashMap<String, OwnedValue>,
|
||||
hints: std::collections::HashMap<String, OwnedValue>,
|
||||
expire_timeout: i32,
|
||||
) -> u32 {
|
||||
let id = if replaces_id != 0 {
|
||||
|
|
@ -45,6 +64,12 @@ impl NotifServer {
|
|||
} else {
|
||||
expire_timeout as u32
|
||||
};
|
||||
// Spec: hints["urgency"] is a byte, 0=low, 1=normal, 2=critical (default normal).
|
||||
let urgency = match hints.get("urgency").and_then(|v| u8::try_from(v.clone()).ok()) {
|
||||
Some(0) => Urgency::Low,
|
||||
Some(2) => Urgency::Critical,
|
||||
_ => Urgency::Normal,
|
||||
};
|
||||
let _ = self
|
||||
.tx
|
||||
.send(NotifEvent::Show {
|
||||
|
|
@ -53,6 +78,7 @@ impl NotifServer {
|
|||
summary: summary.to_string(),
|
||||
body: body.to_string(),
|
||||
timeout_ms,
|
||||
urgency,
|
||||
})
|
||||
.await;
|
||||
id
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use gtk4::prelude::*;
|
|||
use gtk4_layer_shell::{Edge, Layer, LayerShell};
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
|
||||
use super::NotifEvent;
|
||||
use super::{NotifEvent, Urgency};
|
||||
|
||||
type Cards = Rc<RefCell<HashMap<u32, gtk4::Box>>>;
|
||||
|
||||
|
|
@ -27,12 +27,13 @@ pub async fn run(mut rx: Receiver<NotifEvent>) {
|
|||
summary,
|
||||
body,
|
||||
timeout_ms,
|
||||
urgency,
|
||||
} => {
|
||||
// Replace existing card with same id (replaces_id case)
|
||||
if let Some(old) = cards.borrow_mut().remove(&id) {
|
||||
cards_box.remove(&old);
|
||||
}
|
||||
let card = make_card(&app_name, &summary, &body);
|
||||
let card = make_card(&app_name, &summary, &body, urgency);
|
||||
cards_box.prepend(&card);
|
||||
cards.borrow_mut().insert(id, card.clone());
|
||||
window.set_visible(true);
|
||||
|
|
@ -75,11 +76,17 @@ fn create_window() -> gtk4::Window {
|
|||
window
|
||||
}
|
||||
|
||||
fn make_card(app_name: &str, summary: &str, body: &str) -> gtk4::Box {
|
||||
fn make_card(app_name: &str, summary: &str, body: &str, urgency: Urgency) -> gtk4::Box {
|
||||
let card = gtk4::Box::new(gtk4::Orientation::Vertical, 4);
|
||||
card.add_css_class("notification-card");
|
||||
if let Some(class) = urgency.css_class() {
|
||||
card.add_css_class(class);
|
||||
}
|
||||
|
||||
if !app_name.is_empty() {
|
||||
// Senders often set the title/summary to their own app name (e.g. a bare
|
||||
// "Spotify" notification) — showing app_name above an identical summary
|
||||
// is pure repetition, so skip the app label in that case.
|
||||
if !app_name.is_empty() && !app_name.eq_ignore_ascii_case(summary) {
|
||||
let lbl = gtk4::Label::new(Some(app_name));
|
||||
lbl.add_css_class("notification-app");
|
||||
lbl.set_xalign(0.0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue