summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/browser_window_controller.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa/browser_window_controller.mm')
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm236
1 files changed, 120 insertions, 116 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index a6c3012..bb073ec 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -66,20 +66,12 @@ const int kWindowGradientHeight = 24;
@interface BrowserWindowController(Private)
-- (void)positionInfoBar;
-- (void)positionBar; // toolbar or URL bar
-- (void)removeBar; // toolbar or URL bar
-
// Leopard's gradient heuristic gets confused by our tabs and makes the title
// gradient jump when creating a tab that is less than a tab width from the
// right side of the screen. This function disables Leopard's gradient
// heuristic.
- (void)fixWindowGradient;
-// Called by the Notification Center whenever the tabContentArea's
-// frame changes. Re-positions the bookmark bar and the find bar.
-- (void)tabContentAreaFrameChanged:(id)sender;
-
// Saves the window's position in the local state preferences.
- (void)saveWindowPositionIfNeeded;
@@ -97,6 +89,9 @@ willPositionSheet:(NSWindow*)sheet
// Theme up the window.
- (void)applyTheme;
+
+// Repositions the windows subviews.
+- (void)layoutSubviews;
@end
@@ -165,12 +160,12 @@ willPositionSheet:(NSWindow*)sheet
model:browser_->tabstrip_model()]);
// Create the infobar container view, so we can pass it to the
- // ToolbarController, but do not position the view until after the
- // toolbar is in place, as positionToolbar will move the tab content area.
+ // ToolbarController.
infoBarContainerController_.reset(
[[InfoBarContainerController alloc]
initWithTabStripModel:(browser_->tabstrip_model())
- browserWindowController:self]);
+ resizeDelegate:self]);
+ [[[self window] contentView] addSubview:[infoBarContainerController_ view]];
// Create a controller for the toolbar, giving it the toolbar model object
// and the toolbar view from the nib. The controller will handle
@@ -179,30 +174,19 @@ willPositionSheet:(NSWindow*)sheet
initWithModel:browser->toolbar_model()
commands:browser->command_updater()
profile:browser->profile()
- webContentView:[self tabContentArea]
- infoBarsView:[infoBarContainerController_ view]
+ resizeDelegate:self
bookmarkDelegate:self]);
// If we are a pop-up, we have a titlebar and no toolbar.
if (!browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) &&
browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR)) {
[toolbarController_ setHasToolbar:NO];
}
- [self positionBar];
- [self fixWindowGradient];
+ [[[self window] contentView] addSubview:[toolbarController_ view]];
- // Put the infobar container view into the window above the
- // tabcontentarea. There are no infobars when starting up, so its
- // initial height is 0.
- [self positionInfoBar];
+ [self fixWindowGradient];
- // Register ourselves for frame changed notifications from the
- // tabContentArea. This has to come after all of the resizing and
- // positioning above.
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(tabContentAreaFrameChanged:)
- name:nil
- object:[self tabContentArea]];
+ // Force a relayout of all the various bars.
+ [self layoutSubviews];
// Create the bridge for the status bubble.
statusBubble_.reset(new StatusBubbleMac([self window], self));
@@ -236,7 +220,6 @@ willPositionSheet:(NSWindow*)sheet
// window destruction.
[window_ setDelegate:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@@ -338,8 +321,6 @@ willPositionSheet:(NSWindow*)sheet
}
}
-
-
// Called when the user clicks the zoom button (or selects it from the Window
// menu). Zoom to the appropriate size based on the content. Make sure we
// enforce a minimum width to ensure websites with small intrinsic widths
@@ -372,6 +353,32 @@ willPositionSheet:(NSWindow*)sheet
return frame;
}
+// Main method to resize browser window subviews. This method should be called
+// when resizing any child of the content view, rather than resizing the views
+// directly. If the view is already the correct height, does not force a
+// relayout.
+- (void)resizeView:(NSView*)view newHeight:(float)height {
+ // We should only ever be called for one of the following three views.
+ // |downloadShelfController_| may be nil.
+ DCHECK(view);
+ DCHECK(view == [toolbarController_ view] ||
+ view == [infoBarContainerController_ view] ||
+ view == [downloadShelfController_ view]);
+
+ // Change the height of the view and call layoutViews. We set the height here
+ // without regard to where the view is on the screen or whether it needs to
+ // "grow up" or "grow down." The below call to layoutSubviews will position
+ // each view correctly.
+ NSRect frame = [view frame];
+ if (frame.size.height == height)
+ return;
+
+ frame.size.height = height;
+ // TODO(rohitrao): Determine if calling setFrame: twice is bad.
+ [view setFrame:frame];
+ [self layoutSubviews];
+}
+
// Update a toggle state for an NSMenuItem if modified.
// Take care to insure |item| looks like a NSMenuItem.
// Called by validateUserInterfaceItem:.
@@ -708,7 +715,9 @@ willPositionSheet:(NSWindow*)sheet
- (DownloadShelfController*)downloadShelf {
if (!downloadShelfController_.get()) {
downloadShelfController_.reset([[DownloadShelfController alloc]
- initWithBrowser:browser_.get() contentArea:[self tabContentArea]]);
+ initWithBrowser:browser_.get() resizeDelegate:self]);
+ [[[self window] contentView] addSubview:[downloadShelfController_ view]];
+ [downloadShelfController_ show:nil];
}
return downloadShelfController_;
}
@@ -719,8 +728,11 @@ willPositionSheet:(NSWindow*)sheet
// Create a controller for the findbar.
findBarCocoaController_.reset([findBarCocoaController retain]);
- [[[self window] contentView] addSubview:[findBarCocoaController_ view]];
- [findBarCocoaController_ positionFindBarView:[self tabContentArea]];
+ [[[self window] contentView] addSubview:[findBarCocoaController_ view]
+ positioned:NSWindowAbove
+ relativeTo:[toolbarController_ view]];
+ [findBarCocoaController_
+ positionFindBarView:[infoBarContainerController_ view]];
}
// Adjust the UI for fullscreen mode. E.g. when going fullscreen,
@@ -729,18 +741,23 @@ willPositionSheet:(NSWindow*)sheet
if (fullscreen) {
// Disable showing of the bookmark bar. This does not toggle the
// preference.
+ // TODO(jrg): Is this still necessary?
[[toolbarController_ bookmarkBarController] setBookmarkBarEnabled:NO];
// Make room for more content area.
- [self removeBar];
+ [[toolbarController_ view] removeFromSuperview];
// Hide the menubar, and allow it to un-hide when moving the mouse
// to the top of the screen. Does this eliminate the need for an
// info bubble describing how to exit fullscreen mode?
SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
} else {
SetSystemUIMode(kUIModeNormal, 0);
- [self positionBar];
+ [[[self window] contentView] addSubview:[toolbarController_ view]];
+ // TODO(jrg): Is this still necessary?
[[toolbarController_ bookmarkBarController] setBookmarkBarEnabled:YES];
}
+
+ // Force a relayout.
+ [self layoutSubviews];
}
- (NSWindow*)fullscreenWindow {
@@ -751,24 +768,27 @@ willPositionSheet:(NSWindow*)sheet
- (void)setFullscreen:(BOOL)fullscreen {
fullscreen_ = fullscreen;
if (fullscreen) {
- // Minimize our UI
- [self adjustUIForFullscreen:fullscreen];
// Move content to a new fullscreen window
NSView* content = [[self window] contentView];
fullscreen_window_.reset([[self fullscreenWindow] retain]);
[content removeFromSuperview];
[fullscreen_window_ setContentView:content];
[self setWindow:fullscreen_window_.get()];
+ // Minimize our UI. This call triggers a relayout, so it needs to come
+ // after we move the contentview to the new window.
+ [self adjustUIForFullscreen:fullscreen];
// Show one window, hide the other.
[fullscreen_window_ makeKeyAndOrderFront:self];
[content setNeedsDisplay:YES];
[window_ orderOut:self];
} else {
- [self adjustUIForFullscreen:fullscreen];
NSView* content = [fullscreen_window_ contentView];
[content removeFromSuperview];
[window_ setContentView:content];
[self setWindow:window_.get()];
+ // This call triggers a relayout, so it needs to come after we move the
+ // contentview to the new window.
+ [self adjustUIForFullscreen:fullscreen];
[content setNeedsDisplay:YES];
// With this call, valgrind yells at me about "Conditional jump or
@@ -851,22 +871,6 @@ willPositionSheet:(NSWindow*)sheet
[tabStripController_ userChangedTheme];
}
-// TODO(rohitrao, jrg): Move this logic out of BrowserWindowController?
-- (void)infoBarResized:(float)newHeight {
- // The top edge of the infobar is fixed.
- NSView* infoBarView = [infoBarContainerController_ view];
- NSRect infoBarFrame = [infoBarView frame];
- int maxY = NSMaxY(infoBarFrame);
- int minY = maxY - newHeight;
-
- [infoBarView setFrame:NSMakeRect(infoBarFrame.origin.x, minY,
- infoBarFrame.size.width, newHeight)];
-
- NSRect contentFrame = [[self tabContentArea] frame];
- contentFrame.size.height = minY - contentFrame.origin.y;
- [[self tabContentArea] setFrame:contentFrame];
-}
-
- (GTMTheme *)gtm_themeForWindow:(NSWindow*)window {
return theme_ ? theme_ : [GTMTheme defaultTheme];
}
@@ -875,60 +879,6 @@ willPositionSheet:(NSWindow*)sheet
@implementation BrowserWindowController (Private)
-// TODO(rohitrao, jrg): Move this logic out of BrowserWindowController?
-- (void)positionInfoBar {
- NSView* infoBarView = [infoBarContainerController_ view];
- NSRect infoBarFrame = [[self tabContentArea] frame];
- infoBarFrame.origin.y = NSMaxY(infoBarFrame);
- infoBarFrame.size.height = 0;
- [infoBarView setFrame:infoBarFrame];
- [[[self window] contentView] addSubview:infoBarView];
-}
-
-// If |add| is YES:
-// Position |barView| below the tab strip, but not as a sibling. The
-// toolbar or titlebar is part of the window's contentView, mainly
-// because we want the opacity during drags to be the same as the web
-// content. This can be used for either the initial add or a
-// reposition.
-// If |add| is NO:
-// Remove the toolbar or titlebar from it's parent view (the window's
-// content view). Called when going fullscreen and we need to
-// minimize UI.
-- (void)positionOrRemoveBar:(BOOL)add {
- NSView* barView = [toolbarController_ view];
- NSRect barFrame = [barView frame];
- NSView* contentView = [self tabContentArea];
- NSRect contentFrame = [contentView frame];
-
- // Shrink or grow the content area by the height of the toolbar.
- if (add)
- contentFrame.size.height -= barFrame.size.height;
- else
- contentFrame.size.height += barFrame.size.height;
- [contentView setFrame:contentFrame];
-
- if (add) {
- // Move the toolbar above the content area, within the window's content view
- // (as opposed to the tab strip, which is a sibling).
- barFrame.origin.y = NSMaxY(contentFrame);
- barFrame.origin.x = 0;
- barFrame.size.width = contentFrame.size.width;
- [barView setFrame:barFrame];
- [[[self window] contentView] addSubview:barView];
- } else {
- [barView removeFromSuperview];
- }
-}
-
-- (void)positionBar {
- [self positionOrRemoveBar:YES];
-}
-
-- (void)removeBar {
- [self positionOrRemoveBar:NO];
-}
-
// If the browser is in incognito mode, install the image view to decorate
// the window at the upper right. Use the same base y coordinate as the
// tab strip.
@@ -980,14 +930,6 @@ willPositionSheet:(NSWindow*)sheet
}
}
-- (void)tabContentAreaFrameChanged:(id)sender {
- // TODO(rohitrao): This is triggered by window resizes also. Make
- // sure we aren't doing anything wasteful in those cases.
- [downloadShelfController_ resizeDownloadShelf];
-
- [findBarCocoaController_ positionFindBarView:[self tabContentArea]];
-}
-
- (void)saveWindowPositionIfNeeded {
if (browser_ != BrowserList::GetLastActive())
return;
@@ -1081,6 +1023,68 @@ willPositionSheet:(NSWindow*)sheet
[[self window] setBackgroundColor:color];
}
+// Private method to layout browser window subviews. Positions the toolbar and
+// the infobar above the tab content area. Positions the download shelf below
+// the tab content area. If the toolbar is not a child of the contentview, this
+// method will not leave room for it. If we are currently running in fullscreen
+// mode, or if the tabstrip is not a descendant of the window, this method fills
+// the entire content area. Otherwise, this method places the topmost view
+// directly beneath the tabstrip.
+- (void)layoutSubviews {
+ NSView* contentView = fullscreen_ ? [fullscreen_window_ contentView]
+ : [[self window] contentView];
+ NSRect contentFrame = [contentView frame];
+ int maxY = NSMaxY(contentFrame);
+ int minY = NSMinY(contentFrame);
+ if (!fullscreen_ && [self isNormalWindow]) {
+ maxY = NSMinY([[self tabStripView] frame]);
+ }
+ DCHECK_GE(maxY, minY);
+
+ // Place the toolbar at the top of the reserved area, but only if we're not in
+ // fullscreen mode.
+ NSView* toolbarView = [toolbarController_ view];
+ NSRect toolbarFrame = [toolbarView frame];
+ if (!fullscreen_) {
+ // The toolbar is present in the window, so we make room for it.
+ toolbarFrame.origin.x = 0;
+ toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame);
+ toolbarFrame.size.width = NSWidth(contentFrame);
+ maxY -= NSHeight(toolbarFrame);
+ }
+ [toolbarView setFrame:toolbarFrame];
+
+ // Place the infobar container in place below the toolbar.
+ NSView* infoBarView = [infoBarContainerController_ view];
+ NSRect infoBarFrame = [infoBarView frame];
+ infoBarFrame.origin.y = maxY - NSHeight(infoBarFrame);
+ infoBarFrame.size.width = NSWidth(contentFrame);
+ [infoBarView setFrame:infoBarFrame];
+ maxY -= NSHeight(infoBarFrame);
+
+ // Place the download shelf at the bottom of the view, if it exists.
+ if (downloadShelfController_.get()) {
+ NSView* downloadView = [downloadShelfController_ view];
+ NSRect downloadFrame = [downloadView frame];
+ downloadFrame.origin.y = minY;
+ downloadFrame.size.width = NSWidth(contentFrame);
+ [downloadView setFrame:downloadFrame];
+ minY += NSHeight(downloadFrame);
+ }
+
+ // Finally, the tabContentArea takes up all of the remaining space.
+ NSView* tabContentView = [self tabContentArea];
+ NSRect tabContentFrame = [tabContentView frame];
+ tabContentFrame.origin.y = minY;
+ tabContentFrame.size.height = maxY - minY;
+ tabContentFrame.size.width = NSWidth(contentFrame);
+ [tabContentView setFrame:tabContentFrame];
+
+ // Position the find bar relative to the infobar container.
+ [findBarCocoaController_
+ positionFindBarView:[infoBarContainerController_ view]];
+}
+
@end
@implementation GTMTheme (BrowserThemeProviderInitialization)