electron/shell/browser/mac/electron_application_delegate.mm
Charles Kerr aa23198ad8
chore: remove more unused #include calls (#43000)
* chore: in shell/renderer/renderer_client_base.h, remove include media/base/key_systems_support_registration.h

last use removed in c670e38b (##41610)

* chore: iwyu electron/fuses.h

* chore: iwyu media/base/video_frame.h

* chore: iwyu base/functional/callback.h

* chore: iwyu base/task/cancelable_task_tracker.h

* chore: iwyu shell/browser/draggable_region_provider.h

* chore: iwyu shell/browser/ui/inspectable_web_contents_view.h

* chore: iwyu ui/aura/window.h

* chore: iwyu ui/base/win/shell.h

* chore: iwyu ui/display/win/screen_win.h

* chore: iwyu ui/gfx/geometry/insets.h

* chore: iwyu ui/display/display.h

* chore: iwyu ui/gfx/geometry/skia_conversions.h

* chore: iwyu ui/gfx/geometry/rect_conversions.h

* chore: iwyu ui/gfx/geometry/point.h

* chore: iwyu ui/gfx/scoped_canvas.h

* chore: iwyu ui/gfx/image/image.h

* chore: iwyu ui/accessibility/ax_node_data.h

* chore: iwyu ui/views/animation/ink_drop_highlight.h

* chore: iwyu ui/gfx/font_list.h

* chore: iwyu ui/linux/nav_button_provider.h

* chore: iwyu shell/browser/ui/views/frameless_view.h

* chore: iwyu services/metrics/public/cpp/ukm_source_id.h

* chore: iwyu net/http/http_util.h

* chore: iwyu net/base/mime_util.h

* chore: iwyu content/public/common/content_client.h

* chore: iwyu <list>

* chore: iwyu <optional>

* chore: iwyu <memory>

* chore: iwyu base/files/file_path.h

* chore: iwyu ui/base/cursor/cursor.h

* chore: iwyu build/build_config.h

* chore: iwyu content/public/browser/web_contents.h

* chore: iwyu shell/browser/hid/hid_chooser_context.h

* chore: iwyu shell/common/platform_util.h

* chore: iwyu base/task/single_thread_task_runner.h

* chore: iwyu content/browser/renderer_host/render_widget_host_impl.h

* chore: iwyu content/public/browser/render_widget_host.h

* chore: iwyu shell/browser/electron_browser_context.h

* chore: iwyu content/public/browser/web_contents_observer.h

* chore: iwyu content/public/browser/render_frame_host.h

* chore: iwyu content/public/browser/media_stream_request.h

* chore: iwyu chrome/common/chrome_paths.h

* chore: iwyu chrome/browser/icon_manager.h

* chore: iwyu printing/print_settings.h

* chore: iwyu renderer/pepper_helper.h

* chore: iwyu shell/browser/api/process_metric.h

* chore: iwyu shell/browser/electron_browser_client.h

* chore: iwyu shell/browser/electron_browser_context.h

* chore: iwyu shell/browser/api/electron_api_session.h

* chore: iwyu shell/browser/api/electron_api_app.h

* chore: iwyu shell/browser/ui/views/client_frame_view_linux.h

* chore: iwyu shell/browser/native_window_views.h

* chore: iwyu base/win/windows_version.h

* chore: iwyu shell/common/electron_paths.h

* chore: iwyu content/public/common/content_switches.h

* chore: iwyu third_party/skia/include/core/SkRRect.h

* chore: iwyu third_party/skia/include/core/SkBitmap.h

* chore: iwyu third_party/skia

* chore: iwyu shell/browser/osr/osr_host_display_client.h

* chore: iwyu shell/browser/login_handler.h

* chore: iwyu shell/browser/javascript_environment.h

* chore: iwyu shell/browser/event_emitter_mixin.h

* fix: mac

* fix: mac

* chore: iwyu base/nix/xdg_util.h

* fix: win

* fix: win

* fix: win

* fix: win
2024-07-25 11:25:45 +02:00

216 lines
7.8 KiB
Text

// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#import "shell/browser/mac/electron_application_delegate.h"
#include <string>
#include "base/allocator/buildflags.h"
#include "base/allocator/partition_allocator/src/partition_alloc/shim/allocator_shim.h"
#include "base/functional/callback.h"
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
#include "shell/browser/api/electron_api_push_notifications.h"
#include "shell/browser/browser.h"
#include "shell/browser/mac/dict_util.h"
#import "shell/browser/mac/electron_application.h"
#import <UserNotifications/UserNotifications.h>
static NSDictionary* UNNotificationResponseToNSDictionary(
UNNotificationResponse* response) {
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;
}
@implementation ElectronApplicationDelegate {
ElectronMenuController* __strong menu_controller_;
}
- (void)setApplicationDockMenu:(electron::ElectronMenuModel*)model {
menu_controller_ = [[ElectronMenuController alloc] initWithModel:model
useDefaultAccelerator:NO];
}
- (void)willPowerOff:(NSNotification*)notify {
[[AtomApplication sharedApplication] willPowerOff:notify];
}
- (void)applicationWillFinishLaunching:(NSNotification*)notify {
// Don't add the "Enter Full Screen" menu item automatically.
[[NSUserDefaults standardUserDefaults]
setBool:NO
forKey:@"NSFullScreenMenuItemEverywhere"];
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(willPowerOff:)
name:NSWorkspaceWillPowerOffNotification
object:nil];
electron::Browser::Get()->WillFinishLaunching();
}
- (void)applicationDidFinishLaunching:(NSNotification*)notify {
NSObject* user_notification =
[notify userInfo][NSApplicationLaunchUserNotificationKey];
NSDictionary* notification_info = nil;
if (user_notification) {
if ([user_notification isKindOfClass:[NSUserNotification class]]) {
notification_info =
[static_cast<NSUserNotification*>(user_notification) userInfo];
} else {
notification_info = UNNotificationResponseToNSDictionary(
static_cast<UNNotificationResponse*>(user_notification));
}
}
NSAppleEventDescriptor* event =
NSAppleEventManager.sharedAppleEventManager.currentAppleEvent;
BOOL launched_as_login_item =
(event.eventID == kAEOpenApplication &&
[event paramDescriptorForKeyword:keyAEPropData].enumCodeValue ==
keyAELaunchedAsLogInItem);
electron::Browser::Get()->SetLaunchedAtLogin(launched_as_login_item);
electron::Browser::Get()->DidFinishLaunching(
electron::NSDictionaryToValue(notification_info));
}
- (void)applicationDidBecomeActive:(NSNotification*)notification {
electron::Browser::Get()->DidBecomeActive();
}
- (void)applicationDidResignActive:(NSNotification*)notification {
electron::Browser::Get()->DidResignActive();
}
- (NSMenu*)applicationDockMenu:(NSApplication*)sender {
return menu_controller_ ? menu_controller_.menu : nil;
}
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename {
std::string filename_str(base::SysNSStringToUTF8(filename));
return electron::Browser::Get()->OpenFile(filename_str) ? YES : NO;
}
- (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication
hasVisibleWindows:(BOOL)flag {
electron::Browser* browser = electron::Browser::Get();
browser->Activate(static_cast<bool>(flag));
return flag;
}
- (BOOL)application:(NSApplication*)sender
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:
#ifdef MAC_OS_X_VERSION_10_14
(void (^)(NSArray<id<NSUserActivityRestoring>>* restorableObjects))
#else
(void (^)(NSArray* restorableObjects))
#endif
restorationHandler {
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
NSURL* url = userActivity.webpageURL;
NSDictionary* details = url ? @{@"webpageURL" : url.absoluteString} : @{};
if (!userActivity.userInfo)
return NO;
electron::Browser* browser = electron::Browser::Get();
return browser->ContinueUserActivity(
activity_type,
electron::NSDictionaryToValue(userActivity.userInfo),
electron::NSDictionaryToValue(details))
? YES
: NO;
}
- (BOOL)application:(NSApplication*)application
willContinueUserActivityWithType:(NSString*)userActivityType {
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
electron::Browser* browser = electron::Browser::Get();
return browser->WillContinueUserActivity(activity_type) ? YES : NO;
}
- (void)application:(NSApplication*)application
didFailToContinueUserActivityWithType:(NSString*)userActivityType
error:(NSError*)error {
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
std::string error_message(
base::SysNSStringToUTF8(error.localizedDescription));
electron::Browser* browser = electron::Browser::Get();
browser->DidFailToContinueUserActivity(activity_type, error_message);
}
- (IBAction)newWindowForTab:(id)sender {
electron::Browser::Get()->NewWindowForTab();
}
- (void)application:(NSApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
// https://stackoverflow.com/a/16411517
const char* token_data = static_cast<const char*>(deviceToken.bytes);
NSMutableString* token_string = [NSMutableString string];
for (NSUInteger i = 0; i < deviceToken.length; i++) {
[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(
[NSString stringWithFormat:@"%ld %@ %@", error.code, error.domain,
error.userInfo]));
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(
electron::NSDictionaryToValue(userInfo));
}
}
// 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;
}
@end