Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: chrome/browser/app_controller_mac.mm

Issue 37253004: Mac: delay window raising until space transitions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Missing comma Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/app_controller_mac.h ('k') | ui/base/cocoa/focus_window_set.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/app_controller_mac.h ('k') | ui/base/cocoa/focus_window_set.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698