| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/app_controller_mac.h" | 5 #import "chrome/browser/app_controller_mac.h" |
| 6 | 6 |
| 7 #include "apps/app_shim/app_shim_mac.h" | 7 #include "apps/app_shim/app_shim_mac.h" |
| 8 #include "apps/app_shim/extension_app_shim_handler_mac.h" | 8 #include "apps/app_shim/extension_app_shim_handler_mac.h" |
| 9 #include "apps/shell_window_registry.h" | 9 #include "apps/shell_window_registry.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 namespace { | 100 namespace { |
| 101 | 101 |
| 102 // Declare notification names from the 10.7 SDK. | 102 // Declare notification names from the 10.7 SDK. |
| 103 #if !defined(MAC_OS_X_VERSION_10_7) || \ | 103 #if !defined(MAC_OS_X_VERSION_10_7) || \ |
| 104 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | 104 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 |
| 105 NSString* NSPopoverDidShowNotification = @"NSPopoverDidShowNotification"; | 105 NSString* NSPopoverDidShowNotification = @"NSPopoverDidShowNotification"; |
| 106 NSString* NSPopoverDidCloseNotification = @"NSPopoverDidCloseNotification"; | 106 NSString* NSPopoverDidCloseNotification = @"NSPopoverDidCloseNotification"; |
| 107 #endif | 107 #endif |
| 108 | 108 |
| 109 // How long we allow a workspace change notification to wait to be |
| 110 // associated with a dock activation. The animation lasts 250ms. See |
| 111 // applicationShouldHandleReopen:hasVisibleWindows:. |
| 112 static const int kWorkspaceChangeTimeoutMs = 500; |
| 113 |
| 109 // True while AppController is calling chrome::NewEmptyWindow(). We need a | 114 // True while AppController is calling chrome::NewEmptyWindow(). We need a |
| 110 // global flag here, analogue to StartupBrowserCreator::InProcessStartup() | 115 // global flag here, analogue to StartupBrowserCreator::InProcessStartup() |
| 111 // because otherwise the SessionService will try to restore sessions when we | 116 // because otherwise the SessionService will try to restore sessions when we |
| 112 // make a new window while there are no other active windows. | 117 // make a new window while there are no other active windows. |
| 113 bool g_is_opening_new_window = false; | 118 bool g_is_opening_new_window = false; |
| 114 | 119 |
| 115 // Activates a browser window having the given profile (the last one active) if | 120 // Activates a browser window having the given profile (the last one active) if |
| 116 // possible and returns a pointer to the activate |Browser| or NULL if this was | 121 // possible and returns a pointer to the activate |Browser| or NULL if this was |
| 117 // not possible. If the last active browser is minimized (in particular, if | 122 // not possible. If the last active browser is minimized (in particular, if |
| 118 // there are only minimized windows), it will unminimize it. | 123 // there are only minimized windows), it will unminimize it. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 @interface AppController (Private) | 194 @interface AppController (Private) |
| 190 - (void)initMenuState; | 195 - (void)initMenuState; |
| 191 - (void)initProfileMenu; | 196 - (void)initProfileMenu; |
| 192 - (void)updateConfirmToQuitPrefMenuItem:(NSMenuItem*)item; | 197 - (void)updateConfirmToQuitPrefMenuItem:(NSMenuItem*)item; |
| 193 - (void)registerServicesMenuTypesTo:(NSApplication*)app; | 198 - (void)registerServicesMenuTypesTo:(NSApplication*)app; |
| 194 - (void)openUrls:(const std::vector<GURL>&)urls; | 199 - (void)openUrls:(const std::vector<GURL>&)urls; |
| 195 - (void)getUrl:(NSAppleEventDescriptor*)event | 200 - (void)getUrl:(NSAppleEventDescriptor*)event |
| 196 withReply:(NSAppleEventDescriptor*)reply; | 201 withReply:(NSAppleEventDescriptor*)reply; |
| 197 - (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event; | 202 - (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event; |
| 198 - (void)windowLayeringDidChange:(NSNotification*)inNotification; | 203 - (void)windowLayeringDidChange:(NSNotification*)inNotification; |
| 204 - (void)activeSpaceDidChange:(NSNotification*)inNotification; |
| 199 - (void)windowChangedToProfile:(Profile*)profile; | 205 - (void)windowChangedToProfile:(Profile*)profile; |
| 200 - (void)checkForAnyKeyWindows; | 206 - (void)checkForAnyKeyWindows; |
| 201 - (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount; | 207 - (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount; |
| 202 - (BOOL)shouldQuitWithInProgressDownloads; | 208 - (BOOL)shouldQuitWithInProgressDownloads; |
| 203 - (void)executeApplication:(id)sender; | 209 - (void)executeApplication:(id)sender; |
| 204 - (void)profileWasRemoved:(const base::FilePath&)profilePath; | 210 - (void)profileWasRemoved:(const base::FilePath&)profilePath; |
| 205 @end | 211 @end |
| 206 | 212 |
| 207 class AppControllerProfileObserver : public ProfileInfoCacheObserver { | 213 class AppControllerProfileObserver : public ProfileInfoCacheObserver { |
| 208 public: | 214 public: |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 selector:@selector(popoverDidShow:) | 313 selector:@selector(popoverDidShow:) |
| 308 name:NSPopoverDidShowNotification | 314 name:NSPopoverDidShowNotification |
| 309 object:nil]; | 315 object:nil]; |
| 310 [notificationCenter | 316 [notificationCenter |
| 311 addObserver:self | 317 addObserver:self |
| 312 selector:@selector(popoverDidClose:) | 318 selector:@selector(popoverDidClose:) |
| 313 name:NSPopoverDidCloseNotification | 319 name:NSPopoverDidCloseNotification |
| 314 object:nil]; | 320 object:nil]; |
| 315 } | 321 } |
| 316 | 322 |
| 323 // Register for space change notifications. |
| 324 [[[NSWorkspace sharedWorkspace] notificationCenter] |
| 325 addObserver:self |
| 326 selector:@selector(activeSpaceDidChange:) |
| 327 name:NSWorkspaceActiveSpaceDidChangeNotification |
| 328 object:nil]; |
| 329 |
| 317 // Set up the command updater for when there are no windows open | 330 // Set up the command updater for when there are no windows open |
| 318 [self initMenuState]; | 331 [self initMenuState]; |
| 319 | 332 |
| 320 // Initialize the Profile menu. | 333 // Initialize the Profile menu. |
| 321 [self initProfileMenu]; | 334 [self initProfileMenu]; |
| 322 } | 335 } |
| 323 | 336 |
| 324 - (void)unregisterEventHandlers { | 337 - (void)unregisterEventHandlers { |
| 325 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 338 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| 326 [em removeEventHandlerForEventClass:kInternetEventClass | 339 [em removeEventHandlerForEventClass:kInternetEventClass |
| 327 andEventID:kAEGetURL]; | 340 andEventID:kAEGetURL]; |
| 328 [em removeEventHandlerForEventClass:cloud_print::kAECloudPrintClass | 341 [em removeEventHandlerForEventClass:cloud_print::kAECloudPrintClass |
| 329 andEventID:cloud_print::kAECloudPrintClass]; | 342 andEventID:cloud_print::kAECloudPrintClass]; |
| 330 [em removeEventHandlerForEventClass:'WWW!' | 343 [em removeEventHandlerForEventClass:'WWW!' |
| 331 andEventID:'OURL']; | 344 andEventID:'OURL']; |
| 332 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 345 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 346 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; |
| 333 } | 347 } |
| 334 | 348 |
| 335 // (NSApplicationDelegate protocol) This is the Apple-approved place to override | 349 // (NSApplicationDelegate protocol) This is the Apple-approved place to override |
| 336 // the default handlers. | 350 // the default handlers. |
| 337 - (void)applicationWillFinishLaunching:(NSNotification*)notification { | 351 - (void)applicationWillFinishLaunching:(NSNotification*)notification { |
| 338 // Nothing here right now. | 352 // Nothing here right now. |
| 339 } | 353 } |
| 340 | 354 |
| 341 - (BOOL)tryToTerminateApplication:(NSApplication*)app { | 355 - (BOOL)tryToTerminateApplication:(NSApplication*)app { |
| 342 // Check for in-process downloads, and prompt the user if they really want | 356 // Check for in-process downloads, and prompt the user if they really want |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 [windowController isKindOfClass:[BrowserWindowController class]]) { | 563 [windowController isKindOfClass:[BrowserWindowController class]]) { |
| 550 // If the profile is incognito, use the original profile. | 564 // If the profile is incognito, use the original profile. |
| 551 Profile* newProfile = [windowController profile]->GetOriginalProfile(); | 565 Profile* newProfile = [windowController profile]->GetOriginalProfile(); |
| 552 [self windowChangedToProfile:newProfile]; | 566 [self windowChangedToProfile:newProfile]; |
| 553 } else if (chrome::GetTotalBrowserCount() == 0) { | 567 } else if (chrome::GetTotalBrowserCount() == 0) { |
| 554 [self windowChangedToProfile: | 568 [self windowChangedToProfile: |
| 555 g_browser_process->profile_manager()->GetLastUsedProfile()]; | 569 g_browser_process->profile_manager()->GetLastUsedProfile()]; |
| 556 } | 570 } |
| 557 } | 571 } |
| 558 | 572 |
| 573 - (void)activeSpaceDidChange:(NSNotification*)notify { |
| 574 if (reopenTime_.is_null() || |
| 575 ![NSApp isActive] || |
| 576 (base::TimeTicks::Now() - reopenTime_).InMilliseconds() > |
| 577 kWorkspaceChangeTimeoutMs) { |
| 578 return; |
| 579 } |
| 580 |
| 581 // The last applicationShouldHandleReopen:hasVisibleWindows: call |
| 582 // happened during a space change. Now that the change has |
| 583 // completed, raise browser windows. |
| 584 reopenTime_ = base::TimeTicks(); |
| 585 std::set<NSWindow*> browserWindows; |
| 586 for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) { |
| 587 Browser* browser = *iter; |
| 588 browserWindows.insert(browser->window()->GetNativeWindow()); |
| 589 } |
| 590 if (!browserWindows.empty()) { |
| 591 ui::FocusWindowSet(browserWindows, false); |
| 592 } |
| 593 } |
| 594 |
| 559 // Called on Lion and later when a popover (e.g. dictionary) is shown. | 595 // Called on Lion and later when a popover (e.g. dictionary) is shown. |
| 560 - (void)popoverDidShow:(NSNotification*)notify { | 596 - (void)popoverDidShow:(NSNotification*)notify { |
| 561 hasPopover_ = YES; | 597 hasPopover_ = YES; |
| 562 [self fixCloseMenuItemKeyEquivalents]; | 598 [self fixCloseMenuItemKeyEquivalents]; |
| 563 } | 599 } |
| 564 | 600 |
| 565 // Called on Lion and later when a popover (e.g. dictionary) is closed. | 601 // Called on Lion and later when a popover (e.g. dictionary) is closed. |
| 566 - (void)popoverDidClose:(NSNotification*)notify { | 602 - (void)popoverDidClose:(NSNotification*)notify { |
| 567 hasPopover_ = NO; | 603 hasPopover_ = NO; |
| 568 [self fixCloseMenuItemKeyEquivalents]; | 604 [self fixCloseMenuItemKeyEquivalents]; |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 // recently minimized window if no windows in the set are visible. | 1111 // recently minimized window if no windows in the set are visible. |
| 1076 // If there are any, return here. Otherwise, the windows are panels or | 1112 // If there are any, return here. Otherwise, the windows are panels or |
| 1077 // notifications so we still need to open a new window. | 1113 // notifications so we still need to open a new window. |
| 1078 if (hasVisibleWindows) { | 1114 if (hasVisibleWindows) { |
| 1079 std::set<NSWindow*> browserWindows; | 1115 std::set<NSWindow*> browserWindows; |
| 1080 for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) { | 1116 for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) { |
| 1081 Browser* browser = *iter; | 1117 Browser* browser = *iter; |
| 1082 browserWindows.insert(browser->window()->GetNativeWindow()); | 1118 browserWindows.insert(browser->window()->GetNativeWindow()); |
| 1083 } | 1119 } |
| 1084 if (!browserWindows.empty()) { | 1120 if (!browserWindows.empty()) { |
| 1085 ui::FocusWindowSet(browserWindows, false); | 1121 NSWindow* keyWindow = [NSApp keyWindow]; |
| 1086 // Return NO; we've done the unminimize, so AppKit shouldn't do | 1122 if (keyWindow && ![keyWindow isOnActiveSpace]) { |
| 1087 // anything. | 1123 // The key window is not on the active space. We must be mid-animation |
| 1124 // for a space transition triggered by the dock. Delay the call to |
| 1125 // |ui::FocusWindowSet| until the transition completes. Otherwise, the |
| 1126 // wrong space's windows get raised, resulting in an off-screen key |
| 1127 // window. It does not work to |ui::FocusWindowSet| twice, once here |
| 1128 // and once in |activeSpaceDidChange:|, as that appears to break when |
| 1129 // the omnibox is focused. |
| 1130 // |
| 1131 // This check relies on OS X setting the key window to a window on the |
| 1132 // target space before calling this method. |
| 1133 // |
| 1134 // See http://crbug.com/309656. |
| 1135 reopenTime_ = base::TimeTicks::Now(); |
| 1136 } else { |
| 1137 ui::FocusWindowSet(browserWindows, false); |
| 1138 } |
| 1139 // Return NO; we've done (or soon will do) the deminiaturize, so |
| 1140 // AppKit shouldn't do anything. |
| 1088 return NO; | 1141 return NO; |
| 1089 } | 1142 } |
| 1090 } | 1143 } |
| 1091 | 1144 |
| 1092 // If launched as a hidden login item (due to installation of a persistent app | 1145 // If launched as a hidden login item (due to installation of a persistent app |
| 1093 // or by the user, for example in System Preferences->Accounts->Login Items), | 1146 // or by the user, for example in System Preferences->Accounts->Login Items), |
| 1094 // allow session to be restored first time the user clicks on a Dock icon. | 1147 // allow session to be restored first time the user clicks on a Dock icon. |
| 1095 // Normally, it'd just open a new empty page. | 1148 // Normally, it'd just open a new empty page. |
| 1096 { | 1149 { |
| 1097 static BOOL doneOnce = NO; | 1150 static BOOL doneOnce = NO; |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 | 1475 |
| 1423 //--------------------------------------------------------------------------- | 1476 //--------------------------------------------------------------------------- |
| 1424 | 1477 |
| 1425 namespace app_controller_mac { | 1478 namespace app_controller_mac { |
| 1426 | 1479 |
| 1427 bool IsOpeningNewWindow() { | 1480 bool IsOpeningNewWindow() { |
| 1428 return g_is_opening_new_window; | 1481 return g_is_opening_new_window; |
| 1429 } | 1482 } |
| 1430 | 1483 |
| 1431 } // namespace app_controller_mac | 1484 } // namespace app_controller_mac |
| OLD | NEW |