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

Unified 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, 2 months 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/app_controller_mac.mm
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 34736e6251be73809fade4cc03caf67b8cdb177b..10190585c2448d0443b078567865fc517dc733c6 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -106,6 +106,11 @@ NSString* NSPopoverDidShowNotification = @"NSPopoverDidShowNotification";
NSString* NSPopoverDidCloseNotification = @"NSPopoverDidCloseNotification";
#endif
+// How long we allow a workspace change notification to wait to be
+// associated with a dock activation. The animation lasts 250ms. See
+// applicationShouldHandleReopen:hasVisibleWindows:.
+static const int kWorkspaceChangeTimeoutMs = 500;
+
// True while AppController is calling chrome::NewEmptyWindow(). We need a
// global flag here, analogue to StartupBrowserCreator::InProcessStartup()
// because otherwise the SessionService will try to restore sessions when we
@@ -196,6 +201,7 @@ void RecordLastRunAppBundlePath() {
withReply:(NSAppleEventDescriptor*)reply;
- (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event;
- (void)windowLayeringDidChange:(NSNotification*)inNotification;
+- (void)activeSpaceDidChange:(NSNotification*)inNotification;
- (void)windowChangedToProfile:(Profile*)profile;
- (void)checkForAnyKeyWindows;
- (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount;
@@ -314,6 +320,13 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
object:nil];
}
+ // Register for space change notifications.
+ [[[NSWorkspace sharedWorkspace] notificationCenter]
+ addObserver:self
+ selector:@selector(activeSpaceDidChange:)
+ name:NSWorkspaceActiveSpaceDidChangeNotification
+ object:nil];
+
// Set up the command updater for when there are no windows open
[self initMenuState];
@@ -330,6 +343,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
[em removeEventHandlerForEventClass:'WWW!'
andEventID:'OURL'];
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
}
// (NSApplicationDelegate protocol) This is the Apple-approved place to override
@@ -556,6 +570,28 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
}
}
+- (void)activeSpaceDidChange:(NSNotification*)notify {
+ if (reopenTime_.is_null() ||
+ ![NSApp isActive] ||
+ (base::TimeTicks::Now() - reopenTime_).InMilliseconds() >
+ kWorkspaceChangeTimeoutMs) {
+ return;
+ }
+
+ // The last applicationShouldHandleReopen:hasVisibleWindows: call
+ // happened during a space change. Now that the change has
+ // completed, raise browser windows.
+ reopenTime_ = base::TimeTicks();
+ std::set<NSWindow*> browserWindows;
+ for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
+ Browser* browser = *iter;
+ browserWindows.insert(browser->window()->GetNativeWindow());
+ }
+ if (!browserWindows.empty()) {
+ ui::FocusWindowSet(browserWindows, false);
+ }
+}
+
// Called on Lion and later when a popover (e.g. dictionary) is shown.
- (void)popoverDidShow:(NSNotification*)notify {
hasPopover_ = YES;
@@ -1082,9 +1118,26 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
browserWindows.insert(browser->window()->GetNativeWindow());
}
if (!browserWindows.empty()) {
- ui::FocusWindowSet(browserWindows, false);
- // Return NO; we've done the unminimize, so AppKit shouldn't do
- // anything.
+ NSWindow* keyWindow = [NSApp keyWindow];
+ if (keyWindow && ![keyWindow isOnActiveSpace]) {
+ // The key window is not on the active space. We must be mid-animation
+ // for a space transition triggered by the dock. Delay the call to
+ // |ui::FocusWindowSet| until the transition completes. Otherwise, the
+ // wrong space's windows get raised, resulting in an off-screen key
+ // window. It does not work to |ui::FocusWindowSet| twice, once here
+ // and once in |activeSpaceDidChange:|, as that appears to break when
+ // the omnibox is focused.
+ //
+ // This check relies on OS X setting the key window to a window on the
+ // target space before calling this method.
+ //
+ // See http://crbug.com/309656.
+ reopenTime_ = base::TimeTicks::Now();
+ } else {
+ ui::FocusWindowSet(browserWindows, false);
+ }
+ // Return NO; we've done (or soon will do) the deminiaturize, so
+ // AppKit shouldn't do anything.
return NO;
}
}
« 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