diff options
33 files changed, 953 insertions, 390 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index 4a83ffe..5cd38a9 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h @@ -59,6 +59,7 @@ #define IDC_TABPOSE 34036 #define IDC_COMPACT_NAVBAR 34037 #define IDC_DEBUG_FRAME_TOGGLE 34038 +#define IDC_PRESENTATION_MODE 34039 // Page-related commands #define IDC_BOOKMARK_PAGE 35000 diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 1ba0402..df8df69 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -10048,6 +10048,12 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_EXIT_FULLSCREEN_MAC" desc="The Mac menu item to leave fullscreen mode in the view menu and also in the app menu."> Exit Full Screen </message> + <message name="IDS_ENTER_PRESENTATION_MAC" desc="The Mac menu item to go into presentation mode in the view menu."> + Enter Presentation Mode + </message> + <message name="IDS_EXIT_PRESENTATION_MAC" desc="The Mac menu item to leave presentation mode in the view menu."> + Exit Presentation Mode + </message> <message name="IDS_TEXT_BIGGER_MAC" desc="The Mac menu item to zoom in on the page in the view menu."> Zoom In </message> diff --git a/chrome/app/nibs/MainMenu.xib b/chrome/app/nibs/MainMenu.xib index 781414e..a1de814 100644 --- a/chrome/app/nibs/MainMenu.xib +++ b/chrome/app/nibs/MainMenu.xib @@ -2,9 +2,9 @@ <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <data> <int key="IBDocument.SystemTarget">1050</int> - <string key="IBDocument.SystemVersion">10J869</string> + <string key="IBDocument.SystemVersion">10K540</string> <string key="IBDocument.InterfaceBuilderVersion">851</string> - <string key="IBDocument.AppKitVersion">1038.35</string> + <string key="IBDocument.AppKitVersion">1038.36</string> <string key="IBDocument.HIToolboxVersion">461.00</string> <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -733,12 +733,22 @@ </object> <object class="NSMenuItem" id="530225222"> <reference key="NSMenu" ref="466310130"/> - <string key="NSTitle">^IDS_ENTER_FULLSCREEN_MAC</string> + <string key="NSTitle">^IDS_ENTER_PRESENTATION_MAC</string> <string key="NSKeyEquiv">F</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="353210768"/> <reference key="NSMixedImage" ref="549394948"/> + <int key="NSTag">34039</int> + </object> + <object class="NSMenuItem" id="210963491"> + <reference key="NSMenu" ref="466310130"/> + <string key="NSTitle">^IDS_ENTER_FULLSCREEN_MAC</string> + <string key="NSKeyEquiv">f</string> + <int key="NSKeyEquivModMask">1310720</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> <int key="NSTag">34030</int> </object> <object class="NSMenuItem" id="577314768"> @@ -1825,6 +1835,14 @@ </object> <int key="connectionID">690</int> </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="210963491"/> + </object> + <int key="connectionID">693</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -2292,6 +2310,7 @@ <reference ref="350076160"/> <reference ref="577314768"/> <reference ref="902861825"/> + <reference ref="210963491"/> </object> <reference key="parent" ref="586577488"/> </object> @@ -2705,6 +2724,11 @@ <reference key="object" ref="657848419"/> <reference key="parent" ref="649796088"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">692</int> + <reference key="object" ref="210963491"/> + <reference key="parent" ref="466310130"/> + </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> @@ -2902,6 +2926,7 @@ <string>689.IBPluginDependency</string> <string>689.ImportedFromIB2</string> <string>691.IBPluginDependency</string> + <string>692.IBPluginDependency</string> <string>72.IBPluginDependency</string> <string>72.ImportedFromIB2</string> <string>73.IBPluginDependency</string> @@ -3119,6 +3144,7 @@ <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> @@ -3158,7 +3184,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">691</int> + <int key="maxID">693</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index dab9d8a..952317d 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -66,6 +66,10 @@ #include "content/browser/renderer_host/browser_render_process_host.h" #include "content/browser/ssl/ssl_manager.h" +#if defined(OS_MACOSX) +#include "chrome/browser/ui/cocoa/presentation_mode_prefs.h" +#endif + #if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port #include "chrome/browser/ui/views/browser_actions_container.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -179,6 +183,9 @@ void RegisterUserPrefs(PrefService* user_prefs) { NetPrefObserver::RegisterPrefs(user_prefs); ProtocolHandlerRegistry::RegisterPrefs(user_prefs); FirewallTraversalTabHelper::RegisterUserPrefs(user_prefs); +#if defined(OS_MACOSX) + PresentationModePrefs::RegisterUserPrefs(user_prefs); +#endif } void MigrateBrowserPrefs(PrefService* user_prefs, PrefService* local_state) { diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 447257d..21c9014 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -1634,6 +1634,13 @@ void Browser::ToggleFullscreenMode() { #endif } +#if defined(OS_MACOSX) +void Browser::TogglePresentationMode() { + window_->SetPresentationMode(!window_->InPresentationMode()); + WindowFullscreenStateChanged(); +} +#endif + #if defined(OS_CHROMEOS) void Browser::Search() { // If the NTP is showing, close it. @@ -2381,6 +2388,9 @@ void Browser::ExecuteCommandWithDisposition( case IDC_COPY_URL: WriteCurrentURLToClipboard(); break; case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break; case IDC_FULLSCREEN: ToggleFullscreenMode(); break; +#if defined(OS_MACOSX) + case IDC_PRESENTATION_MODE: TogglePresentationMode(); break; +#endif case IDC_EXIT: Exit(); break; case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break; case IDC_COMPACT_NAVBAR: ToggleUseCompactNavigationBar(); break; @@ -3939,6 +3949,7 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window); // Window management commands + // TODO(rohitrao): Disable fullscreen on non-Lion? command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, !(is_type_panel() && is_app())); command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window); @@ -3957,6 +3968,8 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); #if defined(OS_MACOSX) command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window); + command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE, + !(is_type_panel() && is_app())); #endif // Clipboard commands diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 10ae3e8..d043c18 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -508,6 +508,9 @@ class Browser : public TabHandlerDelegate, void ConvertPopupToTabbedBrowser(); // In kiosk mode, the first toggle is valid, the rest is discarded. void ToggleFullscreenMode(); +#if defined(OS_MACOSX) + void TogglePresentationMode(); +#endif void Exit(); #if defined(OS_CHROMEOS) void Search(); diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 67e7fe5..c70f484 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -307,6 +307,11 @@ class BrowserWindow { #if defined(OS_MACOSX) // Opens the tabpose view. virtual void OpenTabpose() = 0; + + // Sets the presentation mode for the window. If the window is not already in + // fullscreen, also enters fullscreen mode. + virtual void SetPresentationMode(bool presentation_mode) = 0; + virtual bool InPresentationMode() = 0; #endif // See InstantDelegate for details. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm index 69fb3b6..e5917cf 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm @@ -32,8 +32,8 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/event_utils.h" -#import "chrome/browser/ui/cocoa/fullscreen_controller.h" #import "chrome/browser/ui/cocoa/menu_button.h" +#import "chrome/browser/ui/cocoa/presentation_mode_controller.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" #import "chrome/browser/ui/cocoa/view_id_util.h" diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index c9b34f7..81665a3 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -107,6 +107,8 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void ToggleTabStripMode(); virtual void ToggleUseCompactNavigationBar() {} virtual void OpenTabpose(); + virtual void SetPresentationMode(bool presentation_mode); + virtual bool InPresentationMode(); virtual void PrepareForInstant(); virtual void ShowInstant(TabContentsWrapper* preview); virtual void HideInstant(bool instant_is_active); diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index f9cd26f..afb3828 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -556,6 +556,14 @@ void BrowserWindowCocoa::OpenTabpose() { [controller_ openTabpose]; } +void BrowserWindowCocoa::SetPresentationMode(bool presentation_mode) { + [controller_ setPresentationMode:presentation_mode]; +} + +bool BrowserWindowCocoa::InPresentationMode() { + return [controller_ inPresentationMode]; +} + void BrowserWindowCocoa::PrepareForInstant() { // TODO: implement fade as done on windows. } diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index 5c11b8e..897dad0 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h @@ -35,10 +35,11 @@ class ConstrainedWindowMac; @class DevToolsController; @class DownloadShelfController; @class FindBarCocoaController; -@class FullscreenController; +@class FullscreenWindow; @class GTMWindowSheetController; @class InfoBarContainerController; class LocationBarViewMac; +@class PresentationModeController; @class PreviewableContentsController; @class SidebarController; class StatusBubbleMac; @@ -71,7 +72,7 @@ class TabContents; scoped_nsobject<DevToolsController> devToolsController_; scoped_nsobject<SidebarController> sidebarController_; scoped_nsobject<PreviewableContentsController> previewableContentsController_; - scoped_nsobject<FullscreenController> fullscreenController_; + scoped_nsobject<PresentationModeController> presentationModeController_; // Strong. StatusBubble is a special case of a strong reference that // we don't wrap in a scoped_ptr because it is acting the same @@ -111,21 +112,39 @@ class TabContents; // fullscreen window. scoped_nsobject<AvatarButton> avatarButton_; + // The view that shows the presentation mode toggle when in Lion fullscreen + // mode. Nil if not in fullscreen mode or not on Lion. + scoped_nsobject<NSButton> presentationModeToggleButton_; + // Lazily created view which draws the background for the floating set of bars - // in fullscreen mode (for window types having a floating bar; it remains nil - // for those which don't). + // in presentation mode (for window types having a floating bar; it remains + // nil for those which don't). scoped_nsobject<NSView> floatingBarBackingView_; // Tracks whether the floating bar is above or below the bookmark bar, in // terms of z-order. BOOL floatingBarAboveBookmarkBar_; - // The proportion of the floating bar which is shown (in fullscreen mode). + // The borderless window used in fullscreen mode. Lion reuses the original + // window in fullscreen mode, so this is always nil on Lion. + scoped_nsobject<NSWindow> fullscreenWindow_; + + // Tracks whether presentation mode was entered from fullscreen mode or + // directly from normal windowed mode. Used to determine what to do when + // exiting presentation mode. + BOOL enteredPresentationModeFromFullscreen_; + + // The size of the original (non-fullscreen) window. This is saved just + // before entering fullscreen mode and is only valid when |-isFullscreen| + // returns YES. + NSRect savedRegularWindowFrame_; + + // The proportion of the floating bar which is shown (in presentation mode). CGFloat floatingBarShownFraction_; // Various UI elements/events may want to ensure that the floating bar is - // visible (in fullscreen mode), e.g., because of where the mouse is or where - // keyboard focus is. Whenever an object requires bar visibility, it has + // visible (in presentation mode), e.g., because of where the mouse is or + // where keyboard focus is. Whenever an object requires bar visibility, it has // itself added to |barVisibilityLocks_|. When it no longer requires bar // visibility, it has itself removed. scoped_nsobject<NSMutableSet> barVisibilityLocks_; @@ -299,7 +318,8 @@ class TabContents; // Methods having to do with the window type (normal/popup/app, and whether the -// window has various features; fullscreen methods are separate). +// window has various features; fullscreen and presentation mode methods are +// separate). @interface BrowserWindowController(WindowType) // Determines whether this controller's window supports a given feature (i.e., @@ -334,32 +354,48 @@ class TabContents; @end // @interface BrowserWindowController(WindowType) -// Methods having to do with fullscreen mode. +// Methods having to do with fullscreen and presentation mode. @interface BrowserWindowController(Fullscreen) -// Enters fullscreen mode. -- (IBAction)enterFullscreen:(id)sender; +// Toggles fullscreen mode. Meant to be called by Lion windows when they enter +// or exit Lion fullscreen mode. Must not be called on Snow Leopard or earlier. +- (void)handleLionToggleFullscreen; -// Enters (or exits) fullscreen mode. +// Enters (or exits) fullscreen mode. This method is safe to call on all OS +// versions. - (void)setFullscreen:(BOOL)fullscreen; -// Returns fullscreen state. +// Returns fullscreen state. This method is safe to call on all OS versions. - (BOOL)isFullscreen; +// Toggles presentation mode without exiting fullscreen mode. Should only be +// called by the presentation mode toggle button. This method should not be +// called on Snow Leopard or earlier. +- (void)togglePresentationModeForLionOrLater:(id)sender; + +// Enters (or exits) presentation mode. Also enters fullscreen mode if this +// window is not already fullscreen. This method is safe to call on all OS +// versions. +- (void)setPresentationMode:(BOOL)presentationMode; + +// Returns presentation mode state. This method is safe to call on all OS +// versions. +- (BOOL)inPresentationMode; + // Resizes the fullscreen window to fit the screen it's currently on. Called by -// the FullscreenController when there is a change in monitor placement or +// the PresentationModeController when there is a change in monitor placement or // resolution. - (void)resizeFullscreenWindow; -// Gets or sets the fraction of the floating bar (fullscreen overlay) that is -// shown. 0 is completely hidden, 1 is fully shown. +// Gets or sets the fraction of the floating bar (presentation mode overlay) +// that is shown. 0 is completely hidden, 1 is fully shown. - (CGFloat)floatingBarShownFraction; - (void)setFloatingBarShownFraction:(CGFloat)fraction; // Query/lock/release the requirement that the tab strip/toolbar/attached // bookmark bar bar cluster is visible (e.g., when one of its elements has -// focus). This is required for the floating bar in fullscreen mode, but should -// also be called when not in fullscreen mode; see the comments for +// focus). This is required for the floating bar in presentation mode, but +// should also be called when not in presentation mode; see the comments for // |barVisibilityLocks_| for more details. Double locks/releases by the same // owner are ignored. If |animate:| is YES, then an animation may be performed, // possibly after a small delay if |delay:| is YES. If |animate:| is NO, diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 6df4d70..639c8c0 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -41,13 +41,13 @@ #import "chrome/browser/ui/cocoa/fast_resize_view.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" -#import "chrome/browser/ui/cocoa/focus_tracker.h" -#import "chrome/browser/ui/cocoa/fullscreen_controller.h" +#import "chrome/browser/ui/cocoa/framed_browser_window.h" #import "chrome/browser/ui/cocoa/fullscreen_window.h" #import "chrome/browser/ui/cocoa/gesture_utils.h" #import "chrome/browser/ui/cocoa/image_utils.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" +#import "chrome/browser/ui/cocoa/presentation_mode_controller.h" #import "chrome/browser/ui/cocoa/sidebar_controller.h" #import "chrome/browser/ui/cocoa/status_bubble_mac.h" #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" @@ -198,6 +198,15 @@ enum { }; typedef NSInteger NSWindowAnimationBehavior; +enum { + NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, + NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8 +}; + +enum { + NSFullScreenWindowMask = 1 << 14 +}; + @interface NSWindow (LionSDKDeclarations) - (void)setRestorable:(BOOL)flag; - (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior; @@ -264,6 +273,12 @@ typedef NSInteger NSWindowAnimationBehavior; if ([window respondsToSelector:@selector(setAnimationBehavior:)]) [window setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow]; + // Set the window to participate in Lion Fullscreen mode. Setting this flag + // has no effect on Snow Leopard or earlier. + NSUInteger collectionBehavior = [window collectionBehavior]; + collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; + [window setCollectionBehavior:collectionBehavior]; + // Get the most appropriate size for the window, then enforce the // minimum width and height. The window shim will handle flipping // the coordinates for us so we can use it to save some code. @@ -409,8 +424,6 @@ typedef NSInteger NSWindowAnimationBehavior; if ([self hasToolbar]) // Do not create the buttons in popups. [toolbarController_ createBrowserActionButtons]; - [self setUpOSFullScreenButton]; - // We are done initializing now. initializing_ = NO; } @@ -428,11 +441,11 @@ typedef NSInteger NSWindowAnimationBehavior; browser_->CloseAllTabs(); [downloadShelfController_ exiting]; - // Explicitly release |fullscreenController_| here, as it may call back to - // this BWC in |-dealloc|. We are required to call |-exitFullscreen| before - // releasing the controller. - [fullscreenController_ exitFullscreen]; - fullscreenController_.reset(); + // Explicitly release |presentationModeController_| here, as it may call back + // to this BWC in |-dealloc|. We are required to call |-exitPresentationMode| + // before releasing the controller. + [presentationModeController_ exitPresentationMode]; + presentationModeController_.reset(); // Under certain testing configurations we may not actually own the browser. if (ownsBrowser_ == NO) @@ -1020,6 +1033,19 @@ typedef NSInteger NSWindowAnimationBehavior; [self isFullscreen] ? IDS_EXIT_FULLSCREEN_MAC : IDS_ENTER_FULLSCREEN_MAC); [static_cast<NSMenuItem*>(item) setTitle:menuTitle]; + + if (base::mac::IsOSSnowLeopardOrEarlier()) + [static_cast<NSMenuItem*>(item) setHidden:YES]; + } + break; + } + case IDC_PRESENTATION_MODE: { + enable &= [self supportsFullscreen]; + if ([static_cast<NSObject*>(item) isKindOfClass:[NSMenuItem class]]) { + NSString* menuTitle = l10n_util::GetNSString( + [self inPresentationMode] ? IDS_EXIT_PRESENTATION_MAC : + IDS_ENTER_PRESENTATION_MAC); + [static_cast<NSMenuItem*>(item) setTitle:menuTitle]; } break; } @@ -1413,7 +1439,8 @@ typedef NSInteger NSWindowAnimationBehavior; relativeTo:[infoBarContainerController_ view]]; // Place the find bar immediately below the toolbar/attached bookmark bar. In - // fullscreen mode, it hangs off the top of the screen when the bar is hidden. + // presentation mode, it hangs off the top of the screen when the bar is + // hidden. CGFloat maxY = [self placeBookmarkBarBelowInfoBar] ? NSMinY([[toolbarController_ view] frame]) : NSMinY([[bookmarkBarController_ view] frame]); @@ -1445,7 +1472,7 @@ typedef NSInteger NSWindowAnimationBehavior; } - (NSRect)regularWindowFrame { - return [self isFullscreen] ? [savedRegularWindow_ frame] : + return [self isFullscreen] ? savedRegularWindowFrame_ : [[self window] frame]; } @@ -2028,171 +2055,108 @@ willAnimateFromState:(bookmarks::VisualState)oldState @implementation BrowserWindowController(Fullscreen) -- (IBAction)enterFullscreen:(id)sender { +- (void)handleLionToggleFullscreen { + DCHECK(base::mac::IsOSLionOrLater()); browser_->ExecuteCommand(IDC_FULLSCREEN); } +// On Lion, this method is called by either the Lion fullscreen button or the +// "Enter Full Screen" menu item. On Snow Leopard, this function is never +// called by the UI directly, but it provides the implementation for +// |-setPresentationMode:|. - (void)setFullscreen:(BOOL)fullscreen { - // The logic in this function is a bit complicated and very carefully - // arranged. See the below comments for more details. - if (fullscreen == [self isFullscreen]) return; if (![self supportsFullscreen]) return; - // Fade to black. - const CGDisplayReservationInterval kFadeDurationSeconds = 0.6; - Boolean didFadeOut = NO; - CGDisplayFadeReservationToken token; - if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token) - == kCGErrorSuccess) { - didFadeOut = YES; - CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal, - kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true); - } - - // Close the bookmark bubble, if it's open. We use |-ok:| instead of - // |-cancel:| or |-close| because that matches the behavior when the bubble - // loses key status. - [bookmarkBubbleController_ ok:self]; - - // Save the current first responder so we can restore after views are moved. - NSWindow* window = [self window]; - scoped_nsobject<FocusTracker> focusTracker( - [[FocusTracker alloc] initWithWindow:window]); - BOOL showDropdown = [self floatingBarHasFocus]; - - // While we move views (and focus) around, disable any bar visibility changes. - [self disableBarVisibilityUpdates]; - - // If we're entering fullscreen, create the fullscreen controller. If we're - // exiting fullscreen, kill the controller. - if (fullscreen) { - fullscreenController_.reset([[FullscreenController alloc] - initWithBrowserController:self]); - } else { - [fullscreenController_ exitFullscreen]; - fullscreenController_.reset(); - } - - // Destroy the tab strip's sheet controller. We will recreate it in the new - // window when needed. - [tabStripController_ destroySheetController]; - - // Retain the tab strip view while we remove it from its superview. - scoped_nsobject<NSView> tabStripView; - if ([self hasTabStrip] && ![self useVerticalTabs]) { - tabStripView.reset([[self tabStripView] retain]); - [tabStripView removeFromSuperview]; + if (base::mac::IsOSLionOrLater()) { + enteredPresentationModeFromFullscreen_ = YES; + if ([[self window] isKindOfClass:[FramedBrowserWindow class]]) + [static_cast<FramedBrowserWindow*>([self window]) toggleSystemFullScreen]; + return; } - // Ditto for the content view. - scoped_nsobject<NSView> contentView([[window contentView] retain]); - // Disable autoresizing of subviews while we move views around. This prevents - // spurious renderer resizes. - [contentView setAutoresizesSubviews:NO]; - [contentView removeFromSuperview]; - - NSWindow* destWindow = nil; - if (fullscreen) { - DCHECK(!savedRegularWindow_); - savedRegularWindow_ = [window retain]; - destWindow = [self createFullscreenWindow]; - } else { - DCHECK(savedRegularWindow_); - destWindow = [savedRegularWindow_ autorelease]; - savedRegularWindow_ = nil; - } - DCHECK(destWindow); - - // Have to do this here, otherwise later calls can crash because the window - // has no delegate. - [window setDelegate:nil]; - [destWindow setDelegate:self]; - - // With this call, valgrind complains that a "Conditional jump or move depends - // on uninitialised value(s)". The error happens in -[NSThemeFrame - // drawOverlayRect:]. I'm pretty convinced this is an Apple bug, but there is - // no visual impact. I have been unable to tickle it away with other window - // or view manipulation Cocoa calls. Stack added to suppressions_mac.txt. - [contentView setAutoresizesSubviews:YES]; - [destWindow setContentView:contentView]; + if (fullscreen) + [self enterFullscreenForSnowLeopardOrEarlier]; + else + [self exitFullscreenForSnowLeopardOrEarlier]; +} - // Move the incognito badge if present. - if (avatarButton_.get()) { - [avatarButton_ removeFromSuperview]; - [avatarButton_ setHidden:YES]; // Will be shown in layout. - [[[destWindow contentView] superview] addSubview:avatarButton_]; +- (BOOL)isFullscreen { + return (fullscreenWindow_.get() != nil) || + ([[self window] styleMask] & NSFullScreenWindowMask); +} + +- (void)togglePresentationModeForLionOrLater:(id)sender { + // Called only by the presentation mode toggle button. + DCHECK(base::mac::IsOSLionOrLater()); + enteredPresentationModeFromFullscreen_ = YES; + browser_->ExecuteCommand(IDC_PRESENTATION_MODE); +} + +// On Lion, this function is called by either the presentation mode toggle +// button or the "Enter Presentation Mode" menu item. In the latter case, this +// function also triggers the Lion machinery to enter fullscreen mode as well as +// set presentation mode. On Snow Leopard, this function is called by the +// "Enter Presentation Mode" menu item, and triggering presentation mode always +// moves the user into fullscreen mode. +- (void)setPresentationMode:(BOOL)presentationMode { + // Presentation mode on Leopard and Snow Leopard maps directly to fullscreen + // mode. + if (base::mac::IsOSSnowLeopardOrEarlier()) { + [self setFullscreen:presentationMode]; + return; } - // Add the tab strip after setting the content view and moving the incognito - // badge (if any), so that the tab strip will be on top (in the z-order). - if ([self hasTabStrip] && ![self useVerticalTabs]) - [[[destWindow contentView] superview] addSubview:tabStripView]; - - [window setWindowController:nil]; - [self setWindow:destWindow]; - [destWindow setWindowController:self]; - [self adjustUIForFullscreen:fullscreen]; - - // Adjust the infobar container. In fullscreen, it needs to be below all - // top chrome elements so it only sits atop the web contents. When in normal - // mode, it needs to draw over the bookmark bar and part of the toolbar. - [[infoBarContainerController_ view] removeFromSuperview]; - NSView* infoBarDest = [[destWindow contentView] superview]; - [infoBarDest addSubview:[infoBarContainerController_ view] - positioned:fullscreen ? NSWindowBelow : NSWindowAbove - relativeTo:fullscreen ? floatingBarBackingView_ - : [bookmarkBarController_ view]]; - - // When entering fullscreen mode, the controller forces a layout for us. When - // exiting, we need to call layoutSubviews manually. - if (fullscreen) { - [fullscreenController_ enterFullscreenForContentView:contentView - showDropdown:showDropdown]; + if (presentationMode) { + BOOL fullscreen = [self isFullscreen]; + [self setShouldUsePresentationModeWhenEnteringFullscreen:YES]; + enteredPresentationModeFromFullscreen_ = fullscreen; + + if (fullscreen) { + // If already in fullscreen mode, just toggle the presentation mode + // setting. Go through an elaborate dance to force the overlay to show, + // then animate out once the mouse moves away. This helps draw attention + // to the fact that the UI is in an overlay. Focus the tab contents + // because the omnibox is the most likely source of bar visibility locks, + // and taking focus away from the omnibox releases its lock. + [self lockBarVisibilityForOwner:self withAnimation:NO delay:NO]; + [self focusTabContents]; + [self setPresentationModeInternal:YES forceDropdown:YES]; + [self releaseBarVisibilityForOwner:self withAnimation:YES delay:YES]; + } else { + // If not in fullscreen mode, trigger the Lion fullscreen mode machinery. + // Presentation mode will automatically be enabled in + // |-windowWillEnterFullScreen:|. + NSWindow* window = [self window]; + if ([window isKindOfClass:[FramedBrowserWindow class]]) + [static_cast<FramedBrowserWindow*>(window) toggleSystemFullScreen]; + } } else { - [self layoutSubviews]; - } - - // Move the status bubble over, if we have one. - if (statusBubble_) - statusBubble_->SwitchParentWindow(destWindow); - - // Move the title over. - [destWindow setTitle:[window title]]; - - // The window needs to be onscreen before we can set its first responder. - // Ordering the window to the front can change the active Space (either to - // the window's old Space or to the application's assigned Space). To prevent - // this by temporarily change the collectionBehavior. - NSWindowCollectionBehavior behavior = [window collectionBehavior]; - [destWindow setCollectionBehavior: - NSWindowCollectionBehaviorMoveToActiveSpace]; - [destWindow makeKeyAndOrderFront:self]; - [destWindow setCollectionBehavior:behavior]; - - [focusTracker restoreFocusInWindow:destWindow]; - [window orderOut:self]; - - // We're done moving focus, so re-enable bar visibility changes. - [self enableBarVisibilityUpdates]; - - // This needs to be done when leaving full-screen mode to ensure that the - // button's action is set properly. - [self setUpOSFullScreenButton]; - - // Fade back in. - if (didFadeOut) { - CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor, - kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false); - CGReleaseDisplayFadeReservation(token); + if (enteredPresentationModeFromFullscreen_) { + // The window is currently in fullscreen mode, but the user is choosing to + // turn presentation mode off (choosing to always show the UI). Set the + // preference to ensure that presentation mode will stay off for the next + // window that goes fullscreen. + [self setShouldUsePresentationModeWhenEnteringFullscreen:NO]; + [self setPresentationModeInternal:NO forceDropdown:NO]; + } else { + // The user entered presentation mode directly from non-fullscreen mode + // using the "Enter Presentation Mode" menu item and is using that same + // menu item to exit presentation mode. In this case, exit fullscreen + // mode as well (using the Lion machinery). + NSWindow* window = [self window]; + if ([window isKindOfClass:[FramedBrowserWindow class]]) + [static_cast<FramedBrowserWindow*>(window) toggleSystemFullScreen]; + } } } -- (BOOL)isFullscreen { - return fullscreenController_.get() && [fullscreenController_ isFullscreen]; +- (BOOL)inPresentationMode { + return presentationModeController_.get() && + [presentationModeController_ inPresentationMode]; } - (void)resizeFullscreenWindow { @@ -2226,10 +2190,10 @@ willAnimateFromState:(bookmarks::VisualState)oldState if (![self isBarVisibilityLockedForOwner:owner]) { [barVisibilityLocks_ addObject:owner]; - // If enabled, show the overlay if necessary (and if in fullscreen mode). + // If enabled, show the overlay if necessary (and if in presentation mode). if (barVisibilityUpdatesEnabled_) { - [fullscreenController_ ensureOverlayShownWithAnimation:animate - delay:delay]; + [presentationModeController_ ensureOverlayShownWithAnimation:animate + delay:delay]; } } } @@ -2240,11 +2204,11 @@ willAnimateFromState:(bookmarks::VisualState)oldState if ([self isBarVisibilityLockedForOwner:owner]) { [barVisibilityLocks_ removeObject:owner]; - // If enabled, hide the overlay if necessary (and if in fullscreen mode). + // If enabled, hide the overlay if necessary (and if in presentation mode). if (barVisibilityUpdatesEnabled_ && ![barVisibilityLocks_ count]) { - [fullscreenController_ ensureOverlayHiddenWithAnimation:animate - delay:delay]; + [presentationModeController_ ensureOverlayHiddenWithAnimation:animate + delay:delay]; } } } diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.h b/chrome/browser/ui/cocoa/browser_window_controller_private.h index cd3b5c4..26c181b 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.h +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.h @@ -21,6 +21,10 @@ // tabs are enabled. Replaces the current controller. - (void)createTabStripController; +// Creates the button used to toggle presentation mode. Must only be called on +// Lion or later. Does nothing if the button already exists. +- (void)createAndInstallPresentationModeToggleButton; + // Saves the window's position in the local state preferences. - (void)saveWindowPositionIfNeeded; @@ -38,13 +42,19 @@ // content area, download shelf (if any). - (void)layoutSubviews; -// Find the total height of the floating bar (in fullscreen mode). Safe to call -// even when not in fullscreen mode. +// Find the total height of the floating bar (in presentation mode). Safe to +// call even when not in presentation mode. - (CGFloat)floatingBarHeight; +// Lays out the presentation mode toggle button at the top right corner of the +// overlay. Creates the button if needed, and removes it if it is not needed. +// This method is safe to call on all OS versions. +- (void)layoutPresentationModeToggleAtOverlayMaxX:(CGFloat)maxX + overlayMaxY:(CGFloat)maxY; + // Lays out the tab strip at the given maximum y-coordinate, with the given -// width, possibly for fullscreen mode; returns the new maximum y (below the tab -// strip). This is safe to call even when there is no tab strip. +// width, possibly for fullscreen mode; returns the new maximum y (below the +// tab strip). This is safe to call even when there is no tab strip. - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY width:(CGFloat)width fullscreen:(BOOL)fullscreen; @@ -70,10 +80,10 @@ width:(CGFloat)width; // Lay out the view which draws the background for the floating bar when in -// fullscreen mode, with the given frame and fullscreen-mode-status. Should be -// called even when not in fullscreen mode to hide the backing view. +// presentation mode, with the given frame and presentation-mode-status. Should +// be called even when not in presentation mode to hide the backing view. - (void)layoutFloatingBarBackingView:(NSRect)frame - fullscreen:(BOOL)fullscreen; + presentationMode:(BOOL)presentationMode; // Lays out the infobar at the given maximum y-coordinate, with the given width; // returns the new maximum y (below the infobar). @@ -104,8 +114,50 @@ // keep the total height of the two views constant. - (void)adjustToolbarAndBookmarkBarForCompression:(CGFloat)compression; -// Adjust the UI when entering or leaving fullscreen mode. -- (void)adjustUIForFullscreen:(BOOL)fullscreen; +// Gets and sets whether to default to presentation mode when entering +// fullscreen on Lion or later. On Leopard and Snow Leopard, this preference is +// ignored (fullscreen mode always turns presentation mode on). This method is +// safe to call on all OS versions. +- (BOOL)shouldUsePresentationModeWhenEnteringFullscreen; +- (void)setShouldUsePresentationModeWhenEnteringFullscreen:(BOOL)flag; + +// Whether to show the presentation mode toggle button in the UI. Returns YES +// if in fullscreen mode on Lion or later. This method is safe to call on all +// OS versions. +- (BOOL)shouldShowPresentationModeToggle; + +// Moves views between windows in preparation for fullscreen mode on Snow +// Leopard or earlier. (Lion and later reuses the original window for +// fullscreen mode, so there is no need to move views around.) This method does +// not position views; callers must also call |-layoutSubviews|. This method +// must not be called on Lion or later. +- (void)moveViewsForFullscreenForSnowLeopardOrEarlier:(BOOL)fullscreen + regularWindow:(NSWindow*)regularWindow + fullscreenWindow:(NSWindow*)fullscreenWindow; + +// Sets presentation mode, creating the PresentationModeController if needed and +// forcing a relayout. If |forceDropdown| is YES, this method will always +// initially show the floating bar when entering presentation mode, even if the +// floating bar does not have focus. This method is safe to call on all OS +// versions. +- (void)setPresentationModeInternal:(BOOL)presentationMode + forceDropdown:(BOOL)forceDropdown; + +// Called on Snow Leopard or earlier to enter or exit fullscreen. These methods +// are internal implementations of |-setFullscreen:|. These methods must not be +// called on Lion or later. +- (void)enterFullscreenForSnowLeopardOrEarlier; +- (void)exitFullscreenForSnowLeopardOrEarlier; + +// Register or deregister for content view resize notifications. These +// notifications are used while transitioning to fullscreen mode in Lion or +// later. This method is safe to call on all OS versions. +- (void)registerForContentViewResizeNotifications; +- (void)deregisterForContentViewResizeNotifications; + +// Adjust the UI when entering or leaving presentation mode. This method is +// safe to call on all OS versions. +- (void)adjustUIForPresentationMode:(BOOL)fullscreen; // Allows/prevents bar visibility locks and releases from updating the visual // state. Enabling makes changes instantaneously; disabling cancels any @@ -113,12 +165,6 @@ - (void)enableBarVisibilityUpdates; - (void)disableBarVisibilityUpdates; -// For versions of Mac OS that provide an "enter fullscreen" button, make one -// appear (in a rather hacky manner). http://crbug.com/74065 : When switching -// the fullscreen implementation to the new API, revisit how much of this -// hacky code is necessary. -- (void)setUpOSFullScreenButton; - @end // @interface BrowserWindowController(Private) #endif // CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_CONTROLLER_PRIVATE_H_ diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index 85b230f..589b6dd 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm @@ -4,6 +4,8 @@ #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" +#include <cmath> + #include "base/command_line.h" #import "base/memory/scoped_nsobject.h" #include "chrome/browser/browser_process.h" @@ -12,12 +14,16 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" #include "chrome/browser/ui/browser_list.h" +#import "chrome/browser/ui/cocoa/browser/avatar_button.h" #import "chrome/browser/ui/cocoa/fast_resize_view.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h" +#import "chrome/browser/ui/cocoa/focus_tracker.h" #import "chrome/browser/ui/cocoa/framed_browser_window.h" -#import "chrome/browser/ui/cocoa/fullscreen_controller.h" +#import "chrome/browser/ui/cocoa/fullscreen_window.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" +#import "chrome/browser/ui/cocoa/presentation_mode_controller.h" +#import "chrome/browser/ui/cocoa/status_bubble_mac.h" #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" #import "chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" @@ -30,30 +36,32 @@ #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents_view.h" -// Provide the forward-declarations of new 10.7 SDK symbols so they can be -// called when building with the 10.5 SDK. -#if !defined(MAC_OS_X_VERSION_10_7) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 - -@interface NSWindow (LionSDKDeclarations) -- (void)toggleFullScreen:(id)sender; -@end - -enum { - NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, - NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8 -}; +// Forward-declare symbols that are part of the 10.6 SDK. +#if !defined(MAC_OS_X_VERSION_10_6) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 enum { - NSWindowFullScreenButton = 7 + NSApplicationPresentationDefault = 0, + NSApplicationPresentationAutoHideDock = (1 << 0), + NSApplicationPresentationHideDock = (1 << 1), + NSApplicationPresentationAutoHideMenuBar = (1 << 2), + NSApplicationPresentationHideMenuBar = (1 << 3), }; +typedef NSUInteger NSApplicationPresentationOptions; -#endif // MAC_OS_X_VERSION_10_7 +#endif // MAC_OS_X_VERSION_10_6 namespace { // Space between the incognito badge and the right edge of the window. -const CGFloat kIncognitoBadgeOffset = 4; +const CGFloat kAvatarRightOffset = 4; + +// The amount by which to shrink the tab strip (on the right) when the +// incognito badge is present. +const CGFloat kAvatarTabStripShrink = 18; + +// The amount by which to shift the avatar to the right if on Lion. +const CGFloat kAvatarShiftForLion = 20; // Insets for the location bar, used when the full toolbar is hidden. // TODO(viettrungluu): We can argue about the "correct" insetting; I like the @@ -82,6 +90,26 @@ const CGFloat kLocBarBottomInset = 1; delegate:self]); } +- (void)createAndInstallPresentationModeToggleButton { + DCHECK(base::mac::IsOSLionOrLater()); + if (presentationModeToggleButton_.get()) + return; + + // TODO(rohitrao): Make this button prettier. + presentationModeToggleButton_.reset( + [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 25, 25)]); + NSButton* button = presentationModeToggleButton_.get(); + [button setButtonType:NSMomentaryLightButton]; + [button setBezelStyle:NSRegularSquareBezelStyle]; + [button setBordered:NO]; + [[button cell] setHighlightsBy:NSContentsCellMask]; + [[button cell] setShowsStateBy:NSContentsCellMask]; + [button setImage:[NSImage imageNamed:NSImageNameIChatTheaterTemplate]]; + [button setTarget:self]; + [button setAction:@selector(togglePresentationModeForLionOrLater:)]; + [[[[self window] contentView] superview] addSubview:button]; +} + - (void)saveWindowPositionIfNeeded { if (browser_ != BrowserList::GetLastActive()) return; @@ -184,22 +212,30 @@ willPositionSheet:(NSWindow*)sheet if ([window respondsToSelector:@selector(setShouldHideTitle:)]) [(id)window setShouldHideTitle:![self hasTitleBar]]; - BOOL isFullscreen = [self isFullscreen]; + BOOL inPresentationMode = [self inPresentationMode]; CGFloat floatingBarHeight = [self floatingBarHeight]; - // In fullscreen mode, |yOffset| accounts for the sliding position of the + // In presentation mode, |yOffset| accounts for the sliding position of the // floating bar and the extra offset needed to dodge the menu bar. - CGFloat yOffset = isFullscreen ? - (floor((1 - floatingBarShownFraction_) * floatingBarHeight) - - [fullscreenController_ floatingBarVerticalOffset]) : 0; + CGFloat yOffset = inPresentationMode ? + (std::floor((1 - floatingBarShownFraction_) * floatingBarHeight) - + [presentationModeController_ floatingBarVerticalOffset]) : 0; CGFloat maxY = NSMaxY(contentBounds) + yOffset; CGFloat startMaxY = maxY; + CGFloat overlayMaxY = + NSMaxY([window frame]) + + std::floor((1 - floatingBarShownFraction_) * floatingBarHeight); + [self layoutPresentationModeToggleAtOverlayMaxX:NSMaxX([window frame]) + overlayMaxY:overlayMaxY]; + if ([self hasTabStrip] && ![self useVerticalTabs]) { // If we need to lay out the top tab strip, replace |maxY| and |startMaxY| // with higher values, and then lay out the tab strip. NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil]; startMaxY = maxY = NSHeight(windowFrame) + yOffset; - maxY = [self layoutTabStripAtMaxY:maxY width:width fullscreen:isFullscreen]; + maxY = [self layoutTabStripAtMaxY:maxY + width:width + fullscreen:[self isFullscreen]]; } // Sanity-check |maxY|. @@ -229,20 +265,20 @@ willPositionSheet:(NSWindow*)sheet NSRect floatingBarBackingRect = NSMakeRect(minX, maxY, width, floatingBarHeight); [self layoutFloatingBarBackingView:floatingBarBackingRect - fullscreen:isFullscreen]; + presentationMode:inPresentationMode]; // Place the find bar immediately below the toolbar/attached bookmark bar. In - // fullscreen mode, it hangs off the top of the screen when the bar is hidden. - // The find bar is unaffected by the side tab positioning. + // presentation mode, it hangs off the top of the screen when the bar is + // hidden. The find bar is unaffected by the side tab positioning. [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width]; - // If in fullscreen mode, reset |maxY| to top of screen, so that the floating - // bar slides over the things which appear to be in the content area. - if (isFullscreen) + // If in presentation mode, reset |maxY| to top of screen, so that the + // floating bar slides over the things which appear to be in the content area. + if (inPresentationMode) maxY = NSMaxY(contentBounds); // Also place the infobar container immediate below the toolbar, except in - // fullscreen mode in which case it's at the top of the visual content area. + // presentation mode in which case it's at the top of the visual content area. maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width]; // If the bookmark bar is detached, place it next in the visual content area. @@ -263,10 +299,10 @@ willPositionSheet:(NSWindow*)sheet } - (CGFloat)floatingBarHeight { - if (![self isFullscreen]) + if (![self inPresentationMode]) return 0; - CGFloat totalHeight = [fullscreenController_ floatingBarVerticalOffset]; + CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset]; if ([self hasTabStrip]) totalHeight += NSHeight([[self tabStripView] frame]); @@ -284,6 +320,23 @@ willPositionSheet:(NSWindow*)sheet return totalHeight; } +- (void)layoutPresentationModeToggleAtOverlayMaxX:(CGFloat)maxX + overlayMaxY:(CGFloat)maxY { + // Lay out the presentation mode toggle button at the very top of the + // tab strip. + if ([self shouldShowPresentationModeToggle]) { + [self createAndInstallPresentationModeToggleButton]; + + NSPoint origin = + NSMakePoint(maxX - NSWidth([presentationModeToggleButton_ frame]), + maxY - NSHeight([presentationModeToggleButton_ frame])); + [presentationModeToggleButton_ setFrameOrigin:origin]; + } else { + [presentationModeToggleButton_ removeFromSuperview]; + presentationModeToggleButton_.reset(); + } +} + - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY width:(CGFloat)width fullscreen:(BOOL)fullscreen { @@ -296,25 +349,38 @@ willPositionSheet:(NSWindow*)sheet maxY -= tabStripHeight; [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)]; - // Set indentation. - [tabStripController_ setIndentForControls:(fullscreen ? 0 : - [[tabStripController_ class] defaultIndentForControls])]; + // Set left indentation based on fullscreen mode status. + [tabStripController_ setLeftIndentForControls:(fullscreen ? 0 : + [[tabStripController_ class] defaultLeftIndentForControls])]; + + // Calculate the right indentation. The default indentation built into the + // tabstrip leaves enough room for the fullscreen button or presentation mode + // toggle button on Lion. On non-Lion systems, the default indentation also + // looks fine. If an avatar button is present, indent enough to account for + // its width. + const CGFloat possibleExtraShiftForLion = + base::mac::IsOSLionOrLater() ? kAvatarShiftForLion : 0; + + CGFloat rightIndent = 0; + if ([self shouldShowAvatar]) + rightIndent += (kAvatarTabStripShrink + possibleExtraShiftForLion); + [tabStripController_ setRightIndentForControls:rightIndent]; - // TODO(viettrungluu): Seems kind of bad -- shouldn't |-layoutSubviews| do - // this? Moreover, |-layoutTabs| will try to animate.... - [tabStripController_ layoutTabs]; + // Go ahead and layout the tabs. + [tabStripController_ layoutTabsWithoutAnimation]; // Now lay out incognito badge together with the tab strip. if (avatarButton_.get()) { - // Set the size of the avatar to be the (height of the tabstrip) - (padding) - // to let large icons fit. CGFloat sizeSquare = tabStripHeight - 5.0; [avatarButton_ setFrameSize:NSMakeSize(sizeSquare, sizeSquare)]; - // Actually place the badge *above* |maxY|, by +2 to miss the divider. - NSPoint origin = NSMakePoint(width - NSWidth([avatarButton_ frame]) - - kIncognitoBadgeOffset, - maxY + 2); + // Actually place the badge *above* |maxY|, by +2 to miss the divider. On + // Lion or later, shift the badge left to move it away from the fullscreen + // button. + CGFloat badgeOffset = kAvatarRightOffset + possibleExtraShiftForLion; + NSPoint origin = + NSMakePoint(width - NSWidth([avatarButton_ frame]) - badgeOffset, + maxY + 2); [avatarButton_ setFrameOrigin:origin]; [avatarButton_ setHidden:NO]; // Make sure it's shown. } @@ -386,9 +452,9 @@ willPositionSheet:(NSWindow*)sheet } - (void)layoutFloatingBarBackingView:(NSRect)frame - fullscreen:(BOOL)fullscreen { - // Only display when in fullscreen mode. - if (fullscreen) { + presentationMode:(BOOL)presentationMode { + // Only display when in presentation mode. + if (presentationMode) { // For certain window types such as app windows (e.g., the dev tools // window), there's no actual overlay. (Displaying one would result in an // overly sliding in only under the menu, which gives an ugly effect.) @@ -414,7 +480,7 @@ willPositionSheet:(NSWindow*)sheet } // But we want the logic to work as usual (for show/hide/etc. purposes). - [fullscreenController_ overlayFrameChanged:frame]; + [presentationModeController_ overlayFrameChanged:frame]; } else { // Okay to call even if |floatingBarBackingView_| is nil. if ([floatingBarBackingView_ superview]) @@ -505,16 +571,287 @@ willPositionSheet:(NSWindow*)sheet [self layoutSubviews]; } +// Fullscreen and presentation mode methods + +- (BOOL)shouldUsePresentationModeWhenEnteringFullscreen { + return browser_->profile()->GetPrefs()->GetBoolean( + prefs::kPresentationModeEnabled); +} + +- (void)setShouldUsePresentationModeWhenEnteringFullscreen:(BOOL)flag { + browser_->profile()->GetPrefs()->SetBoolean( + prefs::kPresentationModeEnabled, flag); +} + +- (BOOL)shouldShowPresentationModeToggle { + return base::mac::IsOSLionOrLater() && [self isFullscreen]; +} + +- (void)moveViewsForFullscreenForSnowLeopardOrEarlier:(BOOL)fullscreen + regularWindow:(NSWindow*)regularWindow + fullscreenWindow:(NSWindow*)fullscreenWindow { + // This method is only for Snow Leopard and earlier. + DCHECK(base::mac::IsOSSnowLeopardOrEarlier()); + + NSWindow* sourceWindow = fullscreen ? regularWindow : fullscreenWindow; + NSWindow* destWindow = fullscreen ? fullscreenWindow : regularWindow; + + // Close the bookmark bubble, if it's open. Use |-ok:| instead of |-cancel:| + // or |-close| because that matches the behavior when the bubble loses key + // status. + [bookmarkBubbleController_ ok:self]; + + // Save the current first responder so we can restore after views are moved. + scoped_nsobject<FocusTracker> focusTracker( + [[FocusTracker alloc] initWithWindow:sourceWindow]); + + // While we move views (and focus) around, disable any bar visibility changes. + [self disableBarVisibilityUpdates]; + + // Destroy the tab strip's sheet controller. We will recreate it in the new + // window when needed. + [tabStripController_ destroySheetController]; + + // Retain the tab strip view while we remove it from its superview. + scoped_nsobject<NSView> tabStripView; + if ([self hasTabStrip] && ![self useVerticalTabs]) { + tabStripView.reset([[self tabStripView] retain]); + [tabStripView removeFromSuperview]; + } + + // Ditto for the content view. + scoped_nsobject<NSView> contentView([[sourceWindow contentView] retain]); + // Disable autoresizing of subviews while we move views around. This prevents + // spurious renderer resizes. + [contentView setAutoresizesSubviews:NO]; + [contentView removeFromSuperview]; + + // Have to do this here, otherwise later calls can crash because the window + // has no delegate. + [sourceWindow setDelegate:nil]; + [destWindow setDelegate:self]; + + // With this call, valgrind complains that a "Conditional jump or move depends + // on uninitialised value(s)". The error happens in -[NSThemeFrame + // drawOverlayRect:]. I'm pretty convinced this is an Apple bug, but there is + // no visual impact. I have been unable to tickle it away with other window + // or view manipulation Cocoa calls. Stack added to suppressions_mac.txt. + [contentView setAutoresizesSubviews:YES]; + [destWindow setContentView:contentView]; + + // Move the incognito badge if present. + if (avatarButton_.get()) { + [avatarButton_ removeFromSuperview]; + [avatarButton_ setHidden:YES]; // Will be shown in layout. + [[[destWindow contentView] superview] addSubview:avatarButton_]; + } + + // Add the tab strip after setting the content view and moving the incognito + // badge (if any), so that the tab strip will be on top (in the z-order). + if ([self hasTabStrip] && ![self useVerticalTabs]) + [[[destWindow contentView] superview] addSubview:tabStripView]; + + [sourceWindow setWindowController:nil]; + [self setWindow:destWindow]; + [destWindow setWindowController:self]; + + // Move the status bubble over, if we have one. + if (statusBubble_) + statusBubble_->SwitchParentWindow(destWindow); + + // Move the title over. + [destWindow setTitle:[sourceWindow title]]; + + // The window needs to be onscreen before we can set its first responder. + // Ordering the window to the front can change the active Space (either to + // the window's old Space or to the application's assigned Space). To prevent + // this by temporarily change the collectionBehavior. + NSWindowCollectionBehavior behavior = [sourceWindow collectionBehavior]; + [destWindow setCollectionBehavior: + NSWindowCollectionBehaviorMoveToActiveSpace]; + [destWindow makeKeyAndOrderFront:self]; + [destWindow setCollectionBehavior:behavior]; + + [focusTracker restoreFocusInWindow:destWindow]; + [sourceWindow orderOut:self]; + + // We're done moving focus, so re-enable bar visibility changes. + [self enableBarVisibilityUpdates]; +} + +- (void)setPresentationModeInternal:(BOOL)presentationMode + forceDropdown:(BOOL)forceDropdown { + if (presentationMode == [self inPresentationMode]) + return; + + if (presentationMode) { + BOOL showDropdown = forceDropdown || [self floatingBarHasFocus]; + NSView* contentView = [[self window] contentView]; + presentationModeController_.reset( + [[PresentationModeController alloc] initWithBrowserController:self]); + [presentationModeController_ enterPresentationModeForContentView:contentView + showDropdown:showDropdown]; + } else { + [presentationModeController_ exitPresentationMode]; + presentationModeController_.reset(); + } + + [self adjustUIForPresentationMode:presentationMode]; + [self layoutSubviews]; +} + +- (void)enterFullscreenForSnowLeopardOrEarlier { + DCHECK(base::mac::IsOSSnowLeopardOrEarlier()); + + // Fade to black. + const CGDisplayReservationInterval kFadeDurationSeconds = 0.6; + Boolean didFadeOut = NO; + CGDisplayFadeReservationToken token; + if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token) + == kCGErrorSuccess) { + didFadeOut = YES; + CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal, + kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true); + } + + // Create the fullscreen window. After this line, isFullscreen will return + // YES. + fullscreenWindow_.reset([[self createFullscreenWindow] retain]); + savedRegularWindow_ = [[self window] retain]; + savedRegularWindowFrame_ = [savedRegularWindow_ frame]; + + [self moveViewsForFullscreenForSnowLeopardOrEarlier:YES + regularWindow:[self window] + fullscreenWindow:fullscreenWindow_.get()]; + [self adjustUIForPresentationMode:YES]; + [self setPresentationModeInternal:YES forceDropdown:NO]; + [self layoutSubviews]; + + // Fade back in. + if (didFadeOut) { + CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor, + kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false); + CGReleaseDisplayFadeReservation(token); + } +} + +- (void)exitFullscreenForSnowLeopardOrEarlier { + DCHECK(base::mac::IsOSSnowLeopardOrEarlier()); + + // Fade to black. + const CGDisplayReservationInterval kFadeDurationSeconds = 0.6; + Boolean didFadeOut = NO; + CGDisplayFadeReservationToken token; + if (CGAcquireDisplayFadeReservation(kFadeDurationSeconds, &token) + == kCGErrorSuccess) { + didFadeOut = YES; + CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendNormal, + kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true); + } + + [self setPresentationModeInternal:NO forceDropdown:NO]; + [self moveViewsForFullscreenForSnowLeopardOrEarlier:NO + regularWindow:savedRegularWindow_ + fullscreenWindow:fullscreenWindow_.get()]; + + // When exiting fullscreen mode, we need to call layoutSubviews manually. + [savedRegularWindow_ autorelease]; + savedRegularWindow_ = nil; + fullscreenWindow_.reset(); + [self layoutSubviews]; + + // Fade back in. + if (didFadeOut) { + CGDisplayFade(token, kFadeDurationSeconds / 2, kCGDisplayBlendSolidColor, + kCGDisplayBlendNormal, 0.0, 0.0, 0.0, /*synchronous=*/false); + CGReleaseDisplayFadeReservation(token); + } +} + // TODO(rohitrao): This function has shrunk into uselessness, and // |-setFullscreen:| has grown rather large. Find a good way to break up // |-setFullscreen:| into smaller pieces. http://crbug.com/36449 -- (void)adjustUIForFullscreen:(BOOL)fullscreen { +- (void)adjustUIForPresentationMode:(BOOL)fullscreen { // Create the floating bar backing view if necessary. if (fullscreen && !floatingBarBackingView_.get() && ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) { floatingBarBackingView_.reset( [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]); + [floatingBarBackingView_ setAutoresizingMask:(NSViewWidthSizable | + NSViewMinYMargin)]; } + + // Adjust the infobar container. In fullscreen, it needs to be below all + // top chrome elements so it only sits atop the web contents. When in normal + // mode, it needs to draw over the bookmark bar and part of the toolbar. + [[infoBarContainerController_ view] removeFromSuperview]; + NSView* infoBarDest = [[self window] contentView]; + [infoBarDest addSubview:[infoBarContainerController_ view] + positioned:fullscreen ? NSWindowBelow : NSWindowAbove + relativeTo:fullscreen ? nil + : [bookmarkBarController_ view]]; +} + +- (void)contentViewDidResize:(NSNotification*)notification { + [self layoutSubviews]; +} + +- (void)registerForContentViewResizeNotifications { + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(contentViewDidResize:) + name:NSViewFrameDidChangeNotification + object:[[self window] contentView]]; +} + +- (void)deregisterForContentViewResizeNotifications { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSViewFrameDidChangeNotification + object:[[self window] contentView]]; +} + +- (NSSize)window:(NSWindow*)window + willUseFullScreenContentSize:(NSSize)proposedSize { + return proposedSize; +} + +- (NSApplicationPresentationOptions)window:(NSWindow*)window + willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)opt { + return (opt | + NSApplicationPresentationAutoHideDock | + NSApplicationPresentationAutoHideMenuBar); +} + +- (void)windowWillEnterFullScreen:(NSNotification*)notification { + [self registerForContentViewResizeNotifications]; + + NSWindow* window = [self window]; + savedRegularWindowFrame_ = [window frame]; + BOOL mode = [self shouldUsePresentationModeWhenEnteringFullscreen]; + [self setPresentationModeInternal:mode forceDropdown:NO]; +} + +- (void)windowDidEnterFullScreen:(NSNotification*)notification { + [self deregisterForContentViewResizeNotifications]; +} + +- (void)windowWillExitFullScreen:(NSNotification*)notification { + [self registerForContentViewResizeNotifications]; + [self setPresentationModeInternal:NO forceDropdown:NO]; +} + +- (void)windowDidExitFullScreen:(NSNotification*)notification { + [self deregisterForContentViewResizeNotifications]; +} + +- (void)windowDidFailToEnterFullScreen:(NSWindow*)window { + [self deregisterForContentViewResizeNotifications]; + [self setPresentationModeInternal:NO forceDropdown:NO]; +} + +- (void)windowDidFailToExitFullScreen:(NSWindow*)window { + [self deregisterForContentViewResizeNotifications]; } - (void)enableBarVisibilityUpdates { @@ -525,9 +862,9 @@ willPositionSheet:(NSWindow*)sheet barVisibilityUpdatesEnabled_ = YES; if ([barVisibilityLocks_ count]) - [fullscreenController_ ensureOverlayShownWithAnimation:NO delay:NO]; + [presentationModeController_ ensureOverlayShownWithAnimation:NO delay:NO]; else - [fullscreenController_ ensureOverlayHiddenWithAnimation:NO delay:NO]; + [presentationModeController_ ensureOverlayHiddenWithAnimation:NO delay:NO]; } - (void)disableBarVisibilityUpdates { @@ -536,11 +873,7 @@ willPositionSheet:(NSWindow*)sheet return; barVisibilityUpdatesEnabled_ = NO; - [fullscreenController_ cancelAnimationAndTimers]; -} - -- (void)setUpOSFullScreenButton { - // TOOD(rsesek): Properly implement Lion fullscreen <http://crbug.com/74065>. + [presentationModeController_ cancelAnimationAndTimers]; } @end // @implementation BrowserWindowController(Private) diff --git a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm index ea81eec..0bd0620 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm @@ -644,7 +644,7 @@ TEST_F(BrowserWindowControllerTest, TestStatusBubblePositioning) { @private // We release the window ourselves, so we don't have to rely on the unittest // doing it for us. - scoped_nsobject<NSWindow> fullscreenWindow_; + scoped_nsobject<NSWindow> testFullscreenWindow_; } @end @@ -713,15 +713,15 @@ TEST_F(BrowserWindowFullScreenControllerTest, TestActivate) { // whole screen. We have to return an actual window because |-layoutSubviews| // looks at the window's frame. - (NSWindow*)createFullscreenWindow { - if (fullscreenWindow_.get()) - return fullscreenWindow_.get(); + if (testFullscreenWindow_.get()) + return testFullscreenWindow_.get(); - fullscreenWindow_.reset( + testFullscreenWindow_.reset( [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,400,400) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]); - return fullscreenWindow_.get(); + return testFullscreenWindow_.get(); } @end diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm index 4bc8fd0..88dc946 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm @@ -18,8 +18,8 @@ #include "chrome/browser/ui/cocoa/download/download_item_controller.h" #include "chrome/browser/ui/cocoa/download/download_shelf_mac.h" #import "chrome/browser/ui/cocoa/download/download_shelf_view.h" -#import "chrome/browser/ui/cocoa/fullscreen_controller.h" #import "chrome/browser/ui/cocoa/hover_button.h" +#import "chrome/browser/ui/cocoa/presentation_mode_controller.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chrome/browser/ui/cocoa/framed_browser_window.h b/chrome/browser/ui/cocoa/framed_browser_window.h index 6629050..3c574a4 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.h +++ b/chrome/browser/ui/cocoa/framed_browser_window.h @@ -42,6 +42,9 @@ const NSInteger kFramedWindowButtonsWithoutTabStripOffsetFromLeft = 8; // Returns the desired spacing between window control views. - (CGFloat)windowButtonsInterButtonSpacing; +// Calls the superclass's implementation of |-toggleFullScreen:|. +- (void)toggleSystemFullScreen; + @end @interface NSWindow (UndocumentedAPI) diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm index e15481a..712959a 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.mm +++ b/chrome/browser/ui/cocoa/framed_browser_window.mm @@ -13,6 +13,18 @@ #import "chrome/browser/renderer_host/render_widget_host_view_mac.h" #include "chrome/browser/themes/theme_service.h" +// Provide the forward-declarations of new 10.7 SDK symbols so they can be +// called when building with the 10.5 SDK. +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSWindow (LionSDKDeclarations) +- (void)toggleFullScreen:(id)sender; +@end + +#endif // MAC_OS_X_VERSION_10_7 + + // Implementer's note: Moving the window controls is tricky. When altering the // code, ensure that: // - accessibility hit testing works @@ -273,4 +285,19 @@ const CGFloat kWindowGradientHeight = 24.0; return [super constrainFrameRect:frame toScreen:screen]; } +// This method is overridden in order to send the toggle fullscreen message +// through the cross-platform browser framework before going fullscreen. The +// message will eventually come back as a call to |-toggleSystemFullScreen|, +// which in turn calls AppKit's |NSWindow -toggleFullScreen:|. +- (void)toggleFullScreen:(id)sender { + id delegate = [self delegate]; + if ([delegate respondsToSelector:@selector(handleLionToggleFullscreen)]) + [delegate handleLionToggleFullscreen]; +} + +- (void)toggleSystemFullScreen { + if ([super respondsToSelector:@selector(toggleFullScreen:)]) + [super toggleFullScreen:nil]; +} + @end diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm index 7c7e7f5..30d2f59 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm @@ -402,7 +402,7 @@ BOOL ThePasteboardIsTooDamnBig() { if (cmd == @selector(cancelOperation:)) { BrowserWindowController* windowController = [BrowserWindowController browserWindowControllerForView:self]; - if ([windowController isFullscreen]) { + if ([windowController inPresentationMode]) { [windowController focusTabContents]; return; } diff --git a/chrome/browser/ui/cocoa/fullscreen_controller.h b/chrome/browser/ui/cocoa/presentation_mode_controller.h index 14aebfc..a5aec98 100644 --- a/chrome/browser/ui/cocoa/fullscreen_controller.h +++ b/chrome/browser/ui/cocoa/presentation_mode_controller.h @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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_UI_COCOA_FULLSCREEN_CONTROLLER_H_ -#define CHROME_BROWSER_UI_COCOA_FULLSCREEN_CONTROLLER_H_ +#ifndef CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_CONTROLLER_H_ +#define CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_CONTROLLER_H_ #pragma once #import <Cocoa/Cocoa.h> @@ -15,11 +15,11 @@ @class BrowserWindowController; @class DropdownAnimation; -// Provides a controller to manage fullscreen mode for a single browser window. -// This class handles running animations, showing and hiding the floating -// dropdown bar, and managing the tracking area associated with the dropdown. -// This class does not directly manage any views -- the BrowserWindowController -// is responsible for positioning and z-ordering views. +// Provides a controller to manage presentation mode for a single browser +// window. This class handles running animations, showing and hiding the +// floating dropdown bar, and managing the tracking area associated with the +// dropdown. This class does not directly manage any views -- the +// BrowserWindowController is responsible for positioning and z-ordering views. // // Tracking areas are disabled while animations are running. If // |overlayFrameChanged:| is called while an animation is running, the @@ -27,23 +27,26 @@ // when the animation finishes. This is largely done for ease of // implementation; it is easier to check the mouse location at each animation // step than it is to manage a constantly-changing tracking area. -@interface FullscreenController : NSObject<NSAnimationDelegate> { +@interface PresentationModeController : NSObject<NSAnimationDelegate> { @private // Our parent controller. BrowserWindowController* browserController_; // weak - // The content view for the fullscreen window. This is nil when not in - // fullscreen mode. + // The content view for the window. This is nil when not in presentation + // mode. NSView* contentView_; // weak - // Whether or not we are in fullscreen mode. - BOOL isFullscreen_; + // YES while this controller is in the process of entering presentation mode. + BOOL enteringPresentationMode_; + + // Whether or not we are in presentation mode. + BOOL inPresentationMode_; // The tracking area associated with the floating dropdown bar. This tracking // area is attached to |contentView_|, because when the dropdown is completely // hidden, we still need to keep a 1px tall tracking area visible. Attaching // to the content view allows us to do this. |trackingArea_| can be nil if - // not in fullscreen mode or during animations. + // not in presentation mode or during animations. scoped_nsobject<NSTrackingArea> trackingArea_; // Pointer to the currently running animation. Is nil if no animation is @@ -60,38 +63,38 @@ // completes. NSRect trackingAreaBounds_; - // Tracks the currently requested fullscreen mode. This should be - // |kFullScreenModeNormal| when the window is not main or not fullscreen, - // |kFullScreenModeHideAll| while the overlay is hidden, and - // |kFullScreenModeHideDock| while the overlay is shown. If the window is not - // on the primary screen, this should always be |kFullScreenModeNormal|. This - // value can get out of sync with the correct state if we miss a notification - // (which can happen when a fullscreen window is closed). Used to track the - // current state and make sure we properly restore the menu bar when this - // controller is destroyed. - base::mac::FullScreenMode currentFullscreenMode_; + // Tracks the currently requested system fullscreen mode, used to show or hide + // the menubar. This should be |kFullScreenModeNormal| when the window is not + // main or not fullscreen, |kFullScreenModeHideAll| while the overlay is + // hidden, and |kFullScreenModeHideDock| while the overlay is shown. If the + // window is not on the primary screen, this should always be + // |kFullScreenModeNormal|. This value can get out of sync with the correct + // state if we miss a notification (which can happen when a window is closed). + // Used to track the current state and make sure we properly restore the menu + // bar when this controller is destroyed. + base::mac::FullScreenMode systemFullscreenMode_; } -@property(readonly, nonatomic) BOOL isFullscreen; +@property(readonly, nonatomic) BOOL inPresentationMode; // Designated initializer. - (id)initWithBrowserController:(BrowserWindowController*)controller; -// Informs the controller that the browser has entered or exited fullscreen -// mode. |-enterFullscreenForContentView:showDropdown:| should be called after -// the fullscreen window is setup, just before it is shown. |-exitFullscreen| +// Informs the controller that the browser has entered or exited presentation +// mode. |-enterPresentationModeForContentView:showDropdown:| should be called +// after the window is setup, just before it is shown. |-exitPresentationMode| // should be called before any views are moved back to the non-fullscreen -// window. If |-enterFullscreenForContentView:showDropdown:| is called, it must -// be followed with a call to |-exitFullscreen| before the controller is -// released. -- (void)enterFullscreenForContentView:(NSView*)contentView - showDropdown:(BOOL)showDropdown; -- (void)exitFullscreen; +// window. If |-enterPresentationModeForContentView:showDropdown:| is called, +// it must be balanced with a call to |-exitPresentationMode| before the +// controller is released. +- (void)enterPresentationModeForContentView:(NSView*)contentView + showDropdown:(BOOL)showDropdown; +- (void)exitPresentationMode; // Returns the amount by which the floating bar should be offset downwards (to // avoid the menu) and by which the overlay view should be enlarged vertically. -// Generally, this is > 0 when the fullscreen window is on the primary screen -// and 0 otherwise. +// Generally, this is > 0 when the window is on the primary screen and 0 +// otherwise. - (CGFloat)floatingBarVerticalOffset; // Informs the controller that the overlay's frame has changed. The controller @@ -110,7 +113,7 @@ - (CGFloat)floatingBarShownFraction; // Sets a new current floating bar shown fraction. NOTE: This function has side -// effects, such as modifying the fullscreen mode (menu bar shown state). +// effects, such as modifying the system fullscreen mode (menu bar shown state). - (void)changeFloatingBarShownFraction:(CGFloat)fraction; @end @@ -119,4 +122,4 @@ extern NSString* const kWillEnterFullscreenNotification; extern NSString* const kWillLeaveFullscreenNotification; -#endif // CHROME_BROWSER_UI_COCOA_FULLSCREEN_CONTROLLER_H_ +#endif // CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/fullscreen_controller.mm b/chrome/browser/ui/cocoa/presentation_mode_controller.mm index 57a515a..35a20a5 100644 --- a/chrome/browser/ui/cocoa/fullscreen_controller.mm +++ b/chrome/browser/ui/cocoa/presentation_mode_controller.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/fullscreen_controller.h" +#import "chrome/browser/ui/cocoa/presentation_mode_controller.h" #include <algorithm> @@ -26,19 +26,19 @@ const NSTimeInterval kDropdownShowDelay = 0.3; const NSTimeInterval kDropdownHideDelay = 0.2; // The amount by which the floating bar is offset downwards (to avoid the menu) -// in fullscreen mode. (We can't use |-[NSMenu menuBarHeight]| since it returns -// 0 when the menu bar is hidden.) +// in presentation mode. (We can't use |-[NSMenu menuBarHeight]| since it +// returns 0 when the menu bar is hidden.) const CGFloat kFloatingBarVerticalOffset = 22; } // end namespace -// Helper class to manage animations for the fullscreen dropdown bar. Calls -// [FullscreenController changeFloatingBarShownFraction] once per animation -// step. +// Helper class to manage animations for the dropdown bar. Calls +// [PresentationModeController changeFloatingBarShownFraction] once per +// animation step. @interface DropdownAnimation : NSAnimation { @private - FullscreenController* controller_; + PresentationModeController* controller_; CGFloat startFraction_; CGFloat endFraction_; } @@ -52,7 +52,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; - (id)initWithFraction:(CGFloat)fromFraction fullDuration:(CGFloat)fullDuration animationCurve:(NSInteger)animationCurve - controller:(FullscreenController*)controller; + controller:(PresentationModeController*)controller; @end @@ -64,7 +64,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; - (id)initWithFraction:(CGFloat)toFraction fullDuration:(CGFloat)fullDuration animationCurve:(NSInteger)animationCurve - controller:(FullscreenController*)controller { + controller:(PresentationModeController*)controller { // Calculate the effective duration, based on the current shown fraction. DCHECK(controller); CGFloat fromFraction = [controller floatingBarShownFraction]; @@ -91,9 +91,9 @@ const CGFloat kFloatingBarVerticalOffset = 22; @end -@interface FullscreenController (PrivateMethods) +@interface PresentationModeController (PrivateMethods) -// Returns YES if the fullscreen window is on the primary screen. +// Returns YES if the window is on the primary screen. - (BOOL)isWindowOnPrimaryScreen; // Returns YES if it is ok to show and hide the menu bar in response to the @@ -103,7 +103,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; // Returns |kFullScreenModeHideAll| when the overlay is hidden and // |kFullScreenModeHideDock| when the overlay is shown. -- (base::mac::FullScreenMode)desiredFullscreenMode; +- (base::mac::FullScreenMode)desiredSystemFullscreenMode; // Change the overlay to the given fraction, with or without animation. Only // guaranteed to work properly with |fraction == 0| or |fraction == 1|. This @@ -151,23 +151,22 @@ const CGFloat kFloatingBarVerticalOffset = 22; - (void)cleanup; // Shows and hides the UI associated with this window being active (having main -// status). This includes hiding the menu bar and displaying the "Exit -// Fullscreen" button. These functions are called when the window gains or -// loses main status as well as in |-cleanup|. +// status). This includes hiding the menu bar. These functions are called when +// the window gains or loses main status as well as in |-cleanup|. - (void)showActiveWindowUI; - (void)hideActiveWindowUI; @end -@implementation FullscreenController +@implementation PresentationModeController -@synthesize isFullscreen = isFullscreen_; +@synthesize inPresentationMode = inPresentationMode_; - (id)initWithBrowserController:(BrowserWindowController*)controller { if ((self = [super init])) { browserController_ = controller; - currentFullscreenMode_ = base::mac::kFullScreenModeNormal; + systemFullscreenMode_ = base::mac::kFullScreenModeNormal; } // Let the world know what we're up to. @@ -179,30 +178,37 @@ const CGFloat kFloatingBarVerticalOffset = 22; } - (void)dealloc { - DCHECK(!isFullscreen_); + DCHECK(!inPresentationMode_); DCHECK(!trackingArea_); [super dealloc]; } -- (void)enterFullscreenForContentView:(NSView*)contentView - showDropdown:(BOOL)showDropdown { - DCHECK(!isFullscreen_); - isFullscreen_ = YES; +- (void)enterPresentationModeForContentView:(NSView*)contentView + showDropdown:(BOOL)showDropdown { + DCHECK(!inPresentationMode_); + enteringPresentationMode_ = YES; + inPresentationMode_ = YES; contentView_ = contentView; [self changeFloatingBarShownFraction:(showDropdown ? 1 : 0)]; // Register for notifications. Self is removed as an observer in |-cleanup|. NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; NSWindow* window = [browserController_ window]; - [nc addObserver:self - selector:@selector(windowDidChangeScreen:) - name:NSWindowDidChangeScreenNotification - object:window]; - [nc addObserver:self - selector:@selector(windowDidMove:) - name:NSWindowDidMoveNotification - object:window]; + // Disable these notifications on Lion as they cause crashes. + // TODO(rohitrao): Figure out what happens if a fullscreen window changes + // monitors on Lion. + if (base::mac::IsOSSnowLeopardOrEarlier()) { + [nc addObserver:self + selector:@selector(windowDidChangeScreen:) + name:NSWindowDidChangeScreenNotification + object:window]; + + [nc addObserver:self + selector:@selector(windowDidMove:) + name:NSWindowDidMoveNotification + object:window]; + } [nc addObserver:self selector:@selector(windowDidBecomeMain:) @@ -213,15 +219,17 @@ const CGFloat kFloatingBarVerticalOffset = 22; selector:@selector(windowDidResignMain:) name:NSWindowDidResignMainNotification object:window]; + + enteringPresentationMode_ = NO; } -- (void)exitFullscreen { +- (void)exitPresentationMode { [[NSNotificationCenter defaultCenter] postNotificationName:kWillLeaveFullscreenNotification object:nil]; - DCHECK(isFullscreen_); + DCHECK(inPresentationMode_); + inPresentationMode_ = NO; [self cleanup]; - isFullscreen_ = NO; } - (void)windowDidChangeScreen:(NSNotification*)notification { @@ -245,7 +253,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; } - (void)overlayFrameChanged:(NSRect)frame { - if (!isFullscreen_) + if (!inPresentationMode_) return; // Make sure |trackingAreaBounds_| always reflects either the tracking area or @@ -264,11 +272,17 @@ const CGFloat kFloatingBarVerticalOffset = 22; if (currentAnimation_) return; + // If this is part of the initial setup, lock bar visibility if the mouse is + // within the tracking area bounds. + if (enteringPresentationMode_ && [self mouseInsideTrackingRect]) + [browserController_ lockBarVisibilityForOwner:self + withAnimation:NO + delay:NO]; [self setupTrackingArea]; } - (void)ensureOverlayShownWithAnimation:(BOOL)animate delay:(BOOL)delay { - if (!isFullscreen_) + if (!inPresentationMode_) return; if (animate) { @@ -286,7 +300,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; } - (void)ensureOverlayHiddenWithAnimation:(BOOL)animate delay:(BOOL)delay { - if (!isFullscreen_) + if (!inPresentationMode_) return; if (animate) { @@ -316,19 +330,19 @@ const CGFloat kFloatingBarVerticalOffset = 22; - (void)changeFloatingBarShownFraction:(CGFloat)fraction { [browserController_ setFloatingBarShownFraction:fraction]; - base::mac::FullScreenMode desiredMode = [self desiredFullscreenMode]; - if (desiredMode != currentFullscreenMode_ && [self shouldToggleMenuBar]) { - if (currentFullscreenMode_ == base::mac::kFullScreenModeNormal) + base::mac::FullScreenMode desiredMode = [self desiredSystemFullscreenMode]; + if (desiredMode != systemFullscreenMode_ && [self shouldToggleMenuBar]) { + if (systemFullscreenMode_ == base::mac::kFullScreenModeNormal) base::mac::RequestFullScreen(desiredMode); else - base::mac::SwitchFullScreenModes(currentFullscreenMode_, desiredMode); - currentFullscreenMode_ = desiredMode; + base::mac::SwitchFullScreenModes(systemFullscreenMode_, desiredMode); + systemFullscreenMode_ = desiredMode; } } -// Used to activate the floating bar in fullscreen mode. +// Used to activate the floating bar in presentation mode. - (void)mouseEntered:(NSEvent*)event { - DCHECK(isFullscreen_); + DCHECK(inPresentationMode_); // Having gotten a mouse entered, we no longer need to do exit checks. [self cancelMouseExitCheck]; @@ -341,9 +355,9 @@ const CGFloat kFloatingBarVerticalOffset = 22; } } -// Used to deactivate the floating bar in fullscreen mode. +// Used to deactivate the floating bar in presentation mode. - (void)mouseExited:(NSEvent*)event { - DCHECK(isFullscreen_); + DCHECK(inPresentationMode_); NSTrackingArea* trackingArea = [event trackingArea]; if (trackingArea == trackingArea_) { @@ -393,7 +407,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; @end -@implementation FullscreenController (PrivateMethods) +@implementation PresentationModeController (PrivateMethods) - (BOOL)isWindowOnPrimaryScreen { NSScreen* screen = [[browserController_ window] screen]; @@ -402,11 +416,12 @@ const CGFloat kFloatingBarVerticalOffset = 22; } - (BOOL)shouldToggleMenuBar { - return [self isWindowOnPrimaryScreen] && + return base::mac::IsOSSnowLeopardOrEarlier() && + [self isWindowOnPrimaryScreen] && [[browserController_ window] isMainWindow]; } -- (base::mac::FullScreenMode)desiredFullscreenMode { +- (base::mac::FullScreenMode)desiredSystemFullscreenMode { if ([browserController_ floatingBarShownFraction] >= 1.0) return base::mac::kFullScreenModeHideDock; return base::mac::kFullScreenModeHideAll; @@ -594,7 +609,7 @@ const CGFloat kFloatingBarVerticalOffset = 22; [self removeTrackingAreaIfNecessary]; contentView_ = nil; - // This isn't tracked when not in fullscreen mode. + // This isn't tracked when not in presentation mode. [browserController_ releaseBarVisibilityForOwner:self withAnimation:NO delay:NO]; @@ -609,23 +624,23 @@ const CGFloat kFloatingBarVerticalOffset = 22; } - (void)showActiveWindowUI { - DCHECK_EQ(currentFullscreenMode_, base::mac::kFullScreenModeNormal); - if (currentFullscreenMode_ != base::mac::kFullScreenModeNormal) + DCHECK_EQ(systemFullscreenMode_, base::mac::kFullScreenModeNormal); + if (systemFullscreenMode_ != base::mac::kFullScreenModeNormal) return; if ([self shouldToggleMenuBar]) { - base::mac::FullScreenMode desiredMode = [self desiredFullscreenMode]; + base::mac::FullScreenMode desiredMode = [self desiredSystemFullscreenMode]; base::mac::RequestFullScreen(desiredMode); - currentFullscreenMode_ = desiredMode; + systemFullscreenMode_ = desiredMode; } // TODO(rohitrao): Insert the Exit Fullscreen button. http://crbug.com/35956 } - (void)hideActiveWindowUI { - if (currentFullscreenMode_ != base::mac::kFullScreenModeNormal) { - base::mac::ReleaseFullScreen(currentFullscreenMode_); - currentFullscreenMode_ = base::mac::kFullScreenModeNormal; + if (systemFullscreenMode_ != base::mac::kFullScreenModeNormal) { + base::mac::ReleaseFullScreen(systemFullscreenMode_); + systemFullscreenMode_ = base::mac::kFullScreenModeNormal; } // TODO(rohitrao): Remove the Exit Fullscreen button. http://crbug.com/35956 diff --git a/chrome/browser/ui/cocoa/presentation_mode_prefs.h b/chrome/browser/ui/cocoa/presentation_mode_prefs.h new file mode 100644 index 0000000..aa00c98 --- /dev/null +++ b/chrome/browser/ui/cocoa/presentation_mode_prefs.h @@ -0,0 +1,21 @@ +// Copyright (c) 2011 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_UI_COCOA_PRESENTATION_MODE_PREFS_H_ +#define CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_PREFS_H_ +#pragma once + +#include "base/basictypes.h" + +class PrefService; + +class PresentationModePrefs { + public: + static void RegisterUserPrefs(PrefService* prefs); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(PresentationModePrefs); +}; + +#endif // CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_PREFS_H_ diff --git a/chrome/browser/ui/cocoa/presentation_mode_prefs.mm b/chrome/browser/ui/cocoa/presentation_mode_prefs.mm new file mode 100644 index 0000000..b5224c1 --- /dev/null +++ b/chrome/browser/ui/cocoa/presentation_mode_prefs.mm @@ -0,0 +1,15 @@ +// Copyright (c) 2011 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. + +#include "chrome/browser/ui/cocoa/presentation_mode_prefs.h" + +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/pref_names.h" + +// static +void PresentationModePrefs::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterBooleanPref(prefs::kPresentationModeEnabled, + false, + PrefService::UNSYNCABLE_PREF); +} diff --git a/chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.mm index 80c3a15..152817b 100644 --- a/chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -23,7 +23,7 @@ if (self) { // Side tabs have no indent since they are not sharing space with the // window controls. - [self setIndentForControls:0.0]; + [self setLeftIndentForControls:0.0]; verticalLayout_ = YES; } return self; diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h index 96d0df4..179acea 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h @@ -140,9 +140,10 @@ class ToolbarModel; // The default favicon, so we can use one copy for all buttons. scoped_nsobject<NSImage> defaultFavicon_; - // The amount by which to indent the tabs on the left (to make room for the - // red/yellow/green buttons). - CGFloat indentForControls_; + // The amount by which to indent the tabs on the sides (to make room for the + // red/yellow/green and incognito/fullscreen buttons). + CGFloat leftIndentForControls_; + CGFloat rightIndentForControls_; // Manages per-tab sheets. scoped_nsobject<GTMWindowSheetController> sheetController_; @@ -154,7 +155,8 @@ class ToolbarModel; scoped_ptr<HoverTabSelector> hoverTabSelector_; } -@property(nonatomic) CGFloat indentForControls; +@property(nonatomic) CGFloat leftIndentForControls; +@property(nonatomic) CGFloat rightIndentForControls; // Initialize the controller with a view and browser that contains // everything else we'll need. |switchView| is the view whose contents get @@ -226,6 +228,7 @@ class ToolbarModel; // Force the tabs to rearrange themselves to reflect the current model. - (void)layoutTabs; +- (void)layoutTabsWithoutAnimation; // Are we in rapid (tab) closure mode? I.e., is a full layout deferred (while // the user closes tabs)? Needed to overcome missing clicks during rapid tab @@ -239,8 +242,8 @@ class ToolbarModel; // Default height for tabs. + (CGFloat)defaultTabHeight; -// Default indentation for tabs (see |indentForControls_|). -+ (CGFloat)defaultIndentForControls; +// Default indentation for tabs (see |leftIndentForControls_|). ++ (CGFloat)defaultLeftIndentForControls; // Returns the (lazily created) window sheet controller of this window. Used // for the per-tab sheets. diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index 3a7da38..43f2a21 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm @@ -97,10 +97,6 @@ const CGFloat kIconWidthAndHeight = 16.0; // The amount by which the new tab button is offset (from the tabs). const CGFloat kNewTabButtonOffset = 8.0; -// The amount by which to shrink the tab strip (on the right) when the -// incognito badge is present. -const CGFloat kAvatarTabStripShrink = 18; - // Time (in seconds) in which tabs animate to their final position. const NSTimeInterval kAnimationDuration = 0.125; @@ -309,7 +305,8 @@ private: @implementation TabStripController -@synthesize indentForControls = indentForControls_; +@synthesize leftIndentForControls = leftIndentForControls_; +@synthesize rightIndentForControls = rightIndentForControls_; - (id)initWithView:(TabStripView*)view switchView:(NSView*)switchView @@ -337,7 +334,8 @@ private: defaultFavicon_.reset( [gfx::GetCachedImageWithName(@"nav.pdf") retain]); - [self setIndentForControls:[[self class] defaultIndentForControls]]; + [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]]; + [self setRightIndentForControls:0]; // TODO(viettrungluu): WTF? "For some reason, if the view is present in the // nib a priori, it draws correctly. If we create it in code and add it to @@ -469,7 +467,7 @@ private: return 25.0; } -+ (CGFloat)defaultIndentForControls { ++ (CGFloat)defaultLeftIndentForControls { // Default indentation leaves enough room so tabs don't overlap with the // window controls. return 70.0; @@ -790,8 +788,9 @@ private: - (BOOL)isTabFullyVisible:(TabView*)tab { NSRect frame = [tab frame]; - return NSMinX(frame) >= [self indentForControls] && - NSMaxX(frame) <= NSMaxX([tabStripView_ frame]); + return NSMinX(frame) >= [self leftIndentForControls] && + NSMaxX(frame) <= (NSMaxX([tabStripView_ frame]) - + [self rightIndentForControls]); } - (void)showNewTabButton:(BOOL)show { @@ -839,18 +838,11 @@ private: } else { availableSpace = NSWidth([tabStripView_ frame]); - BrowserWindowController* controller = - (BrowserWindowController*)[[tabStripView_ window] windowController]; - - // Account for the widths of the new tab button or the avatar, if any/all - // are present. + // Account for the width of the new tab button. availableSpace -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset; - if ([controller respondsToSelector:@selector(shouldShowAvatar)] && - [controller shouldShowAvatar]) { - availableSpace -= kAvatarTabStripShrink; - } } - availableSpace -= [self indentForControls]; + availableSpace -= [self leftIndentForControls]; + availableSpace -= [self rightIndentForControls]; } // This may be negative, but that's okay (taken care of by |MAX()| when @@ -880,7 +872,7 @@ private: BOOL visible = [[tabStripView_ window] isVisible]; - CGFloat offset = [self indentForControls]; + CGFloat offset = [self leftIndentForControls]; bool hasPlaceholderGap = false; for (TabController* tab in tabArray_.get()) { // Ignore a tab that is going through a close animation. @@ -1042,6 +1034,10 @@ private: [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:YES]; } +- (void)layoutTabsWithoutAnimation { + [self layoutTabsWithAnimation:NO regenerateSubviews:YES]; +} + // Handles setting the title of the tab based on the given |contents|. Uses // a canned string if |contents| is NULL. - (void)setTabTitle:(NSViewController*)tab withContents:(TabContents*)contents { diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index 425d925..afce02d 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -383,6 +383,15 @@ void Panel::ToggleTabStripMode() { void Panel::OpenTabpose() { NOTIMPLEMENTED(); } + +void Panel::SetPresentationMode(bool presentation_mode) { + NOTIMPLEMENTED(); +} + +bool Panel::InPresentationMode() { + NOTIMPLEMENTED(); + return false; +} #endif void Panel::PrepareForInstant() { diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index dd44022..d55a74f 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -131,6 +131,8 @@ class Panel : public BrowserWindow { virtual void ToggleTabStripMode() OVERRIDE; #if defined(OS_MACOSX) virtual void OpenTabpose() OVERRIDE; + virtual void SetPresentationMode(bool presentation_mode) OVERRIDE; + virtual bool InPresentationMode() OVERRIDE; #endif virtual void PrepareForInstant() OVERRIDE; virtual void ShowInstant(TabContentsWrapper* preview) OVERRIDE; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a993302..8cface4 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2478,8 +2478,6 @@ 'browser/ui/cocoa/focus_tracker.mm', 'browser/ui/cocoa/framed_browser_window.h', 'browser/ui/cocoa/framed_browser_window.mm', - 'browser/ui/cocoa/fullscreen_controller.h', - 'browser/ui/cocoa/fullscreen_controller.mm', 'browser/ui/cocoa/fullscreen_window.h', 'browser/ui/cocoa/fullscreen_window.mm', 'browser/ui/cocoa/gesture_utils.h', @@ -2595,6 +2593,10 @@ 'browser/ui/cocoa/omnibox/omnibox_view_mac.mm', 'browser/ui/cocoa/page_info_bubble_controller.h', 'browser/ui/cocoa/page_info_bubble_controller.mm', + 'browser/ui/cocoa/presentation_mode_controller.h', + 'browser/ui/cocoa/presentation_mode_controller.mm', + 'browser/ui/cocoa/presentation_mode_prefs.h', + 'browser/ui/cocoa/presentation_mode_prefs.mm', 'browser/ui/cocoa/profile_menu_controller.h', 'browser/ui/cocoa/profile_menu_controller.mm', 'browser/ui/cocoa/repost_form_warning_mac.h', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 573c735..fd8833d 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -742,6 +742,11 @@ const char kEnableHyperlinkAuditing[] = "enable_a_ping"; // Whether to enable sending referrers. const char kEnableReferrers[] = "enable_referrers"; +#if defined(OS_MACOSX) +// Whether presentation mode is enabled for fullscreen (used on Lion only). +const char kPresentationModeEnabled[] = "presentation_mode_enabled"; +#endif + #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX) // The local profile id for this profile. const char kLocalProfileId[] = "profile.local_profile_id"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 3d008e4..6b54fa8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -254,6 +254,10 @@ extern const char kDisable3DAPIs[]; extern const char kEnableHyperlinkAuditing[]; extern const char kEnableReferrers[]; +#if defined(OS_MACOSX) +extern const char kPresentationModeEnabled[]; +#endif + #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX) extern const char kLocalProfileId[]; extern const char kPasswordsUseLocalProfileId[]; diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index ac82c36..b355beb 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc @@ -88,6 +88,12 @@ int TestBrowserWindow::GetExtraRenderViewHeight() const { return 0; } +#if defined(OS_MACOSX) +bool TestBrowserWindow::InPresentationMode() { + return false; +} +#endif + gfx::Rect TestBrowserWindow::GetInstantBounds() { return gfx::Rect(); } diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 171d77e..7502698 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -102,6 +102,8 @@ class TestBrowserWindow : public BrowserWindow { virtual void ToggleTabStripMode() OVERRIDE {} #if defined(OS_MACOSX) virtual void OpenTabpose() OVERRIDE {} + virtual void SetPresentationMode(bool presentation_mode) OVERRIDE {} + virtual bool InPresentationMode() OVERRIDE; #endif virtual void PrepareForInstant() OVERRIDE {} |