2014-10-31 11:17:05 -07:00
|
|
|
// Copyright (c) 2013 GitHub, Inc.
|
2014-04-25 17:49:37 +08:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
2013-05-02 20:09:19 +08:00
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2019-06-19 13:46:59 -07:00
|
|
|
#import "shell/browser/mac/electron_application_delegate.h"
|
2016-05-02 16:18:58 -07:00
|
|
|
|
2019-05-02 14:05:37 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
|
2018-04-11 13:02:35 +02:00
|
|
|
#include "base/allocator/buildflags.h"
|
2023-10-24 11:24:20 -04:00
|
|
|
#include "base/allocator/partition_allocator/src/partition_alloc/shim/allocator_shim.h"
|
2017-08-30 12:03:05 +08:00
|
|
|
#include "base/mac/mac_util.h"
|
2014-04-15 09:35:26 +08:00
|
|
|
#include "base/strings/sys_string_conversions.h"
|
2016-05-05 16:26:44 +09:00
|
|
|
#include "base/values.h"
|
2022-07-12 08:38:49 -07:00
|
|
|
#include "shell/browser/api/electron_api_push_notifications.h"
|
2019-06-19 13:46:59 -07:00
|
|
|
#include "shell/browser/browser.h"
|
|
|
|
#include "shell/browser/mac/dict_util.h"
|
|
|
|
#import "shell/browser/mac/electron_application.h"
|
2013-05-02 20:09:19 +08:00
|
|
|
|
2020-10-28 02:25:10 +01:00
|
|
|
#import <UserNotifications/UserNotifications.h>
|
|
|
|
|
|
|
|
static NSDictionary* UNNotificationResponseToNSDictionary(
|
2023-07-01 16:22:55 -04:00
|
|
|
UNNotificationResponse* response) {
|
2020-10-28 02:25:10 +01:00
|
|
|
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<UNTextInputNotificationResponse*>(response).userText;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-06-08 10:26:33 +02:00
|
|
|
@implementation ElectronApplicationDelegate {
|
|
|
|
ElectronMenuController* __strong menu_controller_;
|
|
|
|
}
|
2013-05-02 20:09:19 +08:00
|
|
|
|
2016-07-02 11:47:40 +09:00
|
|
|
- (void)setApplicationDockMenu:(electron::ElectronMenuModel*)model {
|
2023-06-08 10:26:33 +02:00
|
|
|
menu_controller_ = [[ElectronMenuController alloc] initWithModel:model
|
|
|
|
useDefaultAccelerator:NO];
|
2014-11-16 23:04:31 +08:00
|
|
|
}
|
|
|
|
|
2020-06-15 18:58:28 -07:00
|
|
|
- (void)willPowerOff:(NSNotification*)notify {
|
|
|
|
[[AtomApplication sharedApplication] willPowerOff:notify];
|
|
|
|
}
|
|
|
|
|
2013-06-03 15:31:46 +08:00
|
|
|
- (void)applicationWillFinishLaunching:(NSNotification*)notify {
|
2015-12-10 11:27:41 +08:00
|
|
|
// Don't add the "Enter Full Screen" menu item automatically.
|
2018-04-20 14:47:04 -04:00
|
|
|
[[NSUserDefaults standardUserDefaults]
|
|
|
|
setBool:NO
|
|
|
|
forKey:@"NSFullScreenMenuItemEverywhere"];
|
2020-06-15 18:58:28 -07:00
|
|
|
|
|
|
|
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
|
|
|
addObserver:self
|
|
|
|
selector:@selector(willPowerOff:)
|
|
|
|
name:NSWorkspaceWillPowerOffNotification
|
|
|
|
object:nil];
|
2015-12-10 11:27:41 +08:00
|
|
|
|
2013-06-03 15:31:46 +08:00
|
|
|
electron::Browser::Get()->WillFinishLaunching();
|
|
|
|
}
|
|
|
|
|
2013-05-02 20:09:19 +08:00
|
|
|
- (void)applicationDidFinishLaunching:(NSNotification*)notify {
|
2020-10-28 02:25:10 +01:00
|
|
|
NSObject* user_notification =
|
2020-10-02 04:52:07 +02:00
|
|
|
[notify userInfo][NSApplicationLaunchUserNotificationKey];
|
2020-10-28 02:25:10 +01:00
|
|
|
NSDictionary* notification_info = nil;
|
2016-08-31 17:17:44 -07:00
|
|
|
|
2020-10-28 02:25:10 +01:00
|
|
|
if (user_notification) {
|
|
|
|
if ([user_notification isKindOfClass:[NSUserNotification class]]) {
|
|
|
|
notification_info =
|
|
|
|
[static_cast<NSUserNotification*>(user_notification) userInfo];
|
2023-07-01 16:22:55 -04:00
|
|
|
} else {
|
2020-10-28 02:25:10 +01:00
|
|
|
notification_info = UNNotificationResponseToNSDictionary(
|
|
|
|
static_cast<UNNotificationResponse*>(user_notification));
|
|
|
|
}
|
2016-08-31 17:17:44 -07:00
|
|
|
}
|
2017-08-30 12:03:05 +08:00
|
|
|
|
2020-10-28 02:25:10 +01:00
|
|
|
electron::Browser::Get()->DidFinishLaunching(
|
2022-06-22 23:28:41 -07:00
|
|
|
electron::NSDictionaryToValue(notification_info));
|
2013-05-02 20:09:19 +08:00
|
|
|
}
|
|
|
|
|
2020-06-16 19:03:41 +02:00
|
|
|
- (void)applicationDidBecomeActive:(NSNotification*)notification {
|
|
|
|
electron::Browser::Get()->DidBecomeActive();
|
|
|
|
}
|
|
|
|
|
2023-04-18 16:53:39 +02:00
|
|
|
- (void)applicationDidResignActive:(NSNotification*)notification {
|
|
|
|
electron::Browser::Get()->DidResignActive();
|
|
|
|
}
|
|
|
|
|
2014-11-16 23:04:31 +08:00
|
|
|
- (NSMenu*)applicationDockMenu:(NSApplication*)sender {
|
2023-06-08 10:26:33 +02:00
|
|
|
return menu_controller_ ? menu_controller_.menu : nil;
|
2014-11-16 23:04:31 +08:00
|
|
|
}
|
|
|
|
|
2018-04-20 14:47:04 -04:00
|
|
|
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename {
|
2013-05-30 19:12:14 +08:00
|
|
|
std::string filename_str(base::SysNSStringToUTF8(filename));
|
|
|
|
return electron::Browser::Get()->OpenFile(filename_str) ? YES : NO;
|
2013-05-30 16:03:10 +08:00
|
|
|
}
|
|
|
|
|
2020-05-28 22:53:33 +09:00
|
|
|
- (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication
|
|
|
|
hasVisibleWindows:(BOOL)flag {
|
2014-03-05 18:09:44 +08:00
|
|
|
electron::Browser* browser = electron::Browser::Get();
|
2020-05-28 22:53:33 +09:00
|
|
|
browser->Activate(static_cast<bool>(flag));
|
|
|
|
return flag;
|
2014-03-05 18:09:44 +08:00
|
|
|
}
|
|
|
|
|
2018-04-20 14:47:04 -04:00
|
|
|
- (BOOL)application:(NSApplication*)sender
|
|
|
|
continueUserActivity:(NSUserActivity*)userActivity
|
|
|
|
restorationHandler:
|
2018-09-24 07:41:17 -07:00
|
|
|
#ifdef MAC_OS_X_VERSION_10_14
|
|
|
|
(void (^)(NSArray<id<NSUserActivityRestoring>>* restorableObjects))
|
|
|
|
#else
|
|
|
|
(void (^)(NSArray* restorableObjects))
|
|
|
|
#endif
|
2019-02-25 18:21:57 +01:00
|
|
|
restorationHandler {
|
2016-04-29 17:37:01 -07:00
|
|
|
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
2021-07-13 16:21:33 -04:00
|
|
|
NSURL* url = userActivity.webpageURL;
|
2023-06-08 10:26:33 +02:00
|
|
|
NSDictionary* details = url ? @{@"webpageURL" : url.absoluteString} : @{};
|
2019-10-30 14:30:59 +09:00
|
|
|
if (!userActivity.userInfo)
|
2016-05-05 16:26:44 +09:00
|
|
|
return NO;
|
2016-04-29 17:37:01 -07:00
|
|
|
|
|
|
|
electron::Browser* browser = electron::Browser::Get();
|
2019-10-30 14:30:59 +09:00
|
|
|
return browser->ContinueUserActivity(
|
|
|
|
activity_type,
|
2022-06-22 23:28:41 -07:00
|
|
|
electron::NSDictionaryToValue(userActivity.userInfo),
|
|
|
|
electron::NSDictionaryToValue(details))
|
2019-10-30 14:30:59 +09:00
|
|
|
? YES
|
|
|
|
: NO;
|
2016-04-29 17:37:01 -07:00
|
|
|
}
|
|
|
|
|
2018-04-20 14:47:04 -04:00
|
|
|
- (BOOL)application:(NSApplication*)application
|
|
|
|
willContinueUserActivityWithType:(NSString*)userActivityType {
|
2017-06-26 16:14:44 -03:00
|
|
|
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
2017-09-14 16:12:34 +09:00
|
|
|
|
2017-06-26 16:14:44 -03:00
|
|
|
electron::Browser* browser = electron::Browser::Get();
|
|
|
|
return browser->WillContinueUserActivity(activity_type) ? YES : NO;
|
|
|
|
}
|
|
|
|
|
2018-04-20 14:47:04 -04:00
|
|
|
- (void)application:(NSApplication*)application
|
|
|
|
didFailToContinueUserActivityWithType:(NSString*)userActivityType
|
|
|
|
error:(NSError*)error {
|
2017-06-26 16:14:44 -03:00
|
|
|
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
2018-04-20 14:47:04 -04:00
|
|
|
std::string error_message(
|
2023-06-08 10:26:33 +02:00
|
|
|
base::SysNSStringToUTF8(error.localizedDescription));
|
2017-09-14 16:12:34 +09:00
|
|
|
|
2017-06-26 16:14:44 -03:00
|
|
|
electron::Browser* browser = electron::Browser::Get();
|
|
|
|
browser->DidFailToContinueUserActivity(activity_type, error_message);
|
|
|
|
}
|
|
|
|
|
2017-06-11 01:19:01 -07:00
|
|
|
- (IBAction)newWindowForTab:(id)sender {
|
|
|
|
electron::Browser::Get()->NewWindowForTab();
|
|
|
|
}
|
|
|
|
|
2022-07-12 08:38:49 -07:00
|
|
|
- (void)application:(NSApplication*)application
|
|
|
|
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
|
|
|
|
// https://stackoverflow.com/a/16411517
|
2023-06-08 10:26:33 +02:00
|
|
|
const char* token_data = static_cast<const char*>(deviceToken.bytes);
|
2022-07-12 08:38:49 -07:00
|
|
|
NSMutableString* token_string = [NSMutableString string];
|
2023-06-08 10:26:33 +02:00
|
|
|
for (NSUInteger i = 0; i < deviceToken.length; i++) {
|
2022-07-12 08:38:49 -07:00
|
|
|
[token_string appendFormat:@"%02.2hhX", token_data[i]];
|
|
|
|
}
|
|
|
|
// Resolve outstanding APNS promises created during registration attempts
|
|
|
|
electron::api::PushNotifications* push_notifications =
|
|
|
|
electron::api::PushNotifications::Get();
|
|
|
|
if (push_notifications) {
|
|
|
|
push_notifications->ResolveAPNSPromiseSetWithToken(
|
|
|
|
base::SysNSStringToUTF8(token_string));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)application:(NSApplication*)application
|
|
|
|
didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
|
|
|
|
std::string error_message(base::SysNSStringToUTF8(
|
2023-06-08 10:26:33 +02:00
|
|
|
[NSString stringWithFormat:@"%ld %@ %@", error.code, error.domain,
|
|
|
|
error.userInfo]));
|
2022-07-12 08:38:49 -07:00
|
|
|
electron::api::PushNotifications* push_notifications =
|
|
|
|
electron::api::PushNotifications::Get();
|
|
|
|
if (push_notifications) {
|
|
|
|
push_notifications->RejectAPNSPromiseSetWithError(error_message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)application:(NSApplication*)application
|
|
|
|
didReceiveRemoteNotification:(NSDictionary*)userInfo {
|
|
|
|
electron::api::PushNotifications* push_notifications =
|
|
|
|
electron::api::PushNotifications::Get();
|
|
|
|
if (push_notifications) {
|
|
|
|
electron::api::PushNotifications::Get()->OnDidReceiveAPNSNotification(
|
2022-07-13 12:22:17 +02:00
|
|
|
electron::NSDictionaryToValue(userInfo));
|
2022-07-12 08:38:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 10:22:58 -04:00
|
|
|
// This only has an effect on macOS 12+, and requests any state restoration
|
|
|
|
// archive to be created with secure encoding. See the article at
|
|
|
|
// https://sector7.computest.nl/post/2022-08-process-injection-breaking-all-macos-security-layers-with-a-single-vulnerability/
|
|
|
|
// for more details.
|
|
|
|
- (BOOL)applicationSupportsSecureRestorableState:(NSApplication*)app {
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2013-05-02 20:09:19 +08:00
|
|
|
@end
|