diff options
author | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-21 16:15:49 +0000 |
---|---|---|
committer | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-21 16:15:49 +0000 |
commit | d65b735d987b4098074fecbd9fd910642457c3da (patch) | |
tree | 088823c90ed2d1205b5ac6d43e816edb92aeaeca /chrome/browser/cocoa | |
parent | af1654c383cddf88f5bcade6949f96a90c3f1790 (diff) | |
download | chromium_src-d65b735d987b4098074fecbd9fd910642457c3da.zip chromium_src-d65b735d987b4098074fecbd9fd910642457c3da.tar.gz chromium_src-d65b735d987b4098074fecbd9fd910642457c3da.tar.bz2 |
[Mac] Explicitly set Space when existing full screen
If a user moves the full screen window to a different space they get snapped back to the original space when they exit full screen.
The problem is that internally the full screen window is a different window than the normal browser window. This means that any changes the user makes to the full screen window aren't reflected on the normal browser window.
The correct fix for this bug is to create a new browser window when the user exits full screen. This new window would then be on the correct space. This would require a fairly large architectural change to the BrowserWindowController class.
My proposed fix is much simpler. When exiting full screen we simply move the normal browser window to the Space that the full screen window is on.
Original review at: http://codereview.chromium.org/3345005/show
Patch by Sailesh Agrawal <fnepal@gmail.com>.
BUG=41693
TEST=Moved the full screen window to a different Space. Verified that exiting full screen didn't change the active Space.
Review URL: http://codereview.chromium.org/3386015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60063 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/nswindow_additions.h | 25 | ||||
-rw-r--r-- | chrome/browser/cocoa/nswindow_additions.mm | 104 |
3 files changed, 135 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 899eecd..bdec3b6 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -33,6 +33,7 @@ #import "chrome/browser/cocoa/fullscreen_window.h" #import "chrome/browser/cocoa/infobar_container_controller.h" #import "chrome/browser/cocoa/location_bar/autocomplete_text_field_editor.h" +#import "chrome/browser/cocoa/nswindow_additions.h" #import "chrome/browser/cocoa/sad_tab_controller.h" #import "chrome/browser/cocoa/sidebar_controller.h" #import "chrome/browser/cocoa/status_bubble_mac.h" @@ -1792,6 +1793,11 @@ willAnimateFromState:(bookmarks::VisualState)oldState DCHECK(savedRegularWindow_); destWindow = [savedRegularWindow_ autorelease]; savedRegularWindow_ = nil; + + CGSWorkspaceID workspace; + if ([window cr_workspace:&workspace]) { + [destWindow cr_moveToWorkspace:workspace]; + } } DCHECK(destWindow); diff --git a/chrome/browser/cocoa/nswindow_additions.h b/chrome/browser/cocoa/nswindow_additions.h new file mode 100644 index 0000000..69ed983 --- /dev/null +++ b/chrome/browser/cocoa/nswindow_additions.h @@ -0,0 +1,25 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_NSWINDOW_ADDITIONS_H_ +#define CHROME_BROWSER_COCOA_NSWINDOW_ADDITIONS_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +// ID of a Space. Starts at 1. +typedef int CGSWorkspaceID; + +@interface NSWindow(ChromeAdditions) + +// Gets the Space that the window is currently on. YES on success, NO on +// failure. +- (BOOL)cr_workspace:(CGSWorkspaceID*)outWorkspace; + +// Moves the window to the given Space. YES on success, NO on failure. +- (BOOL)cr_moveToWorkspace:(CGSWorkspaceID)workspace; + +@end + +#endif // CHROME_BROWSER_COCOA_NSWINDOW_ADDITIONS_H_ diff --git a/chrome/browser/cocoa/nswindow_additions.mm b/chrome/browser/cocoa/nswindow_additions.mm new file mode 100644 index 0000000..40da38f --- /dev/null +++ b/chrome/browser/cocoa/nswindow_additions.mm @@ -0,0 +1,104 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/nswindow_additions.h" + +#include <dlfcn.h> + +#include "base/logging.h" + +typedef void* CGSConnectionID; +typedef int CGSWindowID; +typedef int CGSError; +typedef int CGSWorkspaceID; + +// These are private APIs we look up at run time. +typedef CGSConnectionID (*CGSDefaultConnectionFunc)(void); +typedef CGSError (*CGSGetWindowWorkspaceFunc)(const CGSConnectionID cid, + CGSWindowID wid, + CGSWorkspaceID* workspace); +typedef CGSError (*CGSMoveWorkspaceWindowListFunc)(const CGSConnectionID cid, + CGSWindowID* wids, + int count, + CGSWorkspaceID workspace); + +static CGSDefaultConnectionFunc sCGSDefaultConnection; +static CGSGetWindowWorkspaceFunc sCGSGetWindowWorkspace; +static CGSMoveWorkspaceWindowListFunc sCGSMoveWorkspaceWindowList; + +@implementation NSWindow(ChromeAdditions) + +// Looks up private Spaces APIs using dlsym. +- (BOOL)cr_initializeWorkspaceAPIs { + static BOOL shouldInitialize = YES; + if (shouldInitialize) { + shouldInitialize = NO; + + NSBundle* coreGraphicsBundle = + [NSBundle bundleWithIdentifier:@"com.apple.CoreGraphics"]; + NSString* coreGraphicsPath = [[coreGraphicsBundle bundlePath] + stringByAppendingPathComponent:@"CoreGraphics"]; + void* coreGraphicsLibrary = dlopen([coreGraphicsPath UTF8String], + RTLD_GLOBAL | RTLD_LAZY); + + if (coreGraphicsLibrary) { + sCGSDefaultConnection = + (CGSDefaultConnectionFunc)dlsym(coreGraphicsLibrary, + "_CGSDefaultConnection"); + if (!sCGSDefaultConnection) { + LOG(ERROR) << "Failed to lookup _CGSDefaultConnection API" << dlerror(); + } + sCGSGetWindowWorkspace = + (CGSGetWindowWorkspaceFunc)dlsym(coreGraphicsLibrary, + "CGSGetWindowWorkspace"); + if (!sCGSGetWindowWorkspace) { + LOG(ERROR) << "Failed to lookup CGSGetWindowWorkspace API" << dlerror(); + } + sCGSMoveWorkspaceWindowList = + (CGSMoveWorkspaceWindowListFunc)dlsym(coreGraphicsLibrary, + "CGSMoveWorkspaceWindowList"); + if (!sCGSMoveWorkspaceWindowList) { + LOG(ERROR) << "Failed to lookup CGSMoveWorkspaceWindowList API" + << dlerror(); + } + } else { + LOG(ERROR) << "Failed to load CoreGraphics lib" << dlerror(); + } + } + + return sCGSDefaultConnection != NULL && + sCGSGetWindowWorkspace != NULL && + sCGSMoveWorkspaceWindowList != NULL; +} + +- (BOOL)cr_workspace:(CGSWorkspaceID*)outWorkspace { + if (![self cr_initializeWorkspaceAPIs]) { + return NO; + } + + // If this ASSERT fails then consider using CGSDefaultConnectionForThread() + // instead of CGSDefaultConnection(). + DCHECK([NSThread isMainThread]); + CGSConnectionID cid = sCGSDefaultConnection(); + CGSWindowID wid = [self windowNumber]; + CGSError err = sCGSGetWindowWorkspace(cid, wid, outWorkspace); + return err == 0; +} + +- (BOOL)cr_moveToWorkspace:(CGSWorkspaceID)workspace { + if (![self cr_initializeWorkspaceAPIs]) { + return NO; + } + + // If this ASSERT fails then consider using CGSDefaultConnectionForThread() + // instead of CGSDefaultConnection(). + DCHECK([NSThread isMainThread]); + CGSConnectionID cid = sCGSDefaultConnection(); + CGSWindowID wid = [self windowNumber]; + // CGSSetWorkspaceForWindow doesn't seem to work for some reason. + CGSError err = sCGSMoveWorkspaceWindowList(cid, &wid, 1, workspace); + return err == 0; +} + +@end |