From 3683040881da3a3222e5248fc1c227d1c8cf5bf5 Mon Sep 17 00:00:00 2001 From: szymon Date: Tue, 29 Sep 2026 01:00:33 +0200 Subject: [PATCH] feat: add add_action --- src/lib.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6f23cb5..bc5aee0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ pub enum Urgency { pub enum ClosedReason { Unset, Expired, - ApiReqest, + ApiRequest, Undefined, } @@ -53,6 +53,58 @@ impl<'a> Notification { Ok(Self { inner }) } + + pub fn add_action( + &mut self, + action: &str, + label: &str, + callback: F, + ) -> Result<(), Box> + where + F: Fn(&str) + 'static, + { + let action = std::ffi::CString::new(action)?; + let label = std::ffi::CString::new(label)?; + + let callback: Box = Box::new(callback); + let user_data = Box::into_raw(callback) as *mut std::ffi::c_void; + + let free_func = drop_box::; + + unsafe { + notify_notification_add_action( + self.inner, + action.as_ptr(), + label.as_ptr(), + Some(action_trampoline::), + user_data, + Some(free_func), + ); + } + + Ok(()) + } +} + +unsafe extern "C" fn action_trampoline( + _notification: *mut NotifyNotification, + action: *mut ::std::os::raw::c_char, + user_data: gpointer, +) where + F: Fn(&str) + 'static, +{ + let callback = unsafe { &*(user_data as *const F) }; + + if action.is_null() { + return; + } + + let action = unsafe { std::ffi::CStr::from_ptr(action).to_string_lossy() }; + callback(&action); +} + +unsafe extern "C" fn drop_box(data: gpointer) { + unsafe { drop(Box::from_raw(data as *mut F)) }; } #[cfg(test)]