summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-04 22:18:23 +0000
committerrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-04 22:18:23 +0000
commitd3766937d96f44abf9cfe5df3518fff8fc54bb90 (patch)
tree0c09efe8df64cb603200fed14d2ff1a298fd8a2e
parent96958c0ab3bbce1cadfadd94cb85da4a2fe9e737 (diff)
downloadchromium_src-d3766937d96f44abf9cfe5df3518fff8fc54bb90.zip
chromium_src-d3766937d96f44abf9cfe5df3518fff8fc54bb90.tar.gz
chromium_src-d3766937d96f44abf9cfe5df3518fff8fc54bb90.tar.bz2
Fullscreen support for Lion.
XIB changes: - Add new "Enter Presentation Mode" menu item with Cmd-Shift-F. - Change key equivalent for "Enter Full Screen" to Cmd-Opt-F. On Lion: This CL separates the concepts of "fullscreen mode" and "presentation mode." Fullscreen mode uses Lion's fullscreen mode and places the window in its own space. Presentation mode is an extra option to additionally hide the UI when in fullscreen mode. On Lion, clicking on the fullscreen button takes you into fullscreen mode, in which there is a button to toggle presentation mode on or off. While in normal windowed mode, there are two menu options to either "Enter Full Screen" or "Enter Presentation Mode" directly. On Snow Leopard: This CL does not change much on Snow Leopard. To maintain consistency with the new Lion terminology, the "Enter Full Screen" menu item has been renamed to "Enter Presentation Mode." BUG=74065 TEST=Fullscreen works in Lion. Fullscreen continues to work as before in Snow Leopard. Review URL: http://codereview.chromium.org/7566016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95518 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/chrome_command_ids.h1
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/app/nibs/MainMenu.xib34
-rw-r--r--chrome/browser/prefs/browser_prefs.cc7
-rw-r--r--chrome/browser/ui/browser.cc13
-rw-r--r--chrome/browser/ui/browser.h3
-rw-r--r--chrome/browser/ui/browser_window.h5
-rw-r--r--chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm2
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.h2
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.mm8
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller.h72
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller.mm290
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller_private.h76
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller_private.mm445
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller_unittest.mm10
-rw-r--r--chrome/browser/ui/cocoa/download/download_shelf_controller.mm2
-rw-r--r--chrome/browser/ui/cocoa/framed_browser_window.h3
-rw-r--r--chrome/browser/ui/cocoa/framed_browser_window.mm27
-rw-r--r--chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm2
-rw-r--r--chrome/browser/ui/cocoa/presentation_mode_controller.h (renamed from chrome/browser/ui/cocoa/fullscreen_controller.h)79
-rw-r--r--chrome/browser/ui/cocoa/presentation_mode_controller.mm (renamed from chrome/browser/ui/cocoa/fullscreen_controller.mm)131
-rw-r--r--chrome/browser/ui/cocoa/presentation_mode_prefs.h21
-rw-r--r--chrome/browser/ui/cocoa/presentation_mode_prefs.mm15
-rw-r--r--chrome/browser/ui/cocoa/tabs/side_tab_strip_controller.mm4
-rw-r--r--chrome/browser/ui/cocoa/tabs/tab_strip_controller.h15
-rw-r--r--chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm36
-rw-r--r--chrome/browser/ui/panels/panel.cc9
-rw-r--r--chrome/browser/ui/panels/panel.h2
-rw-r--r--chrome/chrome_browser.gypi6
-rw-r--r--chrome/common/pref_names.cc5
-rw-r--r--chrome/common/pref_names.h4
-rw-r--r--chrome/test/base/test_browser_window.cc6
-rw-r--r--chrome/test/base/test_browser_window.h2
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 {}