From 4126950836e31f7971900d25e93e1bff1fcd0d10 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 2 Sep 2021 15:27:20 -0700 Subject: [PATCH] Struct for notification hints --- src/notifications.rs | 117 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/src/notifications.rs b/src/notifications.rs index 7049bd1b..62f3f1a6 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -4,7 +4,9 @@ use gtk4::{ prelude::*, }; use std::{ + borrow::Cow, collections::HashMap, + fmt, num::NonZeroU32, sync::{Arc, Mutex}, }; @@ -56,6 +58,93 @@ pub struct Notifications { next_id: Mutex, } +struct Hints(HashMap); + +#[allow(dead_code)] +impl Hints { + fn prop(&self, name: &str) -> Option { + self.0.get(name)?.get() + } + + fn actions_icon(&self) -> bool { + self.prop("actions-icon").unwrap_or(false) + } + + fn category(&self) -> Option { + self.prop("category") + } + + fn desktop_entry(&self) -> Option { + self.prop("desktop-entry") + } + + fn image_data(&self) -> Option<(i32, i32, i32, bool, i32, i32, Vec)> { + self.prop("image-data") + .or_else(|| self.prop("image_data")) + .or_else(|| self.prop("icon_data")) + } + + fn image_path(&self) -> Option { + self.prop("image-path").or_else(|| self.prop("image_path")) + } + + fn resident(&self) -> bool { + self.prop("resident").unwrap_or(false) + } + + fn sound_file(&self) -> Option { + self.prop("sound-file") + } + + fn sound_name(&self) -> Option { + self.prop("sound-name") + } + + fn transient(&self) -> bool { + self.prop("transient").unwrap_or(false) + } + + fn xy(&self) -> Option<(u8, u8)> { + Some((self.prop("x")?, self.prop("y")?)) + } + + fn urgency(&self) -> Option { + self.prop("urgency") + } +} + +impl fmt::Debug for Hints { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut s = f.debug_struct("Hints"); + for (k, v) in &self.0 { + if let Some(v) = v.get::() { + s.field(k, &v); + } else if let Some(v) = v.get::() { + s.field(k, &v); + } else if let Some(v) = v.get::() { + s.field(k, &v); + } else if let Some(v) = v.get::() { + s.field(k, &v); + } else { + s.field(k, v); + }; + } + s.finish() + } +} + +impl glib::StaticVariantType for Hints { + fn static_variant_type() -> Cow<'static, glib::VariantTy> { + glib::VariantTy::new("a{sv}").unwrap().into() + } +} + +impl glib::FromVariant for Hints { + fn from_variant(variant: &glib::Variant) -> Option { + variant.get().map(Self) + } +} + impl Notifications { pub fn new() -> Arc { let notifications = Arc::new(Notifications { @@ -84,17 +173,31 @@ impl Notifications { fn notify( &self, - _app_name: String, + app_name: String, replaces_id: Option, - _app_icon: String, - _summary: String, - _body: String, - _actions: Vec, - _hints: HashMap, - _expire_timeout: i32, + app_icon: String, + summary: String, + body: String, + actions: Vec, + hints: Hints, + expire_timeout: i32, ) -> NonZeroU32 { let id = replaces_id.unwrap_or_else(|| self.next_id()); + println!( + "{:?}", + ( + id, + app_name, + app_icon, + summary, + body, + actions, + hints, + expire_timeout + ) + ); + // TODO id