From d2727f5aba9a5d11b81bf159945b55c12dc0a708 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Wed, 28 Oct 2020 02:25:10 +0100 Subject: [PATCH] feat: add support for UNNotificationResponse in app 'ready' event (#25950) --- docs/api/app.md | 5 +- docs/api/structures/notification-response.md | 7 +++ docs/tutorial/quick-start.md | 2 +- filenames.auto.gni | 1 + .../mac/electron_application_delegate.mm | 46 ++++++++++++++++--- 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 docs/api/structures/notification-response.md diff --git a/docs/api/app.md b/docs/api/app.md index 239ed6ba1e57d..e2182e17ff086 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -33,10 +33,11 @@ In most cases, you should do everything in the `ready` event handler. Returns: * `event` Event -* `launchInfo` Record _macOS_ +* `launchInfo` Record | [NotificationResponse](structures/notification-response.md) _macOS_ Emitted once, when Electron has finished initializing. On macOS, `launchInfo` -holds the `userInfo` of the `NSUserNotification` that was used to open the +holds the `userInfo` of the `NSUserNotification` or information from +[`UNNotificationResponse`](structures/notification-response.md) that was used to open the application, if it was launched from Notification Center. You can also call `app.isReady()` to check if this event has already fired and `app.whenReady()` to get a Promise that is fulfilled when Electron is initialized. diff --git a/docs/api/structures/notification-response.md b/docs/api/structures/notification-response.md new file mode 100644 index 0000000000000..f6c3e1081a22f --- /dev/null +++ b/docs/api/structures/notification-response.md @@ -0,0 +1,7 @@ +# NotificationResponse Object + +* `actionIdentifier` String - The identifier string of the action that the user selected. +* `date` Number - The delivery date of the notification. +* `identifier` String - The unique identifier for this notification request. +* `userInfo` Record - A dictionary of custom information associated with the notification. +* `userText` String (optional) - The text entered or chosen by the user. diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 5eab0dcc38b57..937f496d64a62 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -297,4 +297,4 @@ Then, in your Electron application, require the module: ```js const S3 = require('aws-sdk/clients/s3') -``` \ No newline at end of file +``` diff --git a/filenames.auto.gni b/filenames.auto.gni index f68861f533dca..b8789b10055b6 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -103,6 +103,7 @@ auto_filenames = { "docs/api/structures/mouse-wheel-input-event.md", "docs/api/structures/new-window-web-contents-event.md", "docs/api/structures/notification-action.md", + "docs/api/structures/notification-response.md", "docs/api/structures/point.md", "docs/api/structures/post-body.md", "docs/api/structures/post-data.md", diff --git a/shell/browser/mac/electron_application_delegate.mm b/shell/browser/mac/electron_application_delegate.mm index 15e4456680069..ceded50f9a5d7 100644 --- a/shell/browser/mac/electron_application_delegate.mm +++ b/shell/browser/mac/electron_application_delegate.mm @@ -17,6 +17,8 @@ #include "shell/browser/mac/dict_util.h" #import "shell/browser/mac/electron_application.h" +#import + #if BUILDFLAG(USE_ALLOCATOR_SHIM) // On macOS 10.12, the IME system attempts to allocate a 2^64 size buffer, // which would typically cause an OOM crash. To avoid this, the problematic @@ -41,6 +43,29 @@ - (void)_coreAttributesFromRange:(NSRange)range @end #endif // BUILDFLAG(USE_ALLOCATOR_SHIM) +static NSDictionary* UNNotificationResponseToNSDictionary( + UNNotificationResponse* response) API_AVAILABLE(macosx(10.14)) { + // [response isKindOfClass:[UNNotificationResponse class]] + if (![response respondsToSelector:@selector(actionIdentifier)] || + ![response respondsToSelector:@selector(notification)]) { + return nil; + } + + NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; + result[@"actionIdentifier"] = response.actionIdentifier; + result[@"date"] = @(response.notification.date.timeIntervalSince1970); + result[@"identifier"] = response.notification.request.identifier; + result[@"userInfo"] = response.notification.request.content.userInfo; + + // [response isKindOfClass:[UNTextInputNotificationResponse class]] + if ([response respondsToSelector:@selector(userText)]) { + result[@"userText"] = + static_cast(response).userText; + } + + return result; +} + @implementation ElectronApplicationDelegate - (void)setApplicationDockMenu:(electron::ElectronMenuModel*)model { @@ -68,16 +93,23 @@ - (void)applicationWillFinishLaunching:(NSNotification*)notify { } - (void)applicationDidFinishLaunching:(NSNotification*)notify { - NSUserNotification* user_notification = + NSObject* user_notification = [notify userInfo][NSApplicationLaunchUserNotificationKey]; - - if ([user_notification isKindOfClass:[NSUserNotification class]]) { - electron::Browser::Get()->DidFinishLaunching( - electron::NSDictionaryToDictionaryValue(user_notification.userInfo)); - } else { - electron::Browser::Get()->DidFinishLaunching(base::DictionaryValue()); + NSDictionary* notification_info = nil; + + if (user_notification) { + if ([user_notification isKindOfClass:[NSUserNotification class]]) { + notification_info = + [static_cast(user_notification) userInfo]; + } else if (@available(macOS 10.14, *)) { + notification_info = UNNotificationResponseToNSDictionary( + static_cast(user_notification)); + } } + electron::Browser::Get()->DidFinishLaunching( + electron::NSDictionaryToDictionaryValue(notification_info)); + #if BUILDFLAG(USE_ALLOCATOR_SHIM) // Disable fatal OOM to hack around an OS bug https://crbug.com/654695. if (base::mac::IsOS10_12()) {