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 |