Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions examples/click.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use mac_notification_sys::*;

fn main() {
let response = send_notification(
"clickable notification",
None,
"click me",
Some(Notification::new().wait_for_click(true)),
)
.unwrap();

if matches!(response, NotificationResponse::Click) {
println!("Clicked the notification");
} else {
println!("No interaction");
}
}
3 changes: 2 additions & 1 deletion objc/notify.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ BOOL installNSBundleHook(void) {

@interface NotificationCenterDelegate: NSObject <NSUserNotificationCenterDelegate>
@property(nonatomic, assign) BOOL keepRunning;
@property(nonatomic, assign) BOOL waitForClick;
@property(nonatomic, retain) NSDictionary* actionData;
@end

Expand All @@ -40,7 +41,7 @@ BOOL installNSBundleHook(void) {
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
didDeliverNotification:(NSUserNotification*)notification {
// Stop running if we're not expecting a response
if (!notification.hasActionButton && !notification.hasReplyButton) {
if (!notification.hasActionButton && !notification.hasReplyButton && !self.waitForClick) {
self.keepRunning = NO;
}
}
Expand Down
6 changes: 6 additions & 0 deletions objc/notify.m
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ BOOL setApplication(NSString* newbundleIdentifier) {
userNotification.responsePlaceholder = options[@"mainButtonLabel"];
}

// Wait for click
if (options[@"click"] && ![options[@"click"] isEqualToString:@"yes"]) {
ncDelegate.keepRunning = YES;
ncDelegate.waitForClick = YES;
}

// Change the icon of the app in the notification
if (options[@"appIcon"] && ![options[@"appIcon"] isEqualToString:@""]) {
NSImage* icon = getImageFromURL(options[@"appIcon"]);
Expand Down
20 changes: 20 additions & 0 deletions src/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct Notification<'a> {
pub(crate) delivery_date: Option<f64>,
pub(crate) sound: Option<Sound>,
pub(crate) asynchronous: Option<bool>,
pub(crate) wait_for_click: Option<bool>,
}

impl<'a> Notification<'a> {
Expand Down Expand Up @@ -230,6 +231,19 @@ impl<'a> Notification<'a> {
self
}

/// Allow waiting a response for notification click.
///
/// # Example:
///
/// ```no_run
/// # use mac_notification_sys::*;
/// let _ = Notification::new().wait_for_click(true);
/// ```
pub fn wait_for_click(&mut self, click: bool) -> &mut Self {
self.wait_for_click = Some(click);
self
}

/// Convert the Notification to an Objective C NSDictionary
pub(crate) fn to_dictionary(&self) -> Retained<NSDictionary<NSString, NSString>> {
// TODO: If possible, find a way to simplify this so I don't have to manually convert struct to NSDictionary
Expand All @@ -243,6 +257,7 @@ impl<'a> Notification<'a> {
&*NSString::from_str("deliveryDate"),
&*NSString::from_str("asynchronous"),
&*NSString::from_str("sound"),
&*NSString::from_str("click"),
];
let (main_button_label, actions, is_response): (&str, &[&str], bool) =
match &self.main_button {
Expand Down Expand Up @@ -280,6 +295,11 @@ impl<'a> Notification<'a> {
Some(true) => "yes",
_ => "no",
}),
// TODO: Same as above, if NSDictionary could support multiple types, this could be a boolean
NSString::from_str(match self.wait_for_click {
Some(true) => "yes",
_ => "no",
}),
NSString::from_str(sound),
];
NSDictionary::from_retained_objects(keys, &vals)
Expand Down