summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/browser_theme_provider_init.h19
-rw-r--r--chrome/browser/cocoa/browser_theme_provider_init.mm178
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h117
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm991
-rw-r--r--chrome/browser/cocoa/browser_window_controller_private.h108
-rw-r--r--chrome/browser/cocoa/browser_window_controller_private.mm440
-rwxr-xr-xchrome/chrome_browser.gypi4
7 files changed, 990 insertions, 867 deletions
diff --git a/chrome/browser/cocoa/browser_theme_provider_init.h b/chrome/browser/cocoa/browser_theme_provider_init.h
new file mode 100644
index 0000000..0959e9c
--- /dev/null
+++ b/chrome/browser/cocoa/browser_theme_provider_init.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COCOA_BROWSER_THEME_PROVIDER_INIT_H_
+#define CHROME_BROWSER_COCOA_BROWSER_THEME_PROVIDER_INIT_H_
+
+#import "third_party/GTM/AppKit/GTMTheme.h"
+
+class BrowserThemeProvider;
+
+// Provides a routine to initialize GTMTheme with data from a provided
+// |BrowserThemeProvider|.
+@interface GTMTheme(BrowserThemeProviderInitialization)
++ (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider
+ isOffTheRecord:(BOOL)offTheRecord;
+@end
+
+#endif // CHROME_BROWSER_COCOA_BROWSER_THEME_PROVIDER_INIT_H_
diff --git a/chrome/browser/cocoa/browser_theme_provider_init.mm b/chrome/browser/cocoa/browser_theme_provider_init.mm
new file mode 100644
index 0000000..baf5226
--- /dev/null
+++ b/chrome/browser/cocoa/browser_theme_provider_init.mm
@@ -0,0 +1,178 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/browser_theme_provider_init.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include <map>
+#include <string>
+#include <utility>
+
+#import "base/scoped_nsobject.h"
+#include "chrome/browser/browser_theme_provider.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+
+
+@implementation GTMTheme(BrowserThemeProviderInitialization)
+
++ (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider
+ isOffTheRecord:(BOOL)isOffTheRecord {
+ // First check if it's in the cache.
+ typedef std::pair<std::string, BOOL> ThemeKey;
+ static std::map<ThemeKey, GTMTheme*> cache;
+ ThemeKey key(provider->GetThemeID(), isOffTheRecord);
+ GTMTheme* theme = cache[key];
+ if (theme)
+ return theme;
+
+ theme = [[GTMTheme alloc] init]; // "Leak" it in the cache.
+ cache[key] = theme;
+
+ // TODO(pinkerton): Need to be able to theme the entire incognito window
+ // http://crbug.com/18568 The hardcoding of the colors here will need to be
+ // removed when that bug is addressed, but are here in order for things to be
+ // usable in the meantime.
+ if (isOffTheRecord) {
+ NSColor* incognitoColor = [NSColor colorWithCalibratedRed:83/255.0
+ green:108.0/255.0
+ blue:140/255.0
+ alpha:1.0];
+ [theme setBackgroundColor:incognitoColor];
+ [theme setValue:[NSColor blackColor]
+ forAttribute:@"textColor"
+ style:GTMThemeStyleTabBarSelected
+ state:GTMThemeStateActiveWindow];
+ [theme setValue:[NSColor blackColor]
+ forAttribute:@"textColor"
+ style:GTMThemeStyleTabBarDeselected
+ state:GTMThemeStateActiveWindow];
+ [theme setValue:[NSColor blackColor]
+ forAttribute:@"textColor"
+ style:GTMThemeStyleBookmarksBarButton
+ state:GTMThemeStateActiveWindow];
+ [theme setValue:[NSColor blackColor]
+ forAttribute:@"iconColor"
+ style:GTMThemeStyleToolBarButton
+ state:GTMThemeStateActiveWindow];
+ return theme;
+ }
+
+ NSImage* frameImage = provider->GetNSImageNamed(IDR_THEME_FRAME);
+ NSImage* frameInactiveImage =
+ provider->GetNSImageNamed(IDR_THEME_FRAME_INACTIVE);
+
+ [theme setValue:frameImage
+ forAttribute:@"backgroundImage"
+ style:GTMThemeStyleWindow
+ state:GTMThemeStateActiveWindow];
+
+ NSColor* tabTextColor =
+ provider->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT);
+ [theme setValue:tabTextColor
+ forAttribute:@"textColor"
+ style:GTMThemeStyleTabBarSelected
+ state:GTMThemeStateActiveWindow];
+
+ NSColor* tabInactiveTextColor =
+ provider->GetNSColor(BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT);
+ [theme setValue:tabInactiveTextColor
+ forAttribute:@"textColor"
+ style:GTMThemeStyleTabBarDeselected
+ state:GTMThemeStateActiveWindow];
+
+ NSColor* bookmarkBarTextColor =
+ provider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
+ [theme setValue:bookmarkBarTextColor
+ forAttribute:@"textColor"
+ style:GTMThemeStyleBookmarksBarButton
+ state:GTMThemeStateActiveWindow];
+
+ [theme setValue:frameInactiveImage
+ forAttribute:@"backgroundImage"
+ style:GTMThemeStyleWindow
+ state:0];
+
+ NSImage* toolbarImage = provider->GetNSImageNamed(IDR_THEME_TOOLBAR);
+ [theme setValue:toolbarImage
+ forAttribute:@"backgroundImage"
+ style:GTMThemeStyleToolBar
+ state:GTMThemeStateActiveWindow];
+ NSImage* toolbarBackgroundImage =
+ provider->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND);
+ [theme setValue:toolbarBackgroundImage
+ forAttribute:@"backgroundImage"
+ style:GTMThemeStyleTabBarDeselected
+ state:GTMThemeStateActiveWindow];
+
+ NSImage* toolbarButtonImage =
+ provider->GetNSImageNamed(IDR_THEME_BUTTON_BACKGROUND);
+ if (toolbarButtonImage) {
+ [theme setValue:toolbarButtonImage
+ forAttribute:@"backgroundImage"
+ style:GTMThemeStyleToolBarButton
+ state:GTMThemeStateActiveWindow];
+ } else {
+ NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.0];
+ NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.3];
+ scoped_nsobject<NSGradient> gradient([[NSGradient alloc]
+ initWithStartingColor:startColor
+ endingColor:endColor]);
+
+ [theme setValue:gradient
+ forAttribute:@"gradient"
+ style:GTMThemeStyleToolBarButton
+ state:GTMThemeStateActiveWindow];
+
+ [theme setValue:gradient
+ forAttribute:@"gradient"
+ style:GTMThemeStyleToolBarButton
+ state:GTMThemeStateActiveWindow];
+ }
+
+ NSColor* toolbarButtonIconColor =
+ provider->GetNSColorTint(BrowserThemeProvider::TINT_BUTTONS);
+ [theme setValue:toolbarButtonIconColor
+ forAttribute:@"iconColor"
+ style:GTMThemeStyleToolBarButton
+ state:GTMThemeStateActiveWindow];
+
+ NSColor* toolbarButtonBorderColor = toolbarButtonIconColor;
+ [theme setValue:toolbarButtonBorderColor
+ forAttribute:@"borderColor"
+ style:GTMThemeStyleToolBar
+ state:GTMThemeStateActiveWindow];
+
+ NSColor* toolbarBackgroundColor =
+ provider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR);
+ [theme setValue:toolbarBackgroundColor
+ forAttribute:@"backgroundColor"
+ style:GTMThemeStyleToolBar
+ state:GTMThemeStateActiveWindow];
+
+ NSImage* frameOverlayImage =
+ provider->GetNSImageNamed(IDR_THEME_FRAME_OVERLAY);
+ if (frameOverlayImage) {
+ [theme setValue:frameOverlayImage
+ forAttribute:@"overlay"
+ style:GTMThemeStyleWindow
+ state:GTMThemeStateActiveWindow];
+ }
+
+ NSImage* frameOverlayInactiveImage =
+ provider->GetNSImageNamed(IDR_THEME_FRAME_OVERLAY_INACTIVE);
+ if (frameOverlayInactiveImage) {
+ [theme setValue:frameOverlayInactiveImage
+ forAttribute:@"overlay"
+ style:GTMThemeStyleWindow
+ state:GTMThemeStateInactiveWindow];
+ }
+
+ return theme;
+}
+
+
+@end // @implementation GTMTheme(BrowserThemeProviderInitialization)
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index db0364f..ad38462 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -23,6 +23,7 @@
#include "chrome/browser/sync/sync_ui_util.h"
#import "third_party/GTM/AppKit/GTMTheme.h"
+
class Browser;
class BrowserWindow;
class BrowserWindowCocoa;
@@ -42,6 +43,7 @@ class TabStripModelObserverBridge;
@class ToolbarController;
@class TitlebarController;
+
@interface BrowserWindowController :
TabWindowController<NSUserInterfaceValidations,
BookmarkBarControllerDelegate,
@@ -130,12 +132,18 @@ class TabStripModelObserverBridge;
// Access the C++ bridge between the NSWindow and the rest of Chromium.
- (BrowserWindow*)browserWindow;
-// Access the C++ bridge object representing the location bar.
-- (LocationBar*)locationBarBridge;
+// Return a weak pointer to the toolbar controller.
+- (ToolbarController*)toolbarController;
+
+// Return a weak pointer to the tab strip controller.
+- (TabStripController*)tabStripController;
// Access the C++ bridge object representing the status bubble for the window.
- (StatusBubbleMac*)statusBubble;
+// Access the C++ bridge object representing the location bar.
+- (LocationBar*)locationBarBridge;
+
// Updates the toolbar (and transitively the location bar) with the states of
// the specified |tab|. If |shouldRestore| is true, we're switching
// (back?) to this tab and should restore any previous location bar state
@@ -164,6 +172,57 @@ class TabStripModelObserverBridge;
// coordinates (origin in bottom-left).
- (NSRect)regularWindowFrame;
+- (BOOL)isBookmarkBarVisible;
+
+// Called after bookmark bar visibility changes (due to pref change or change in
+// tab/tab contents).
+- (void)updateBookmarkBarVisibilityWithAnimation:(BOOL)animate;
+
+- (BOOL)isDownloadShelfVisible;
+
+// Lazily creates the download shelf in visible state if it doesn't exist yet.
+- (DownloadShelfController*)downloadShelf;
+
+// Retains the given FindBarCocoaController and adds its view to this
+// browser window. Must only be called once per
+// BrowserWindowController.
+- (void)addFindBar:(FindBarCocoaController*)findBarCocoaController;
+
+// The user changed the theme.
+- (void)userChangedTheme;
+
+// Executes the command in the context of the current browser.
+// |command| is an integer value containing one of the constants defined in the
+// "chrome/app/chrome_dll_resource.h" file.
+- (void)executeCommand:(int)command;
+
+// Delegate method for the status bubble to query about its vertical offset.
+- (float)verticalOffsetForStatusBubble;
+
+// Show the bookmark bubble (e.g. user just clicked on the STAR)
+- (void)showBookmarkBubbleForURL:(const GURL&)url
+ alreadyBookmarked:(BOOL)alreadyBookmarked;
+
+// Returns the (lazily created) window sheet controller of this window. Used
+// for the per-tab sheets.
+- (GTMWindowSheetController*)sheetController;
+
+// Requests that |window| is opened as a per-tab sheet to the current tab.
+- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window;
+// Closes the tab sheet |window| and potentially shows the next sheet in the
+// tab's sheet queue.
+- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window;
+
+// Shows or hides the docked web inspector depending on |contents|'s state.
+- (void)updateDevToolsForContents:(TabContents*)contents;
+
+@end // @interface BrowserWindowController
+
+
+// Methods having to do with the window type (normal/popup/app, and whether the
+// window has various features; fullscreen methods are separate).
+@interface BrowserWindowController(WindowType)
+
// Determines whether this controller's window supports a given feature (i.e.,
// whether a given feature is or can be shown in the window).
// TODO(viettrungluu): |feature| is really should be |Browser::Feature|, but I
@@ -191,27 +250,11 @@ class TabStripModelObserverBridge;
// pop-up window). Returns YES if it is, NO otherwise.
- (BOOL)isNormalWindow;
-- (BOOL)isBookmarkBarVisible;
+@end // @interface BrowserWindowController(WindowType)
-// Called after bookmark bar visibility changes (due to pref change or change in
-// tab/tab contents).
-- (void)updateBookmarkBarVisibilityWithAnimation:(BOOL)animate;
-// Return a weak pointer to the tab strip controller.
-- (TabStripController*)tabStripController;
-
-// Return a weak pointer to the toolbar controller.
-- (ToolbarController*)toolbarController;
-
-- (BOOL)isDownloadShelfVisible;
-
-// Lazily creates the download shelf in visible state if it doesn't exist yet.
-- (DownloadShelfController*)downloadShelf;
-
-// Retains the given FindBarCocoaController and adds its view to this
-// browser window. Must only be called once per
-// BrowserWindowController.
-- (void)addFindBar:(FindBarCocoaController*)findBarCocoaController;
+// Methods having to do with fullscreen mode.
+@interface BrowserWindowController(Fullscreen)
// Enters (or exits) fullscreen mode.
- (void)setFullscreen:(BOOL)fullscreen;
@@ -245,35 +288,8 @@ class TabStripModelObserverBridge;
// Returns YES if any of the views in the floating bar currently has focus.
- (BOOL)floatingBarHasFocus;
-// The user changed the theme.
-- (void)userChangedTheme;
+@end // @interface BrowserWindowController(Fullscreen)
-// Executes the command in the context of the current browser.
-// |command| is an integer value containing one of the constants defined in the
-// "chrome/app/chrome_dll_resource.h" file.
-- (void)executeCommand:(int)command;
-
-// Delegate method for the status bubble to query about its vertical offset.
-- (float)verticalOffsetForStatusBubble;
-
-// Show the bookmark bubble (e.g. user just clicked on the STAR)
-- (void)showBookmarkBubbleForURL:(const GURL&)url
- alreadyBookmarked:(BOOL)alreadyBookmarked;
-
-// Returns the (lazily created) window sheet controller of this window. Used
-// for the per-tab sheets.
-- (GTMWindowSheetController*)sheetController;
-
-// Requests that |window| is opened as a per-tab sheet to the current tab.
-- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window;
-// Closes the tab sheet |window| and potentially shows the next sheet in the
-// tab's sheet queue.
-- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window;
-
-// Shows or hides the docked web inspector depending on |contents|'s state.
-- (void)updateDevToolsForContents:(TabContents*)contents;
-
-@end
// Methods which are either only for testing, or only public for testing.
@interface BrowserWindowController(TestingAPI)
@@ -305,6 +321,7 @@ class TabStripModelObserverBridge;
// or the download shelf), so that future shrinking will occur from the bottom.
- (void)resetWindowGrowthState;
-@end // BrowserWindowController(TestingAPI)
+@end // @interface BrowserWindowController(TestingAPI)
+
#endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index c646528..4818b52 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -12,32 +12,25 @@
#import "base/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#include "chrome/app/chrome_dll_resource.h" // IDC_*
-#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/dock_info.h"
#include "chrome/browser/encoding_menu_controller.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/window_sizer.h"
-#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents/tab_contents_view.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/bookmarks/bookmark_editor.h"
#import "chrome/browser/cocoa/autocomplete_text_field_editor.h"
#import "chrome/browser/cocoa/background_gradient_view.h"
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
#import "chrome/browser/cocoa/bookmark_editor_controller.h"
#import "chrome/browser/cocoa/browser_window_cocoa.h"
-#import "chrome/browser/cocoa/chrome_browser_window.h"
+#import "chrome/browser/cocoa/browser_window_controller_private.h"
#import "chrome/browser/cocoa/download_shelf_controller.h"
#import "chrome/browser/cocoa/event_utils.h"
#import "chrome/browser/cocoa/fast_resize_view.h"
#import "chrome/browser/cocoa/find_bar_cocoa_controller.h"
-#include "chrome/browser/cocoa/find_bar_bridge.h"
-#import "chrome/browser/cocoa/floating_bar_backing_view.h"
+#import "chrome/browser/cocoa/find_bar_bridge.h"
#import "chrome/browser/cocoa/focus_tracker.h"
#import "chrome/browser/cocoa/fullscreen_controller.h"
#import "chrome/browser/cocoa/fullscreen_window.h"
@@ -46,37 +39,51 @@
#import "chrome/browser/cocoa/status_bubble_mac.h"
#import "chrome/browser/cocoa/tab_contents_controller.h"
#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
-#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_strip_controller.h"
+#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_view.h"
#import "chrome/browser/cocoa/toolbar_controller.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/sync_ui_util_mac.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
-#include "grit/generated_resources.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
#include "grit/locale_settings.h"
-#include "grit/theme_resources.h"
-#import "third_party/GTM/AppKit/GTMTheme.h"
+
// ORGANIZATION: This is a big file. It is (in principle) organized as follows
// (in order):
-// 1. Interfaces, including for our private methods. Very short, one-time-use
-// classes may include an implementation immediately after their interface.
+// 1. Interfaces. Very short, one-time-use classes may include an implementation
+// immediately after their interface.
// 2. The general implementation section, ordered as follows:
// i. Public methods and overrides.
// ii. Overrides/implementations of undocumented methods.
// iii. Delegate methods for various protocols, formal and informal, to which
// |BrowserWindowController| conforms.
-// 3. The private implementation section (|BrowserWindowController (Private)|).
-// 4. Implementation for |GTMTheme (BrowserThemeProviderInitialization)|.
+// 3. (temporary) Implementation sections for various categories.
+//
+// Private methods are defined and implemented separately in
+// browser_window_controller_private.{h,mm}.
//
// Not all of the above guidelines are followed and more (re-)organization is
// needed. BUT PLEASE TRY TO KEEP THIS FILE ORGANIZED. I'd rather re-organize as
// little as possible, since doing so messes up the file's history.
//
-// TODO(viettrungluu): (re-)organize some more, possibly split into separate
-// files?
+// TODO(viettrungluu): [crbug.com/35543] on-going re-organization, splitting
+// things into multiple files -- the plan is as follows:
+// - in general, everything stays in browser_window_controller.h, but is split
+// off into categories (see below)
+// - core stuff stays in browser_window_controller.mm
+// - ... overrides also stay (without going into a category, in particular)
+// - private stuff which everyone needs goes into
+// browser_window_controller_private.{h,mm}; if no one else needs them, they
+// can go in individual files (see below)
+// - area/task-specific stuff go in browser_window_controller_<area>.mm
+// - ... in categories called "(<Area>)" or "(<PrivateArea>)"
+// Plan of action:
+// - first re-organize into categories
+// - then split into files
// Notes on self-inflicted (not user-inflicted) window resizing and moving:
//
@@ -119,25 +126,8 @@
// longer indicate that the window is shrinking from an apparent zoomed state)
// and if it's set we continue to constrain the resize.
-namespace {
-// Insets for the location bar, used when the full toolbar is hidden.
-// TODO(viettrungluu): We can argue about the "correct" insetting; I like the
-// following best, though arguably 0 inset is better/more correct.
-const CGFloat kLocBarLeftRightInset = 1;
-const CGFloat kLocBarTopInset = 0;
-const CGFloat kLocBarBottomInset = 1;
-
-// The amount by which the floating bar is offset downwards (to avoid the menu)
-// in fullscreen mode.
-const CGFloat kFullscreenVerticalBarOffset = 14;
-} // end namespace
-
-@interface GTMTheme (BrowserThemeProviderInitialization)
-+ (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider
- isOffTheRecord:(BOOL)offTheRecord;
-@end
-@interface NSWindow (NSPrivateApis)
+@interface NSWindow(NSPrivateApis)
// Note: These functions are private, use -[NSObject respondsToSelector:]
// before calling them.
@@ -147,95 +137,6 @@ const CGFloat kFullscreenVerticalBarOffset = 14;
@end
-@interface BrowserWindowController(Private)
-
-// Saves the window's position in the local state preferences.
-- (void)saveWindowPositionIfNeeded;
-
-// Saves the window's position to the given pref service.
-- (void)saveWindowPositionToPrefs:(PrefService*)prefs;
-
-// We need to adjust where sheets come out of the window, as by default they
-// erupt from the omnibox, which is rather weird.
-- (NSRect)window:(NSWindow*)window
-willPositionSheet:(NSWindow*)sheet
- usingRect:(NSRect)defaultSheetRect;
-
-// Assign a theme to the window.
-- (void)setTheme;
-
-// Repositions the window's subviews. From the top down: toolbar, normal
-// bookmark bar (if shown), infobar, NTP detached bookmark bar (if shown),
-// 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.
-- (CGFloat)floatingBarHeight;
-
-// 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.
-- (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
- width:(CGFloat)width
- fullscreen:(BOOL)fullscreen;
-
-// Lays out the toolbar (or just location bar for popups) at the given maximum
-// y-coordinate, with the given width; returns the new maximum y (below the
-// toolbar).
-- (CGFloat)layoutToolbarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
-
-// Returns YES if the bookmark bar should be placed below the infobar, NO
-// otherwise.
-- (BOOL)placeBookmarkBarBelowInfoBar;
-
-// Lays out the bookmark bar at the given maximum y-coordinate, with the given
-// width; returns the new maximum y (below the bookmark bar). Note that one must
-// call it with the appropriate |maxY| which depends on whether or not the
-// bookmark bar is shown as the NTP bubble or not (use
-// |-placeBookmarkBarBelowInfoBar|).
-- (CGFloat)layoutBookmarkBarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
-
-// Lay out the view which draws the background for the floating bar when in
-// fullscreen mode, with the given (minimum) y-coordinate, width, height, and
-// fullscreen-mode-status. Should be called even when not in fullscreen mode to
-// hide the backing view.
-- (void)layoutFloatingBarBackingViewAtY:(CGFloat)y
- width:(CGFloat)width
- height:(CGFloat)height
- fullscreen:(BOOL)fullscreen;
-
-// Lays out the infobar at the given maximum y-coordinate, with the given width;
-// returns the new maximum y (below the infobar).
-- (CGFloat)layoutInfoBarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
-
-// Lays out the download shelf, if there is one, at the given minimum
-// y-coordinate, with the given width; returns the new minimum y (above the
-// download shelf). This is safe to call even if there is no download shelf.
-- (CGFloat)layoutDownloadShelfAtMinY:(CGFloat)minY width:(CGFloat)width;
-
-// Lays out the tab content area between the given minimum and maximum
-// y-coordinates, with the given width.
-- (void)layoutTabContentAreaAtMinY:(CGFloat)minY
- maxY:(CGFloat)maxY
- width:(CGFloat)width;
-
-// Should we show the normal bookmark bar?
-- (BOOL)shouldShowBookmarkBar;
-
-// Is the current page one for which the bookmark should be shown detached *if*
-// the normal bookmark bar is not shown?
-- (BOOL)shouldShowDetachedBookmarkBar;
-
-// Sets the toolbar's height to a value appropriate for the given compression.
-// Also adjusts the bookmark bar's height by the opposite amount in order to
-// 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;
-
-@end
// IncognitoImageView subclasses NSImageView to allow mouse events to pass
// through it so you can drag the window by dragging on the spy guy
@@ -248,6 +149,7 @@ willPositionSheet:(NSWindow*)sheet
}
@end
+
@implementation BrowserWindowController
+ (BrowserWindowController*)browserWindowControllerForView:(NSView*)view {
@@ -264,7 +166,7 @@ willPositionSheet:(NSWindow*)sheet
return [self initWithBrowser:browser takeOwnership:YES];
}
-// Private (TestingAPI) init routine with testing options.
+// Private(TestingAPI) init routine with testing options.
- (id)initWithBrowser:(Browser*)browser takeOwnership:(BOOL)ownIt {
// Use initWithWindowNibPath:: instead of initWithWindowNibName: so we
// can override it in a unit test.
@@ -413,11 +315,26 @@ willPositionSheet:(NSWindow*)sheet
[super dealloc];
}
-// Access the C++ bridge between the NSWindow and the rest of Chromium
- (BrowserWindow*)browserWindow {
return windowShim_.get();
}
+- (ToolbarController*)toolbarController {
+ return toolbarController_.get();
+}
+
+- (TabStripController*)tabStripController {
+ return tabStripController_.get();
+}
+
+- (StatusBubbleMac*)statusBubble {
+ return statusBubble_;
+}
+
+- (LocationBar*)locationBarBridge {
+ return [toolbarController_ locationBarBridge];
+}
+
- (void)destroyBrowser {
[NSApp removeWindowsItem:[self window]];
@@ -1038,14 +955,6 @@ willPositionSheet:(NSWindow*)sheet
return [tabStripController_ sheetController];
}
-- (LocationBar*)locationBarBridge {
- return [toolbarController_ locationBarBridge];
-}
-
-- (StatusBubbleMac*)statusBubble {
- return statusBubble_;
-}
-
- (void)updateToolbarWithContents:(TabContents*)tab
shouldRestoreState:(BOOL)shouldRestore {
[toolbarController_ updateToolbarWithContents:tab
@@ -1162,14 +1071,6 @@ willPositionSheet:(NSWindow*)sheet
return [tabStripController_ selectedTabView];
}
-- (TabStripController*)tabStripController {
- return tabStripController_.get();
-}
-
-- (ToolbarController*)toolbarController {
- return toolbarController_.get();
-}
-
- (void)setIsLoading:(BOOL)isLoading {
[toolbarController_ setIsLoading:isLoading];
}
@@ -1320,146 +1221,6 @@ willPositionSheet:(NSWindow*)sheet
autorelease];
}
-- (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;
-
- // 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];
-
- // 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(nil);
- }
-
- // Retain the tab strip view while we remove it from its superview.
- scoped_nsobject<NSView> tabStripView;
- if ([self hasTabStrip]) {
- tabStripView.reset([[self tabStripView] retain]);
- [tabStripView removeFromSuperview];
- }
-
- // 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];
-
- // Add the tabstrip after setting the content view, so that the tab strip will
- // be on top (in the z-order).
- if ([self hasTabStrip])
- [[[destWindow contentView] superview] addSubview:tabStripView];
-
- [window setWindowController:nil];
- [self setWindow:destWindow];
- [destWindow setWindowController:self];
- [self adjustUIForFullscreen:fullscreen];
-
- // 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];
- } else {
- [self layoutSubviews];
- }
-
- // The window needs to be onscreen before we can set its first responder.
- [destWindow makeKeyAndOrderFront:self];
- [focusTracker restoreFocusInWindow:destWindow];
- [window orderOut:self];
-}
-
-- (BOOL)isFullscreen {
- return savedRegularWindow_ != nil;
-}
-
-- (CGFloat)floatingBarShownFraction {
- return floatingBarShownFraction_;
-}
-
-- (void)setFloatingBarShownFraction:(CGFloat)fraction {
- floatingBarShownFraction_ = fraction;
- [self layoutSubviews];
-}
-
-- (BOOL)isBarVisibilityLockedForOwner:(id)owner {
- DCHECK(owner);
- DCHECK(barVisibilityLocks_);
- return [barVisibilityLocks_ containsObject:owner];
-}
-
-- (void)lockBarVisibilityForOwner:(id)owner
- withAnimation:(BOOL)animate
- delay:(BOOL)delay {
- if (![self isBarVisibilityLockedForOwner:owner]) {
- [barVisibilityLocks_ addObject:owner];
-
- // Show the overlay if necessary (and if in fullscreen mode).
- [fullscreenController_ ensureOverlayShownWithAnimation:animate
- delay:delay];
- }
-}
-
-- (void)releaseBarVisibilityForOwner:(id)owner
- withAnimation:(BOOL)animate
- delay:(BOOL)delay {
- if ([self isBarVisibilityLockedForOwner:owner]) {
- [barVisibilityLocks_ removeObject:owner];
-
- // Hide the overlay if necessary (and if in fullscreen mode).
- if (![barVisibilityLocks_ count]) {
- [fullscreenController_ ensureOverlayHiddenWithAnimation:animate
- delay:delay];
- }
- }
-}
-
-- (BOOL)floatingBarHasFocus {
- NSResponder* focused = [[self window] firstResponder];
- return [focused isKindOfClass:[AutocompleteTextFieldEditor class]];
-}
-
- (NSInteger)numberOfTabs {
return browser_->tabstrip_model()->count();
}
@@ -1469,11 +1230,6 @@ willPositionSheet:(NSWindow*)sheet
return base::SysUTF16ToNSString(contents->GetTitle());
}
-- (BOOL)supportsWindowFeature:(int)feature {
- return browser_->SupportsWindowFeature(
- static_cast<Browser::WindowFeature>(feature));
-}
-
- (NSRect)regularWindowFrame {
return [self isFullscreen] ? [savedRegularWindow_ frame] :
[[self window] frame];
@@ -1484,26 +1240,6 @@ willPositionSheet:(NSWindow*)sheet
return [self supportsWindowFeature:Browser::FEATURE_TABSTRIP];
}
-- (BOOL)hasTitleBar {
- return [self supportsWindowFeature:Browser::FEATURE_TITLEBAR];
-}
-
-- (BOOL)hasToolbar {
- return [self supportsWindowFeature:Browser::FEATURE_TOOLBAR];
-}
-
-- (BOOL)hasLocationBar {
- return [self supportsWindowFeature:Browser::FEATURE_LOCATIONBAR];
-}
-
-- (BOOL)supportsBookmarkBar {
- return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR];
-}
-
-- (BOOL)isNormalWindow {
- return browser_->type() == Browser::TYPE_NORMAL;
-}
-
- (void)selectTabWithContents:(TabContents*)newContents
previousContents:(TabContents*)oldContents
atIndex:(NSInteger)index
@@ -1844,558 +1580,179 @@ willAnimateFromState:(bookmarks::VisualState)oldState
isShrinkingFromZoomed_ = NO;
}
-@end
+@end // @implementation BrowserWindowController
-@implementation BrowserWindowController (Private)
-- (void)saveWindowPositionIfNeeded {
- if (browser_ != BrowserList::GetLastActive())
- return;
+@implementation BrowserWindowController(Fullscreen)
+
+- (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 (!g_browser_process || !g_browser_process->local_state() ||
- !browser_->ShouldSaveWindowPlacement())
+ if (fullscreen == [self isFullscreen])
return;
- [self saveWindowPositionToPrefs:g_browser_process->local_state()];
-}
-
-- (void)saveWindowPositionToPrefs:(PrefService*)prefs {
- // If we're in fullscreen mode, save the position of the regular window
- // instead.
- NSWindow* window = [self isFullscreen] ? savedRegularWindow_ : [self window];
-
- // Window positions are stored relative to the origin of the primary monitor.
- NSRect monitorFrame = [[[NSScreen screens] objectAtIndex:0] frame];
-
- // Start with the window's frame, which is in virtual coordinates.
- // Do some y twiddling to flip the coordinate system.
- gfx::Rect bounds(NSRectToCGRect([window frame]));
- bounds.set_y(monitorFrame.size.height - bounds.y() - bounds.height());
-
- // We also need to save the current work area, in flipped coordinates.
- gfx::Rect workArea(NSRectToCGRect([[window screen] visibleFrame]));
- workArea.set_y(monitorFrame.size.height - workArea.y() - workArea.height());
-
- DictionaryValue* windowPreferences = prefs->GetMutableDictionary(
- browser_->GetWindowPlacementKey().c_str());
- windowPreferences->SetInteger(L"left", bounds.x());
- windowPreferences->SetInteger(L"top", bounds.y());
- windowPreferences->SetInteger(L"right", bounds.right());
- windowPreferences->SetInteger(L"bottom", bounds.bottom());
- windowPreferences->SetBoolean(L"maximized", false);
- windowPreferences->SetBoolean(L"always_on_top", false);
- windowPreferences->SetInteger(L"work_area_left", workArea.x());
- windowPreferences->SetInteger(L"work_area_top", workArea.y());
- windowPreferences->SetInteger(L"work_area_right", workArea.right());
- windowPreferences->SetInteger(L"work_area_bottom", workArea.bottom());
-}
-
-- (NSRect)window:(NSWindow*)window
-willPositionSheet:(NSWindow*)sheet
- usingRect:(NSRect)defaultSheetRect {
- // Position the sheet as follows:
- // - If the bookmark bar is hidden or shown as a bubble (on the NTP when the
- // bookmark bar is disabled), position the sheet immediately below the
- // normal toolbar.
- // - If the bookmark bar is shown (attached to the normal toolbar), position
- // the sheet below the bookmark bar.
- // - If the bookmark bar is currently animating, position the sheet according
- // to where the bar will be when the animation ends.
- switch ([bookmarkBarController_ visualState]) {
- case bookmarks::kShowingState: {
- NSRect bookmarkBarFrame = [[bookmarkBarController_ view] frame];
- defaultSheetRect.origin.y = bookmarkBarFrame.origin.y;
- break;
- }
- case bookmarks::kHiddenState:
- case bookmarks::kDetachedState: {
- NSRect toolbarFrame = [[toolbarController_ view] frame];
- defaultSheetRect.origin.y = toolbarFrame.origin.y;
- break;
- }
- case bookmarks::kInvalidState:
- default:
- NOTREACHED();
- }
- return defaultSheetRect;
-}
-
-- (void)setTheme {
- ThemeProvider* theme_provider = browser_->profile()->GetThemeProvider();
- BrowserThemeProvider* browser_theme_provider =
- static_cast<BrowserThemeProvider*>(theme_provider);
- if (browser_theme_provider) {
- bool offtheRecord = browser_->profile()->IsOffTheRecord();
- GTMTheme* theme =
- [GTMTheme themeWithBrowserThemeProvider:browser_theme_provider
- isOffTheRecord:offtheRecord];
- theme_.reset([theme retain]);
- }
-}
+ if (![self supportsFullscreen])
+ return;
-- (void)layoutSubviews {
- // With the exception of the tab strip, the subviews which we lay out are
- // subviews of the content view, so we mainly work in the content view's
- // coordinate system. Note, however, that the content view's coordinate system
- // and the window's base coordinate system should coincide.
+ // Save the current first responder so we can restore after views are moved.
NSWindow* window = [self window];
- NSView* contentView = [window contentView];
- NSRect contentBounds = [contentView bounds];
- CGFloat minY = NSMinY(contentBounds);
- CGFloat width = NSWidth(contentBounds);
-
- // Suppress title drawing if necessary.
- if ([window respondsToSelector:@selector(setShouldHideTitle:)])
- [(id)window setShouldHideTitle:![self hasTitleBar]];
+ scoped_nsobject<FocusTracker> focusTracker(
+ [[FocusTracker alloc] initWithWindow:window]);
+ BOOL showDropdown = [self floatingBarHasFocus];
- BOOL isFullscreen = [self isFullscreen];
- CGFloat floatingBarHeight = [self floatingBarHeight];
- CGFloat yOffset = floor(
- isFullscreen ? (1 - floatingBarShownFraction_) * floatingBarHeight : 0);
- CGFloat maxY = NSMaxY(contentBounds) + yOffset;
- CGFloat startMaxY = maxY;
+ // 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(nil);
+ }
+ // Retain the tab strip view while we remove it from its superview.
+ scoped_nsobject<NSView> tabStripView;
if ([self hasTabStrip]) {
- // If we need to lay out the tab strip, replace |maxY| and |startMaxY| with
- // higher values, and then lay out the tab strip.
- startMaxY = maxY = NSHeight([window frame]) + yOffset;
- maxY = [self layoutTabStripAtMaxY:maxY width:width fullscreen:isFullscreen];
+ tabStripView.reset([[self tabStripView] retain]);
+ [tabStripView removeFromSuperview];
}
- // Sanity-check |maxY|.
- DCHECK_GE(maxY, minY);
- DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
-
- // Place the toolbar at the top of the reserved area.
- maxY = [self layoutToolbarAtMaxY:maxY width:width];
-
- // If we're not displaying the bookmark bar below the infobar, then it goes
- // immediately below the toolbar.
- BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
- if (!placeBookmarkBarBelowInfoBar)
- maxY = [self layoutBookmarkBarAtMaxY:maxY width:width];
-
- // The floating bar backing view doesn't actually add any height.
- [self layoutFloatingBarBackingViewAtY:maxY
- width:width
- height:floatingBarHeight
- fullscreen:isFullscreen];
+ // 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];
- [fullscreenController_ overlayFrameChanged:[floatingBarBackingView_ frame]];
+ NSWindow* destWindow = nil;
+ if (fullscreen) {
+ DCHECK(!savedRegularWindow_);
+ savedRegularWindow_ = [window retain];
+ destWindow = [self createFullscreenWindow];
+ } else {
+ DCHECK(savedRegularWindow_);
+ destWindow = [savedRegularWindow_ autorelease];
+ savedRegularWindow_ = nil;
+ }
+ DCHECK(destWindow);
- // 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.
- [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width];
+ // Have to do this here, otherwise later calls can crash because the window
+ // has no delegate.
+ [window setDelegate:nil];
+ [destWindow setDelegate:self];
- // 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)
- maxY = NSMaxY(contentBounds);
+ // 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];
- // 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.
- maxY = [self layoutInfoBarAtMaxY:maxY width:width];
+ // Add the tabstrip after setting the content view, so that the tab strip will
+ // be on top (in the z-order).
+ if ([self hasTabStrip])
+ [[[destWindow contentView] superview] addSubview:tabStripView];
- // If the bookmark bar is detached, place it next in the visual content area.
- if (placeBookmarkBarBelowInfoBar)
- maxY = [self layoutBookmarkBarAtMaxY:maxY width:width];
+ [window setWindowController:nil];
+ [self setWindow:destWindow];
+ [destWindow setWindowController:self];
+ [self adjustUIForFullscreen:fullscreen];
- // Place the download shelf, if any, at the bottom of the view.
- minY = [self layoutDownloadShelfAtMinY:minY width:width];
+ // 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];
+ } else {
+ [self layoutSubviews];
+ }
- // Finally, the content area takes up all of the remaining space.
- [self layoutTabContentAreaAtMinY:minY maxY:maxY width:width];
+ // The window needs to be onscreen before we can set its first responder.
+ [destWindow makeKeyAndOrderFront:self];
+ [focusTracker restoreFocusInWindow:destWindow];
+ [window orderOut:self];
+}
- // Place the status bubble at the bottom of the content area.
- verticalOffsetForStatusBubble_ = minY;
+- (BOOL)isFullscreen {
+ return savedRegularWindow_ != nil;
+}
- // Normally, we don't need to tell the toolbar whether or not to show the
- // divider, but things break down during animation.
- [toolbarController_
- setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
+- (CGFloat)floatingBarShownFraction {
+ return floatingBarShownFraction_;
}
-- (CGFloat)floatingBarHeight {
- if (![self isFullscreen])
- return 0;
+- (void)setFloatingBarShownFraction:(CGFloat)fraction {
+ floatingBarShownFraction_ = fraction;
+ [self layoutSubviews];
+}
- CGFloat totalHeight = kFullscreenVerticalBarOffset;
+- (BOOL)isBarVisibilityLockedForOwner:(id)owner {
+ DCHECK(owner);
+ DCHECK(barVisibilityLocks_);
+ return [barVisibilityLocks_ containsObject:owner];
+}
- if ([self hasTabStrip])
- totalHeight += NSHeight([[self tabStripView] frame]);
+- (void)lockBarVisibilityForOwner:(id)owner
+ withAnimation:(BOOL)animate
+ delay:(BOOL)delay {
+ if (![self isBarVisibilityLockedForOwner:owner]) {
+ [barVisibilityLocks_ addObject:owner];
- if ([self hasToolbar]) {
- totalHeight += NSHeight([[toolbarController_ view] frame]);
- } else if ([self hasLocationBar]) {
- totalHeight += NSHeight([[toolbarController_ view] frame]) +
- kLocBarTopInset + kLocBarBottomInset;
+ // Show the overlay if necessary (and if in fullscreen mode).
+ [fullscreenController_ ensureOverlayShownWithAnimation:animate
+ delay:delay];
}
-
- if (![self placeBookmarkBarBelowInfoBar])
- totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
-
- return totalHeight;
}
-- (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
- width:(CGFloat)width
- fullscreen:(BOOL)fullscreen {
- // Nothing to do if no tab strip.
- if (![self hasTabStrip])
- return maxY;
-
- NSView* tabStripView = [self tabStripView];
- CGFloat tabStripHeight = NSHeight([tabStripView frame]);
- // In fullscreen mode, push the tab strip down so that the main menu (which
- // also slides down) doesn't run it over.
- if (fullscreen)
- maxY -= kFullscreenVerticalBarOffset;
- maxY -= tabStripHeight;
- [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)];
-
- // Set indentation.
- [tabStripController_ setIndentForControls:(fullscreen ? 0 :
- [[tabStripController_ class] defaultIndentForControls])];
-
- // TODO(viettrungluu): Seems kind of bad -- shouldn't |-layoutSubviews| do
- // this? Moreover, |-layoutTabs| will try to animate....
- [tabStripController_ layoutTabs];
-
- return maxY;
-}
+- (void)releaseBarVisibilityForOwner:(id)owner
+ withAnimation:(BOOL)animate
+ delay:(BOOL)delay {
+ if ([self isBarVisibilityLockedForOwner:owner]) {
+ [barVisibilityLocks_ removeObject:owner];
-- (CGFloat)layoutToolbarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
- NSView* toolbarView = [toolbarController_ view];
- NSRect toolbarFrame = [toolbarView frame];
- if ([self hasToolbar]) {
- // The toolbar is present in the window, so we make room for it.
- DCHECK(![toolbarView isHidden]);
- toolbarFrame.origin.x = 0;
- toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame);
- toolbarFrame.size.width = width;
- maxY -= NSHeight(toolbarFrame);
- } else {
- if ([self hasLocationBar]) {
- // Location bar is present with no toolbar. Put a border of
- // |kLocBar...Inset| pixels around the location bar.
- // TODO(viettrungluu): This is moderately ridiculous. The toolbar should
- // really be aware of what its height should be (the way the toolbar
- // compression stuff is currently set up messes things up).
- DCHECK(![toolbarView isHidden]);
- toolbarFrame.origin.x = kLocBarLeftRightInset;
- toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame) - kLocBarTopInset;
- toolbarFrame.size.width = width - 2 * kLocBarLeftRightInset;
- maxY -= kLocBarTopInset + NSHeight(toolbarFrame) + kLocBarBottomInset;
- } else {
- DCHECK([toolbarView isHidden]);
- }
- }
- [toolbarView setFrame:toolbarFrame];
- return maxY;
-}
-
-- (BOOL)placeBookmarkBarBelowInfoBar {
- // If we are currently displaying the NTP detached bookmark bar or animating
- // to/from it (from/to anything else), we display the bookmark bar below the
- // infobar.
- return [bookmarkBarController_ isInState:bookmarks::kDetachedState] ||
- [bookmarkBarController_ isAnimatingToState:bookmarks::kDetachedState] ||
- [bookmarkBarController_ isAnimatingFromState:bookmarks::kDetachedState];
-}
-
-- (CGFloat)layoutBookmarkBarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
- NSView* bookmarkBarView = [bookmarkBarController_ view];
- NSRect bookmarkBarFrame = [bookmarkBarView frame];
- BOOL oldHidden = [bookmarkBarView isHidden];
- BOOL newHidden = ![self isBookmarkBarVisible];
- if (oldHidden != newHidden)
- [bookmarkBarView setHidden:newHidden];
- bookmarkBarFrame.origin.y = maxY - NSHeight(bookmarkBarFrame);
- bookmarkBarFrame.size.width = width;
- [bookmarkBarView setFrame:bookmarkBarFrame];
- maxY -= NSHeight(bookmarkBarFrame);
-
- // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be
- // necessary in the non-NTP case.
- [bookmarkBarController_ layoutSubviews];
-
- return maxY;
-}
-
-- (void)layoutFloatingBarBackingViewAtY:(CGFloat)y
- width:(CGFloat)width
- height:(CGFloat)height
- fullscreen:(BOOL)fullscreen {
- // Only display when in fullscreen mode.
- if (fullscreen) {
- DCHECK(floatingBarBackingView_.get());
- BOOL aboveBookmarkBar = [self placeBookmarkBarBelowInfoBar];
-
- // Insert it into the view hierarchy if necessary.
- if (![floatingBarBackingView_ superview] ||
- aboveBookmarkBar != floatingBarAboveBookmarkBar_) {
- NSView* contentView = [[self window] contentView];
- // z-order gets messed up unless we explicitly remove the floatingbar view
- // and re-add it.
- [floatingBarBackingView_ removeFromSuperview];
- [contentView addSubview:floatingBarBackingView_
- positioned:(aboveBookmarkBar ?
- NSWindowAbove : NSWindowBelow)
- relativeTo:[bookmarkBarController_ view]];
- floatingBarAboveBookmarkBar_ = aboveBookmarkBar;
+ // Hide the overlay if necessary (and if in fullscreen mode).
+ if (![barVisibilityLocks_ count]) {
+ [fullscreenController_ ensureOverlayHiddenWithAnimation:animate
+ delay:delay];
}
-
- // Set its frame.
- [floatingBarBackingView_ setFrame:NSMakeRect(0, y, width, height)];
- } else {
- // Okay to call even if |floatingBarBackingView_| is nil.
- if ([floatingBarBackingView_ superview])
- [floatingBarBackingView_ removeFromSuperview];
}
}
-- (CGFloat)layoutInfoBarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
- NSView* infoBarView = [infoBarContainerController_ view];
- NSRect infoBarFrame = [infoBarView frame];
- infoBarFrame.origin.y = maxY - NSHeight(infoBarFrame);
- infoBarFrame.size.width = width;
- [infoBarView setFrame:infoBarFrame];
- maxY -= NSHeight(infoBarFrame);
- return maxY;
-}
-
-- (CGFloat)layoutDownloadShelfAtMinY:(CGFloat)minY width:(CGFloat)width {
- if (downloadShelfController_.get()) {
- NSView* downloadView = [downloadShelfController_ view];
- NSRect downloadFrame = [downloadView frame];
- downloadFrame.origin.y = minY;
- downloadFrame.size.width = width;
- [downloadView setFrame:downloadFrame];
- minY += NSHeight(downloadFrame);
- }
- return minY;
+- (BOOL)floatingBarHasFocus {
+ NSResponder* focused = [[self window] firstResponder];
+ return [focused isKindOfClass:[AutocompleteTextFieldEditor class]];
}
-- (void)layoutTabContentAreaAtMinY:(CGFloat)minY
- maxY:(CGFloat)maxY
- width:(CGFloat)width {
- NSView* tabContentView = [self tabContentArea];
- NSRect tabContentFrame = [tabContentView frame];
+@end // @implementation BrowserWindowController(Fullscreen)
- bool contentShifted = NSMaxY(tabContentFrame) != maxY;
- tabContentFrame.origin.y = minY;
- tabContentFrame.size.height = maxY - minY;
- tabContentFrame.size.width = width;
- [tabContentView setFrame:tabContentFrame];
+@implementation BrowserWindowController(WindowType)
- // If the relayout shifts the content area up or down, let the renderer know.
- if (contentShifted) {
- if (TabContents* contents = browser_->GetSelectedTabContents()) {
- if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
- rwhv->WindowFrameChanged();
- }
- }
+- (BOOL)supportsWindowFeature:(int)feature {
+ return browser_->SupportsWindowFeature(
+ static_cast<Browser::WindowFeature>(feature));
}
-- (BOOL)shouldShowBookmarkBar {
- DCHECK(browser_.get());
- return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) ?
- YES : NO;
+- (BOOL)hasTitleBar {
+ return [self supportsWindowFeature:Browser::FEATURE_TITLEBAR];
}
-- (BOOL)shouldShowDetachedBookmarkBar {
- DCHECK(browser_.get());
- TabContents* contents = browser_->GetSelectedTabContents();
- return (contents && contents->ShouldShowBookmarkBar()) ? YES : NO;
+- (BOOL)hasToolbar {
+ return [self supportsWindowFeature:Browser::FEATURE_TOOLBAR];
}
-- (void)adjustToolbarAndBookmarkBarForCompression:(CGFloat)compression {
- CGFloat newHeight =
- [toolbarController_ desiredHeightForCompression:compression];
- NSRect toolbarFrame = [[toolbarController_ view] frame];
- CGFloat deltaH = newHeight - toolbarFrame.size.height;
-
- if (deltaH == 0)
- return;
-
- toolbarFrame.size.height = newHeight;
- NSRect bookmarkFrame = [[bookmarkBarController_ view] frame];
- bookmarkFrame.size.height = bookmarkFrame.size.height - deltaH;
- [[toolbarController_ view] setFrame:toolbarFrame];
- [[bookmarkBarController_ view] setFrame:bookmarkFrame];
- [self layoutSubviews];
+- (BOOL)hasLocationBar {
+ return [self supportsWindowFeature:Browser::FEATURE_LOCATIONBAR];
}
-- (void)adjustUIForFullscreen:(BOOL)fullscreen {
- if (fullscreen) {
- mac_util::RequestFullScreen();
-
- // Create the floating bar backing view if necessary.
- if (!floatingBarBackingView_.get()) {
- floatingBarBackingView_.reset(
- [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]);
- }
- } else {
- mac_util::ReleaseFullScreen();
- }
+- (BOOL)supportsBookmarkBar {
+ return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR];
}
-@end // @implementation BrowserWindowController (Private)
-
-@implementation GTMTheme (BrowserThemeProviderInitialization)
-+ (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider
- isOffTheRecord:(BOOL)isOffTheRecord {
- // First check if it's in the cache.
- typedef std::pair<std::string, BOOL> ThemeKey;
- static std::map<ThemeKey, GTMTheme*> cache;
- ThemeKey key(provider->GetThemeID(), isOffTheRecord);
- GTMTheme* theme = cache[key];
- if (theme)
- return theme;
-
- theme = [[GTMTheme alloc] init]; // "Leak" it in the cache.
- cache[key] = theme;
-
- // TODO(pinkerton): Need to be able to theme the entire incognito window
- // http://crbug.com/18568 The hardcoding of the colors here will need to be
- // removed when that bug is addressed, but are here in order for things to be
- // usable in the meantime.
- if (isOffTheRecord) {
- NSColor* incognitoColor = [NSColor colorWithCalibratedRed:83/255.0
- green:108.0/255.0
- blue:140/255.0
- alpha:1.0];
- [theme setBackgroundColor:incognitoColor];
- [theme setValue:[NSColor blackColor]
- forAttribute:@"textColor"
- style:GTMThemeStyleTabBarSelected
- state:GTMThemeStateActiveWindow];
- [theme setValue:[NSColor blackColor]
- forAttribute:@"textColor"
- style:GTMThemeStyleTabBarDeselected
- state:GTMThemeStateActiveWindow];
- [theme setValue:[NSColor blackColor]
- forAttribute:@"textColor"
- style:GTMThemeStyleBookmarksBarButton
- state:GTMThemeStateActiveWindow];
- [theme setValue:[NSColor blackColor]
- forAttribute:@"iconColor"
- style:GTMThemeStyleToolBarButton
- state:GTMThemeStateActiveWindow];
- return theme;
- }
-
- NSImage* frameImage = provider->GetNSImageNamed(IDR_THEME_FRAME);
- NSImage* frameInactiveImage =
- provider->GetNSImageNamed(IDR_THEME_FRAME_INACTIVE);
-
- [theme setValue:frameImage
- forAttribute:@"backgroundImage"
- style:GTMThemeStyleWindow
- state:GTMThemeStateActiveWindow];
-
- NSColor* tabTextColor =
- provider->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT);
- [theme setValue:tabTextColor
- forAttribute:@"textColor"
- style:GTMThemeStyleTabBarSelected
- state:GTMThemeStateActiveWindow];
-
- NSColor* tabInactiveTextColor =
- provider->GetNSColor(BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT);
- [theme setValue:tabInactiveTextColor
- forAttribute:@"textColor"
- style:GTMThemeStyleTabBarDeselected
- state:GTMThemeStateActiveWindow];
-
- NSColor* bookmarkBarTextColor =
- provider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
- [theme setValue:bookmarkBarTextColor
- forAttribute:@"textColor"
- style:GTMThemeStyleBookmarksBarButton
- state:GTMThemeStateActiveWindow];
-
- [theme setValue:frameInactiveImage
- forAttribute:@"backgroundImage"
- style:GTMThemeStyleWindow
- state:0];
-
- NSImage* toolbarImage = provider->GetNSImageNamed(IDR_THEME_TOOLBAR);
- [theme setValue:toolbarImage
- forAttribute:@"backgroundImage"
- style:GTMThemeStyleToolBar
- state:GTMThemeStateActiveWindow];
- NSImage* toolbarBackgroundImage =
- provider->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND);
- [theme setValue:toolbarBackgroundImage
- forAttribute:@"backgroundImage"
- style:GTMThemeStyleTabBarDeselected
- state:GTMThemeStateActiveWindow];
-
- NSImage* toolbarButtonImage =
- provider->GetNSImageNamed(IDR_THEME_BUTTON_BACKGROUND);
- if (toolbarButtonImage) {
- [theme setValue:toolbarButtonImage
- forAttribute:@"backgroundImage"
- style:GTMThemeStyleToolBarButton
- state:GTMThemeStateActiveWindow];
- } else {
- NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.0];
- NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.3];
- scoped_nsobject<NSGradient> gradient([[NSGradient alloc]
- initWithStartingColor:startColor
- endingColor:endColor]);
-
- [theme setValue:gradient
- forAttribute:@"gradient"
- style:GTMThemeStyleToolBarButton
- state:GTMThemeStateActiveWindow];
-
- [theme setValue:gradient
- forAttribute:@"gradient"
- style:GTMThemeStyleToolBarButton
- state:GTMThemeStateActiveWindow];
- }
-
- NSColor* toolbarButtonIconColor =
- provider->GetNSColorTint(BrowserThemeProvider::TINT_BUTTONS);
- [theme setValue:toolbarButtonIconColor
- forAttribute:@"iconColor"
- style:GTMThemeStyleToolBarButton
- state:GTMThemeStateActiveWindow];
-
- NSColor* toolbarButtonBorderColor = toolbarButtonIconColor;
- [theme setValue:toolbarButtonBorderColor
- forAttribute:@"borderColor"
- style:GTMThemeStyleToolBar
- state:GTMThemeStateActiveWindow];
-
- NSColor* toolbarBackgroundColor =
- provider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR);
- [theme setValue:toolbarBackgroundColor
- forAttribute:@"backgroundColor"
- style:GTMThemeStyleToolBar
- state:GTMThemeStateActiveWindow];
-
- NSImage* frameOverlayImage =
- provider->GetNSImageNamed(IDR_THEME_FRAME_OVERLAY);
- if (frameOverlayImage) {
- [theme setValue:frameOverlayImage
- forAttribute:@"overlay"
- style:GTMThemeStyleWindow
- state:GTMThemeStateActiveWindow];
- }
-
- NSImage* frameOverlayInactiveImage =
- provider->GetNSImageNamed(IDR_THEME_FRAME_OVERLAY_INACTIVE);
- if (frameOverlayInactiveImage) {
- [theme setValue:frameOverlayInactiveImage
- forAttribute:@"overlay"
- style:GTMThemeStyleWindow
- state:GTMThemeStateInactiveWindow];
- }
-
- return theme;
+- (BOOL)isNormalWindow {
+ return browser_->type() == Browser::TYPE_NORMAL;
}
-@end
+
+@end // @implementation BrowserWindowController(WindowType)
diff --git a/chrome/browser/cocoa/browser_window_controller_private.h b/chrome/browser/cocoa/browser_window_controller_private.h
new file mode 100644
index 0000000..3ae054a
--- /dev/null
+++ b/chrome/browser/cocoa/browser_window_controller_private.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COCOA_BROWSER_WINDOW_CONTROLLER_PRIVATE_H_
+#define CHROME_BROWSER_COCOA_BROWSER_WINDOW_CONTROLLER_PRIVATE_H_
+
+#import "chrome/browser/cocoa/browser_window_controller.h"
+
+
+// Private methods for the |BrowserWindowController|. This category should
+// contain the private methods used by different parts of the BWC; private
+// methods used only by single parts should be declared in their own file.
+// TODO(viettrungluu): [crbug.com/35543] work on splitting out stuff from the
+// BWC, and figuring out which methods belong here (need to unravel
+// "dependencies").
+@interface BrowserWindowController(Private)
+
+// Saves the window's position in the local state preferences.
+- (void)saveWindowPositionIfNeeded;
+
+// Saves the window's position to the given pref service.
+- (void)saveWindowPositionToPrefs:(PrefService*)prefs;
+
+// We need to adjust where sheets come out of the window, as by default they
+// erupt from the omnibox, which is rather weird.
+- (NSRect)window:(NSWindow*)window
+ willPositionSheet:(NSWindow*)sheet
+ usingRect:(NSRect)defaultSheetRect;
+
+// Assign a theme to the window.
+- (void)setTheme;
+
+// Repositions the window's subviews. From the top down: toolbar, normal
+// bookmark bar (if shown), infobar, NTP detached bookmark bar (if shown),
+// 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.
+- (CGFloat)floatingBarHeight;
+
+// 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.
+- (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
+ width:(CGFloat)width
+ fullscreen:(BOOL)fullscreen;
+
+// Lays out the toolbar (or just location bar for popups) at the given maximum
+// y-coordinate, with the given width; returns the new maximum y (below the
+// toolbar).
+- (CGFloat)layoutToolbarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
+
+// Returns YES if the bookmark bar should be placed below the infobar, NO
+// otherwise.
+- (BOOL)placeBookmarkBarBelowInfoBar;
+
+// Lays out the bookmark bar at the given maximum y-coordinate, with the given
+// width; returns the new maximum y (below the bookmark bar). Note that one must
+// call it with the appropriate |maxY| which depends on whether or not the
+// bookmark bar is shown as the NTP bubble or not (use
+// |-placeBookmarkBarBelowInfoBar|).
+- (CGFloat)layoutBookmarkBarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
+
+// Lay out the view which draws the background for the floating bar when in
+// fullscreen mode, with the given (minimum) y-coordinate, width, height, and
+// fullscreen-mode-status. Should be called even when not in fullscreen mode to
+// hide the backing view.
+- (void)layoutFloatingBarBackingViewAtY:(CGFloat)y
+ width:(CGFloat)width
+ height:(CGFloat)height
+ fullscreen:(BOOL)fullscreen;
+
+// Lays out the infobar at the given maximum y-coordinate, with the given width;
+// returns the new maximum y (below the infobar).
+- (CGFloat)layoutInfoBarAtMaxY:(CGFloat)maxY width:(CGFloat)width;
+
+// Lays out the download shelf, if there is one, at the given minimum
+// y-coordinate, with the given width; returns the new minimum y (above the
+// download shelf). This is safe to call even if there is no download shelf.
+- (CGFloat)layoutDownloadShelfAtMinY:(CGFloat)minY width:(CGFloat)width;
+
+// Lays out the tab content area between the given minimum and maximum
+// y-coordinates, with the given width.
+- (void)layoutTabContentAreaAtMinY:(CGFloat)minY
+ maxY:(CGFloat)maxY
+ width:(CGFloat)width;
+
+// Should we show the normal bookmark bar?
+- (BOOL)shouldShowBookmarkBar;
+
+// Is the current page one for which the bookmark should be shown detached *if*
+// the normal bookmark bar is not shown?
+- (BOOL)shouldShowDetachedBookmarkBar;
+
+// Sets the toolbar's height to a value appropriate for the given compression.
+// Also adjusts the bookmark bar's height by the opposite amount in order to
+// 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;
+
+@end // @interface BrowserWindowController(Private)
+
+
+#endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_CONTROLLER_PRIVATE_H_
diff --git a/chrome/browser/cocoa/browser_window_controller_private.mm b/chrome/browser/cocoa/browser_window_controller_private.mm
new file mode 100644
index 0000000..45da0bf
--- /dev/null
+++ b/chrome/browser/cocoa/browser_window_controller_private.mm
@@ -0,0 +1,440 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/browser_window_controller_private.h"
+
+#include "base/mac_util.h"
+#import "base/scoped_nsobject.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_theme_provider.h"
+#import "chrome/browser/cocoa/browser_theme_provider_init.h"
+#import "chrome/browser/cocoa/chrome_browser_window.h"
+#import "chrome/browser/cocoa/fast_resize_view.h"
+#import "chrome/browser/cocoa/find_bar_cocoa_controller.h"
+#import "chrome/browser/cocoa/floating_bar_backing_view.h"
+#import "chrome/browser/cocoa/fullscreen_controller.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
+#import "chrome/browser/cocoa/tab_strip_view.h"
+#import "chrome/browser/cocoa/toolbar_controller.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+
+
+namespace {
+
+// Insets for the location bar, used when the full toolbar is hidden.
+// TODO(viettrungluu): We can argue about the "correct" insetting; I like the
+// following best, though arguably 0 inset is better/more correct.
+const CGFloat kLocBarLeftRightInset = 1;
+const CGFloat kLocBarTopInset = 0;
+const CGFloat kLocBarBottomInset = 1;
+
+// The amount by which the floating bar is offset downwards (to avoid the menu)
+// in fullscreen mode.
+const CGFloat kFullscreenVerticalBarOffset = 14;
+
+} // end namespace
+
+
+@implementation BrowserWindowController(Private)
+
+- (void)saveWindowPositionIfNeeded {
+ if (browser_ != BrowserList::GetLastActive())
+ return;
+
+ if (!g_browser_process || !g_browser_process->local_state() ||
+ !browser_->ShouldSaveWindowPlacement())
+ return;
+
+ [self saveWindowPositionToPrefs:g_browser_process->local_state()];
+}
+
+- (void)saveWindowPositionToPrefs:(PrefService*)prefs {
+ // If we're in fullscreen mode, save the position of the regular window
+ // instead.
+ NSWindow* window = [self isFullscreen] ? savedRegularWindow_ : [self window];
+
+ // Window positions are stored relative to the origin of the primary monitor.
+ NSRect monitorFrame = [[[NSScreen screens] objectAtIndex:0] frame];
+
+ // Start with the window's frame, which is in virtual coordinates.
+ // Do some y twiddling to flip the coordinate system.
+ gfx::Rect bounds(NSRectToCGRect([window frame]));
+ bounds.set_y(monitorFrame.size.height - bounds.y() - bounds.height());
+
+ // We also need to save the current work area, in flipped coordinates.
+ gfx::Rect workArea(NSRectToCGRect([[window screen] visibleFrame]));
+ workArea.set_y(monitorFrame.size.height - workArea.y() - workArea.height());
+
+ DictionaryValue* windowPreferences = prefs->GetMutableDictionary(
+ browser_->GetWindowPlacementKey().c_str());
+ windowPreferences->SetInteger(L"left", bounds.x());
+ windowPreferences->SetInteger(L"top", bounds.y());
+ windowPreferences->SetInteger(L"right", bounds.right());
+ windowPreferences->SetInteger(L"bottom", bounds.bottom());
+ windowPreferences->SetBoolean(L"maximized", false);
+ windowPreferences->SetBoolean(L"always_on_top", false);
+ windowPreferences->SetInteger(L"work_area_left", workArea.x());
+ windowPreferences->SetInteger(L"work_area_top", workArea.y());
+ windowPreferences->SetInteger(L"work_area_right", workArea.right());
+ windowPreferences->SetInteger(L"work_area_bottom", workArea.bottom());
+}
+
+- (NSRect)window:(NSWindow*)window
+willPositionSheet:(NSWindow*)sheet
+ usingRect:(NSRect)defaultSheetRect {
+ // Position the sheet as follows:
+ // - If the bookmark bar is hidden or shown as a bubble (on the NTP when the
+ // bookmark bar is disabled), position the sheet immediately below the
+ // normal toolbar.
+ // - If the bookmark bar is shown (attached to the normal toolbar), position
+ // the sheet below the bookmark bar.
+ // - If the bookmark bar is currently animating, position the sheet according
+ // to where the bar will be when the animation ends.
+ switch ([bookmarkBarController_ visualState]) {
+ case bookmarks::kShowingState: {
+ NSRect bookmarkBarFrame = [[bookmarkBarController_ view] frame];
+ defaultSheetRect.origin.y = bookmarkBarFrame.origin.y;
+ break;
+ }
+ case bookmarks::kHiddenState:
+ case bookmarks::kDetachedState: {
+ NSRect toolbarFrame = [[toolbarController_ view] frame];
+ defaultSheetRect.origin.y = toolbarFrame.origin.y;
+ break;
+ }
+ case bookmarks::kInvalidState:
+ default:
+ NOTREACHED();
+ }
+ return defaultSheetRect;
+}
+
+- (void)setTheme {
+ ThemeProvider* theme_provider = browser_->profile()->GetThemeProvider();
+ BrowserThemeProvider* browser_theme_provider =
+ static_cast<BrowserThemeProvider*>(theme_provider);
+ if (browser_theme_provider) {
+ bool offtheRecord = browser_->profile()->IsOffTheRecord();
+ GTMTheme* theme =
+ [GTMTheme themeWithBrowserThemeProvider:browser_theme_provider
+ isOffTheRecord:offtheRecord];
+ theme_.reset([theme retain]);
+ }
+}
+
+- (void)layoutSubviews {
+ // With the exception of the tab strip, the subviews which we lay out are
+ // subviews of the content view, so we mainly work in the content view's
+ // coordinate system. Note, however, that the content view's coordinate system
+ // and the window's base coordinate system should coincide.
+ NSWindow* window = [self window];
+ NSView* contentView = [window contentView];
+ NSRect contentBounds = [contentView bounds];
+ CGFloat minY = NSMinY(contentBounds);
+ CGFloat width = NSWidth(contentBounds);
+
+ // Suppress title drawing if necessary.
+ if ([window respondsToSelector:@selector(setShouldHideTitle:)])
+ [(id)window setShouldHideTitle:![self hasTitleBar]];
+
+ BOOL isFullscreen = [self isFullscreen];
+ CGFloat floatingBarHeight = [self floatingBarHeight];
+ CGFloat yOffset = floor(
+ isFullscreen ? (1 - floatingBarShownFraction_) * floatingBarHeight : 0);
+ CGFloat maxY = NSMaxY(contentBounds) + yOffset;
+ CGFloat startMaxY = maxY;
+
+ if ([self hasTabStrip]) {
+ // If we need to lay out the tab strip, replace |maxY| and |startMaxY| with
+ // higher values, and then lay out the tab strip.
+ startMaxY = maxY = NSHeight([window frame]) + yOffset;
+ maxY = [self layoutTabStripAtMaxY:maxY width:width fullscreen:isFullscreen];
+ }
+
+ // Sanity-check |maxY|.
+ DCHECK_GE(maxY, minY);
+ DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
+
+ // Place the toolbar at the top of the reserved area.
+ maxY = [self layoutToolbarAtMaxY:maxY width:width];
+
+ // If we're not displaying the bookmark bar below the infobar, then it goes
+ // immediately below the toolbar.
+ BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
+ if (!placeBookmarkBarBelowInfoBar)
+ maxY = [self layoutBookmarkBarAtMaxY:maxY width:width];
+
+ // The floating bar backing view doesn't actually add any height.
+ [self layoutFloatingBarBackingViewAtY:maxY
+ width:width
+ height:floatingBarHeight
+ fullscreen:isFullscreen];
+
+ [fullscreenController_ overlayFrameChanged:[floatingBarBackingView_ frame]];
+
+ // 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.
+ [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)
+ 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.
+ maxY = [self layoutInfoBarAtMaxY:maxY width:width];
+
+ // If the bookmark bar is detached, place it next in the visual content area.
+ if (placeBookmarkBarBelowInfoBar)
+ maxY = [self layoutBookmarkBarAtMaxY:maxY width:width];
+
+ // Place the download shelf, if any, at the bottom of the view.
+ minY = [self layoutDownloadShelfAtMinY:minY width:width];
+
+ // Finally, the content area takes up all of the remaining space.
+ [self layoutTabContentAreaAtMinY:minY maxY:maxY width:width];
+
+ // Place the status bubble at the bottom of the content area.
+ verticalOffsetForStatusBubble_ = minY;
+
+ // Normally, we don't need to tell the toolbar whether or not to show the
+ // divider, but things break down during animation.
+ [toolbarController_
+ setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
+}
+
+- (CGFloat)floatingBarHeight {
+ if (![self isFullscreen])
+ return 0;
+
+ CGFloat totalHeight = kFullscreenVerticalBarOffset;
+
+ if ([self hasTabStrip])
+ totalHeight += NSHeight([[self tabStripView] frame]);
+
+ if ([self hasToolbar]) {
+ totalHeight += NSHeight([[toolbarController_ view] frame]);
+ } else if ([self hasLocationBar]) {
+ totalHeight += NSHeight([[toolbarController_ view] frame]) +
+ kLocBarTopInset + kLocBarBottomInset;
+ }
+
+ if (![self placeBookmarkBarBelowInfoBar])
+ totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
+
+ return totalHeight;
+}
+
+- (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
+ width:(CGFloat)width
+ fullscreen:(BOOL)fullscreen {
+ // Nothing to do if no tab strip.
+ if (![self hasTabStrip])
+ return maxY;
+
+ NSView* tabStripView = [self tabStripView];
+ CGFloat tabStripHeight = NSHeight([tabStripView frame]);
+ // In fullscreen mode, push the tab strip down so that the main menu (which
+ // also slides down) doesn't run it over.
+ if (fullscreen)
+ maxY -= kFullscreenVerticalBarOffset;
+ maxY -= tabStripHeight;
+ [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)];
+
+ // Set indentation.
+ [tabStripController_ setIndentForControls:(fullscreen ? 0 :
+ [[tabStripController_ class] defaultIndentForControls])];
+
+ // TODO(viettrungluu): Seems kind of bad -- shouldn't |-layoutSubviews| do
+ // this? Moreover, |-layoutTabs| will try to animate....
+ [tabStripController_ layoutTabs];
+
+ return maxY;
+}
+
+- (CGFloat)layoutToolbarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
+ NSView* toolbarView = [toolbarController_ view];
+ NSRect toolbarFrame = [toolbarView frame];
+ if ([self hasToolbar]) {
+ // The toolbar is present in the window, so we make room for it.
+ DCHECK(![toolbarView isHidden]);
+ toolbarFrame.origin.x = 0;
+ toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame);
+ toolbarFrame.size.width = width;
+ maxY -= NSHeight(toolbarFrame);
+ } else {
+ if ([self hasLocationBar]) {
+ // Location bar is present with no toolbar. Put a border of
+ // |kLocBar...Inset| pixels around the location bar.
+ // TODO(viettrungluu): This is moderately ridiculous. The toolbar should
+ // really be aware of what its height should be (the way the toolbar
+ // compression stuff is currently set up messes things up).
+ DCHECK(![toolbarView isHidden]);
+ toolbarFrame.origin.x = kLocBarLeftRightInset;
+ toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame) - kLocBarTopInset;
+ toolbarFrame.size.width = width - 2 * kLocBarLeftRightInset;
+ maxY -= kLocBarTopInset + NSHeight(toolbarFrame) + kLocBarBottomInset;
+ } else {
+ DCHECK([toolbarView isHidden]);
+ }
+ }
+ [toolbarView setFrame:toolbarFrame];
+ return maxY;
+}
+
+- (BOOL)placeBookmarkBarBelowInfoBar {
+ // If we are currently displaying the NTP detached bookmark bar or animating
+ // to/from it (from/to anything else), we display the bookmark bar below the
+ // infobar.
+ return [bookmarkBarController_ isInState:bookmarks::kDetachedState] ||
+ [bookmarkBarController_ isAnimatingToState:bookmarks::kDetachedState] ||
+ [bookmarkBarController_ isAnimatingFromState:bookmarks::kDetachedState];
+}
+
+- (CGFloat)layoutBookmarkBarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
+ NSView* bookmarkBarView = [bookmarkBarController_ view];
+ NSRect bookmarkBarFrame = [bookmarkBarView frame];
+ BOOL oldHidden = [bookmarkBarView isHidden];
+ BOOL newHidden = ![self isBookmarkBarVisible];
+ if (oldHidden != newHidden)
+ [bookmarkBarView setHidden:newHidden];
+ bookmarkBarFrame.origin.y = maxY - NSHeight(bookmarkBarFrame);
+ bookmarkBarFrame.size.width = width;
+ [bookmarkBarView setFrame:bookmarkBarFrame];
+ maxY -= NSHeight(bookmarkBarFrame);
+
+ // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be
+ // necessary in the non-NTP case.
+ [bookmarkBarController_ layoutSubviews];
+
+ return maxY;
+}
+
+- (void)layoutFloatingBarBackingViewAtY:(CGFloat)y
+ width:(CGFloat)width
+ height:(CGFloat)height
+ fullscreen:(BOOL)fullscreen {
+ // Only display when in fullscreen mode.
+ if (fullscreen) {
+ DCHECK(floatingBarBackingView_.get());
+ BOOL aboveBookmarkBar = [self placeBookmarkBarBelowInfoBar];
+
+ // Insert it into the view hierarchy if necessary.
+ if (![floatingBarBackingView_ superview] ||
+ aboveBookmarkBar != floatingBarAboveBookmarkBar_) {
+ NSView* contentView = [[self window] contentView];
+ // z-order gets messed up unless we explicitly remove the floatingbar view
+ // and re-add it.
+ [floatingBarBackingView_ removeFromSuperview];
+ [contentView addSubview:floatingBarBackingView_
+ positioned:(aboveBookmarkBar ?
+ NSWindowAbove : NSWindowBelow)
+ relativeTo:[bookmarkBarController_ view]];
+ floatingBarAboveBookmarkBar_ = aboveBookmarkBar;
+ }
+
+ // Set its frame.
+ [floatingBarBackingView_ setFrame:NSMakeRect(0, y, width, height)];
+ } else {
+ // Okay to call even if |floatingBarBackingView_| is nil.
+ if ([floatingBarBackingView_ superview])
+ [floatingBarBackingView_ removeFromSuperview];
+ }
+}
+
+- (CGFloat)layoutInfoBarAtMaxY:(CGFloat)maxY width:(CGFloat)width {
+ NSView* infoBarView = [infoBarContainerController_ view];
+ NSRect infoBarFrame = [infoBarView frame];
+ infoBarFrame.origin.y = maxY - NSHeight(infoBarFrame);
+ infoBarFrame.size.width = width;
+ [infoBarView setFrame:infoBarFrame];
+ maxY -= NSHeight(infoBarFrame);
+ return maxY;
+}
+
+- (CGFloat)layoutDownloadShelfAtMinY:(CGFloat)minY width:(CGFloat)width {
+ if (downloadShelfController_.get()) {
+ NSView* downloadView = [downloadShelfController_ view];
+ NSRect downloadFrame = [downloadView frame];
+ downloadFrame.origin.y = minY;
+ downloadFrame.size.width = width;
+ [downloadView setFrame:downloadFrame];
+ minY += NSHeight(downloadFrame);
+ }
+ return minY;
+}
+
+- (void)layoutTabContentAreaAtMinY:(CGFloat)minY
+ maxY:(CGFloat)maxY
+ width:(CGFloat)width {
+ NSView* tabContentView = [self tabContentArea];
+ NSRect tabContentFrame = [tabContentView frame];
+
+ bool contentShifted = NSMaxY(tabContentFrame) != maxY;
+
+ tabContentFrame.origin.y = minY;
+ tabContentFrame.size.height = maxY - minY;
+ tabContentFrame.size.width = width;
+ [tabContentView setFrame:tabContentFrame];
+
+ // If the relayout shifts the content area up or down, let the renderer know.
+ if (contentShifted) {
+ if (TabContents* contents = browser_->GetSelectedTabContents()) {
+ if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
+ rwhv->WindowFrameChanged();
+ }
+ }
+}
+
+- (BOOL)shouldShowBookmarkBar {
+ DCHECK(browser_.get());
+ return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) ?
+ YES : NO;
+}
+
+- (BOOL)shouldShowDetachedBookmarkBar {
+ DCHECK(browser_.get());
+ TabContents* contents = browser_->GetSelectedTabContents();
+ return (contents && contents->ShouldShowBookmarkBar()) ? YES : NO;
+}
+
+- (void)adjustToolbarAndBookmarkBarForCompression:(CGFloat)compression {
+ CGFloat newHeight =
+ [toolbarController_ desiredHeightForCompression:compression];
+ NSRect toolbarFrame = [[toolbarController_ view] frame];
+ CGFloat deltaH = newHeight - toolbarFrame.size.height;
+
+ if (deltaH == 0)
+ return;
+
+ toolbarFrame.size.height = newHeight;
+ NSRect bookmarkFrame = [[bookmarkBarController_ view] frame];
+ bookmarkFrame.size.height = bookmarkFrame.size.height - deltaH;
+ [[toolbarController_ view] setFrame:toolbarFrame];
+ [[bookmarkBarController_ view] setFrame:bookmarkFrame];
+ [self layoutSubviews];
+}
+
+- (void)adjustUIForFullscreen:(BOOL)fullscreen {
+ if (fullscreen) {
+ mac_util::RequestFullScreen();
+
+ // Create the floating bar backing view if necessary.
+ if (!floatingBarBackingView_.get()) {
+ floatingBarBackingView_.reset(
+ [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]);
+ }
+ } else {
+ mac_util::ReleaseFullScreen();
+ }
+}
+
+@end // @implementation BrowserWindowController(Private)
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 109b503..54fa4fe9 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -437,10 +437,14 @@
'browser/cocoa/browser_command_executor.h',
'browser/cocoa/browser_frame_view.h',
'browser/cocoa/browser_frame_view.mm',
+ 'browser/cocoa/browser_theme_provider_init.h',
+ 'browser/cocoa/browser_theme_provider_init.mm',
'browser/cocoa/browser_window_cocoa.h',
'browser/cocoa/browser_window_cocoa.mm',
'browser/cocoa/browser_window_controller.h',
'browser/cocoa/browser_window_controller.mm',
+ 'browser/cocoa/browser_window_controller_private.h',
+ 'browser/cocoa/browser_window_controller_private.mm',
'browser/cocoa/bubble_view.h',
'browser/cocoa/bubble_view.mm',
'browser/cocoa/bug_report_window_controller.h',