atom_application_delegate.mm 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #import "atom/browser/mac/atom_application_delegate.h"
  5. #include "atom/browser/browser.h"
  6. #import "atom/browser/mac/atom_application.h"
  7. #include "atom/browser/mac/dict_util.h"
  8. #include "base/allocator/allocator_shim.h"
  9. #include "base/allocator/features.h"
  10. #include "base/mac/mac_util.h"
  11. #include "base/mac/scoped_objc_class_swizzler.h"
  12. #include "base/strings/sys_string_conversions.h"
  13. #include "base/values.h"
  14. #if BUILDFLAG(USE_ALLOCATOR_SHIM)
  15. // On macOS 10.12, the IME system attempts to allocate a 2^64 size buffer,
  16. // which would typically cause an OOM crash. To avoid this, the problematic
  17. // method is swizzled out and the make-OOM-fatal bit is disabled for the
  18. // duration of the original call. https://crbug.com/654695
  19. static base::mac::ScopedObjCClassSwizzler* g_swizzle_imk_input_session;
  20. @interface OOMDisabledIMKInputSession : NSObject
  21. @end
  22. @implementation OOMDisabledIMKInputSession
  23. - (void)_coreAttributesFromRange:(NSRange)range
  24. whichAttributes:(long long)attributes
  25. completionHandler:(void (^)(void))block {
  26. // The allocator flag is per-process, so other threads may temporarily
  27. // not have fatal OOM occur while this method executes, but it is better
  28. // than crashing when using IME.
  29. base::allocator::SetCallNewHandlerOnMallocFailure(false);
  30. g_swizzle_imk_input_session->GetOriginalImplementation()(self, _cmd, range,
  31. attributes, block);
  32. base::allocator::SetCallNewHandlerOnMallocFailure(true);
  33. }
  34. @end
  35. #endif // BUILDFLAG(USE_ALLOCATOR_SHIM)
  36. @implementation AtomApplicationDelegate
  37. - (void)setApplicationDockMenu:(atom::AtomMenuModel*)model {
  38. menu_controller_.reset([[AtomMenuController alloc] initWithModel:model
  39. useDefaultAccelerator:NO]);
  40. }
  41. - (void)applicationWillFinishLaunching:(NSNotification*)notify {
  42. // Don't add the "Enter Full Screen" menu item automatically.
  43. [[NSUserDefaults standardUserDefaults]
  44. setBool:NO
  45. forKey:@"NSFullScreenMenuItemEverywhere"];
  46. atom::Browser::Get()->WillFinishLaunching();
  47. }
  48. - (void)applicationDidFinishLaunching:(NSNotification*)notify {
  49. NSUserNotification* user_notification =
  50. [notify userInfo][(id) @"NSApplicationLaunchUserNotificationKey"];
  51. if (user_notification.userInfo != nil) {
  52. std::unique_ptr<base::DictionaryValue> launch_info =
  53. atom::NSDictionaryToDictionaryValue(user_notification.userInfo);
  54. atom::Browser::Get()->DidFinishLaunching(*launch_info);
  55. } else {
  56. std::unique_ptr<base::DictionaryValue> empty_info(
  57. new base::DictionaryValue);
  58. atom::Browser::Get()->DidFinishLaunching(*empty_info);
  59. }
  60. #if BUILDFLAG(USE_ALLOCATOR_SHIM)
  61. // Disable fatal OOM to hack around an OS bug https://crbug.com/654695.
  62. if (base::mac::IsOS10_12()) {
  63. g_swizzle_imk_input_session = new base::mac::ScopedObjCClassSwizzler(
  64. NSClassFromString(@"IMKInputSession"),
  65. [OOMDisabledIMKInputSession class],
  66. @selector(_coreAttributesFromRange:whichAttributes:completionHandler:));
  67. }
  68. #endif
  69. }
  70. - (NSMenu*)applicationDockMenu:(NSApplication*)sender {
  71. if (menu_controller_)
  72. return [menu_controller_ menu];
  73. else
  74. return nil;
  75. }
  76. - (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename {
  77. std::string filename_str(base::SysNSStringToUTF8(filename));
  78. return atom::Browser::Get()->OpenFile(filename_str) ? YES : NO;
  79. }
  80. - (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication
  81. hasVisibleWindows:(BOOL)flag {
  82. atom::Browser* browser = atom::Browser::Get();
  83. browser->Activate(static_cast<bool>(flag));
  84. return flag;
  85. }
  86. - (BOOL)application:(NSApplication*)sender
  87. continueUserActivity:(NSUserActivity*)userActivity
  88. restorationHandler:
  89. (void (^)(NSArray* restorableObjects))restorationHandler
  90. API_AVAILABLE(macosx(10.10)) {
  91. std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
  92. std::unique_ptr<base::DictionaryValue> user_info =
  93. atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
  94. if (!user_info)
  95. return NO;
  96. atom::Browser* browser = atom::Browser::Get();
  97. return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
  98. }
  99. - (BOOL)application:(NSApplication*)application
  100. willContinueUserActivityWithType:(NSString*)userActivityType {
  101. std::string activity_type(base::SysNSStringToUTF8(userActivityType));
  102. atom::Browser* browser = atom::Browser::Get();
  103. return browser->WillContinueUserActivity(activity_type) ? YES : NO;
  104. }
  105. - (void)application:(NSApplication*)application
  106. didFailToContinueUserActivityWithType:(NSString*)userActivityType
  107. error:(NSError*)error {
  108. std::string activity_type(base::SysNSStringToUTF8(userActivityType));
  109. std::string error_message(
  110. base::SysNSStringToUTF8([error localizedDescription]));
  111. atom::Browser* browser = atom::Browser::Get();
  112. browser->DidFailToContinueUserActivity(activity_type, error_message);
  113. }
  114. - (IBAction)newWindowForTab:(id)sender {
  115. atom::Browser::Get()->NewWindowForTab();
  116. }
  117. @end