summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.mm18
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h11
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm98
-rw-r--r--chrome/browser/cocoa/browser_window_controller_unittest.mm73
-rw-r--r--chrome/browser/cocoa/toolbar_controller.h5
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm6
-rw-r--r--chrome/browser/cocoa/toolbar_controller_unittest.mm7
7 files changed, 174 insertions, 44 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm
index 6f2806d..d1c9861 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller.mm
@@ -360,15 +360,6 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;
duration:kBookmarkBarAnimationDuration];
} else if ([self isAnimatingFromState:bookmarks::kShowingState
toState:bookmarks::kHiddenState]) {
- // The toolbar uncompresses immediately at the beginning (otherwise the
- // slide looks wrong, since we slide into the bottom of stuff in the
- // toolbar). Do this only if we're at the beginning height since we may
- // enter this mid-animation.
- if (NSHeight([[self view] frame]) == bookmarks::kBookmarkBarHeight) {
- [resizeDelegate_ resizeView:[self view]
- newHeight:(bookmarks::kBookmarkBarHeight -
- kBookmarkBarOverlap)];
- }
[[self backgroundGradientView] setShowsDivider:YES];
[[self view] setHidden:NO];
AnimatableView* view = [self animatableView];
@@ -376,15 +367,6 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;
duration:kBookmarkBarAnimationDuration];
} else if ([self isAnimatingFromState:bookmarks::kShowingState
toState:bookmarks::kDetachedState]) {
- // The toolbar uncompresses immediately at the beginning (otherwise the
- // slide looks wrong, since we slide into the bottom of stuff in the
- // toolbar). Do this only if we're at the beginning height since we may
- // enter this mid-animation.
- if (NSHeight([[self view] frame]) == bookmarks::kBookmarkBarHeight) {
- [resizeDelegate_ resizeView:[self view]
- newHeight:(bookmarks::kBookmarkBarHeight -
- kBookmarkBarOverlap)];
- }
[[self backgroundGradientView] setShowsDivider:YES];
[[self view] setHidden:NO];
AnimatableView* view = [self animatableView];
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index fed8fc1..c410592 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -74,6 +74,7 @@ class TabStripModelObserverBridge;
BookmarkBubbleController* bookmarkBubbleController_; // Weak.
scoped_nsobject<GTMTheme> theme_;
+ BOOL initializing_; // YES while we are currently in initWithBrowser:
BOOL ownsBrowser_; // Only ever NO when testing
CGFloat verticalOffsetForStatusBubble_;
}
@@ -185,6 +186,16 @@ class TabStripModelObserverBridge;
// Allows us to initWithBrowser withOUT taking ownership of the browser.
- (id)initWithBrowser:(Browser*)browser takeOwnership:(BOOL)ownIt;
+// Adjusts the window height by the given amount. If the window spans from the
+// top of the current workspace to the bottom of the current workspace, the
+// height is not adjusted. If growing the window by the requested amount would
+// size the window to be taller than the current workspace, the window height is
+// capped to be equal to the height of the current workspace. If the window is
+// partially offscreen, its height is not adjusted at all. This function
+// prefers to grow the window down, but will grow up if needed. Calls to this
+// function should be followed by a call to |layoutSubviews|.
+- (void)adjustWindowHeightBy:(CGFloat)deltaH;
+
// Return an autoreleased NSWindow suitable for fullscreen use.
- (NSWindow*)fullscreenWindow;
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index ff2c441..a58ad28 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -92,6 +92,11 @@ willPositionSheet:(NSWindow*)sheet
// 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;
+
@end
@@ -113,6 +118,7 @@ willPositionSheet:(NSWindow*)sheet
ofType:@"nib"];
if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
DCHECK(browser);
+ initializing_ = YES;
browser_.reset(browser);
ownsBrowser_ = ownIt;
tabObserver_.reset(
@@ -219,6 +225,9 @@ willPositionSheet:(NSWindow*)sheet
// Create the bridge for the status bubble.
statusBubble_ = new StatusBubbleMac([self window], self);
+
+ // We are done initializing now.
+ initializing_ = NO;
}
return self;
}
@@ -468,6 +477,53 @@ willPositionSheet:(NSWindow*)sheet
return NO;
}
+// Adjusts the window height by the given amount.
+- (void)adjustWindowHeightBy:(CGFloat)deltaH {
+ // By not adjusting the window height when initializing, we can ensure that
+ // the window opens with the same size that was saved on close.
+ if (initializing_ || [self isFullscreen] || deltaH == 0)
+ return;
+
+ NSWindow* window = [self window];
+ NSRect windowFrame = [window frame];
+ NSRect workarea = [[window screen] visibleFrame];
+
+ // If the window is not already fully in the workarea, do not adjust its frame
+ // at all.
+ if (!NSContainsRect(workarea, windowFrame))
+ return;
+
+ // If the window spans the full height of the current workspace, do not adjust
+ // its frame at all.
+ if (windowFrame.origin.y == workarea.origin.y &&
+ windowFrame.size.height == workarea.size.height)
+ return;
+
+ // Resize the window down until it hits the bottom of the workarea, then if
+ // needed continue resizing upwards. Do not resize the window to be taller
+ // than the current workarea.
+ // Resize the window as requested, keeping the top left corner fixed.
+ windowFrame.origin.y -= deltaH;
+ windowFrame.size.height += deltaH;
+
+ // If the bottom left corner is now outside the visible frame, move the window
+ // up to make it fit, but make sure not to move the top left corner out of the
+ // visible frame.
+ if (windowFrame.origin.y < workarea.origin.y) {
+ windowFrame.origin.y = workarea.origin.y;
+ windowFrame.size.height =
+ std::min(windowFrame.size.height, workarea.size.height);
+ }
+
+ // Disable subview resizing while resizing the window, or else we will get
+ // unwanted renderer resizes. The calling code must call layoutSubviews to
+ // make things right again.
+ NSView* contentView = [window contentView];
+ [contentView setAutoresizesSubviews:NO];
+ [window setFrame:windowFrame display:NO];
+ [contentView setAutoresizesSubviews:YES];
+}
+
// 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
@@ -491,6 +547,23 @@ willPositionSheet:(NSWindow*)sheet
if (frame.size.height == height)
return;
+ // Grow or shrink the window by the amount of the height change. We adjust
+ // the window height only in two cases:
+ // 1) We are adjusting the height of the bookmark bar and it is currently
+ // animating either open or closed.
+ // 2) We are adjusting the height of the download shelf.
+ //
+ // We do not adjust the window height for bookmark bar changes on the NTP.
+ BOOL shouldAdjustBookmarkHeight =
+ [bookmarkBarController_ isAnimatingBetweenState:bookmarks::kHiddenState
+ andState:bookmarks::kShowingState];
+ if ((shouldAdjustBookmarkHeight && view == [bookmarkBarController_ view]) ||
+ view == [downloadShelfController_ view]) {
+ [[self window] disableScreenUpdatesUntilFlush];
+ CGFloat deltaH = height - frame.size.height;
+ [self adjustWindowHeightBy:deltaH];
+ }
+
frame.size.height = height;
// TODO(rohitrao): Determine if calling setFrame: twice is bad.
[view setFrame:frame];
@@ -1227,9 +1300,9 @@ willPositionSheet:(NSWindow*)sheet
didChangeFromState:(bookmarks::VisualState)oldState
toState:(bookmarks::VisualState)newState {
[toolbarController_
- setHeightCompression:[controller getDesiredToolbarHeightCompression]];
- [toolbarController_
setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
+ [self adjustToolbarAndBookmarkBarForCompression:
+ [controller getDesiredToolbarHeightCompression]];
}
// (Needed for |BookmarkBarControllerDelegate| protocol.)
@@ -1237,9 +1310,9 @@ willPositionSheet:(NSWindow*)sheet
willAnimateFromState:(bookmarks::VisualState)oldState
toState:(bookmarks::VisualState)newState {
[toolbarController_
- setHeightCompression:[controller getDesiredToolbarHeightCompression]];
- [toolbarController_
setDividerOpacity:[bookmarkBarController_ toolbarDividerOpacity]];
+ [self adjustToolbarAndBookmarkBarForCompression:
+ [controller getDesiredToolbarHeightCompression]];
}
@end
@@ -1526,6 +1599,23 @@ willPositionSheet:(NSWindow*)sheet
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];
+}
+
@end
@implementation GTMTheme (BrowserThemeProviderInitialization)
diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm
index 6e8fc96..81cccc9 100644
--- a/chrome/browser/cocoa/browser_window_controller_unittest.mm
+++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm
@@ -194,6 +194,63 @@ void CheckViewPositions(BrowserWindowController* controller) {
}
} // end namespace
+TEST_F(BrowserWindowControllerTest, TestAdjustWindowHeight) {
+ NSWindow* window = [controller_ window];
+ NSRect workarea = [[window screen] visibleFrame];
+
+ // Place the window well above the bottom of the screen and try to adjust its
+ // height.
+ NSRect initialFrame = NSMakeRect(workarea.origin.x, workarea.origin.y + 100,
+ 200, 200);
+ [window setFrame:initialFrame display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ NSRect finalFrame = [window frame];
+ EXPECT_FALSE(NSEqualRects(finalFrame, initialFrame));
+ EXPECT_FLOAT_EQ(NSHeight(finalFrame), NSHeight(initialFrame) + 40);
+
+ // Place the window at the bottom of the screen and try again. Its height
+ // should still change, but it should not grow down below the work area.
+ initialFrame = NSMakeRect(workarea.origin.x, workarea.origin.y, 200, 200);
+ [window setFrame:initialFrame display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ EXPECT_FALSE(NSEqualRects(finalFrame, initialFrame));
+ EXPECT_GE(NSMinY(finalFrame), NSMinY(initialFrame));
+ EXPECT_FLOAT_EQ(NSHeight(finalFrame), NSHeight(initialFrame) + 40);
+
+ // Move the window slightly offscreen and try again. The height should not
+ // change this time.
+ initialFrame = NSMakeRect(workarea.origin.x - 10, 0, 200, 200);
+ [window setFrame:initialFrame display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ EXPECT_TRUE(NSEqualRects([window frame], initialFrame));
+
+ // Make the window the same size as the workarea. Resizing both larger and
+ // smaller should have no effect.
+ [window setFrame:workarea display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ EXPECT_TRUE(NSEqualRects([window frame], workarea));
+ [controller_ adjustWindowHeightBy:-40];
+ EXPECT_TRUE(NSEqualRects([window frame], workarea));
+
+ // Make the window smaller than the workarea and place it near the bottom of
+ // the workarea. The window should grow down until it hits the bottom and
+ // then continue to grow up.
+ initialFrame = NSMakeRect(workarea.origin.x, workarea.origin.y + 5,
+ 200, 200);
+ [window setFrame:initialFrame display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ finalFrame = [window frame];
+ EXPECT_EQ(NSMinY(workarea), NSMinY(finalFrame));
+ EXPECT_FLOAT_EQ(NSHeight(finalFrame), NSHeight(initialFrame) + 40);
+
+ // Inset the window slightly from the workarea. It should not grow to be
+ // larger than the workarea.
+ initialFrame = NSInsetRect(workarea, 0, 5);
+ [window setFrame:initialFrame display:YES];
+ [controller_ adjustWindowHeightBy:40];
+ EXPECT_EQ(NSHeight(workarea), NSHeight([window frame]));
+}
+
// Test to make sure resizing and relaying-out subviews works correctly.
TEST_F(BrowserWindowControllerTest, TestResizeViews) {
TabStripView* tabstrip = [controller_ tabStripView];
@@ -205,9 +262,7 @@ TEST_F(BrowserWindowControllerTest, TestResizeViews) {
// We need to muck with the views a bit to put us in a consistent state before
// we start resizing. In particular, we need to move the tab strip to be
// immediately above the content area, since we layout views to be directly
- // under the tab strip. We also explicitly set the contentView's frame to be
- // 800x600.
- [contentView setFrame:NSMakeRect(0, 0, 800, 600)];
+ // under the tab strip.
NSRect tabstripFrame = [tabstrip frame];
tabstripFrame.origin.y = NSMaxY([contentView frame]);
[tabstrip setFrame:tabstripFrame];
@@ -215,7 +270,9 @@ TEST_F(BrowserWindowControllerTest, TestResizeViews) {
// The download shelf is created lazily. Force-create it and set its initial
// height to 0.
NSView* download = [[controller_ downloadShelf] view];
- [controller_ resizeView:download newHeight:0];
+ NSRect downloadFrame = [download frame];
+ downloadFrame.size.height = 0;
+ [download setFrame:downloadFrame];
// Force a layout and check each view's frame.
[controller_ layoutSubviews];
@@ -259,9 +316,7 @@ TEST_F(BrowserWindowControllerTest, TestResizeViewsWithBookmarkBar) {
// We need to muck with the views a bit to put us in a consistent state before
// we start resizing. In particular, we need to move the tab strip to be
// immediately above the content area, since we layout views to be directly
- // under the tab strip. We also explicitly set the contentView's frame to be
- // 800x600.
- [contentView setFrame:NSMakeRect(0, 0, 800, 600)];
+ // under the tab strip.
NSRect tabstripFrame = [tabstrip frame];
tabstripFrame.origin.y = NSMaxY([contentView frame]);
[tabstrip setFrame:tabstripFrame];
@@ -269,7 +324,9 @@ TEST_F(BrowserWindowControllerTest, TestResizeViewsWithBookmarkBar) {
// The download shelf is created lazily. Force-create it and set its initial
// height to 0.
NSView* download = [[controller_ downloadShelf] view];
- [controller_ resizeView:download newHeight:0];
+ NSRect downloadFrame = [download frame];
+ downloadFrame.size.height = 0;
+ [download setFrame:downloadFrame];
// Force a layout and check each view's frame.
[controller_ layoutSubviews];
diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h
index a78ae47..3801667 100644
--- a/chrome/browser/cocoa/toolbar_controller.h
+++ b/chrome/browser/cocoa/toolbar_controller.h
@@ -134,9 +134,8 @@ class ToolbarModel;
// Somewhere near the star button seems like a good start.
- (NSRect)starButtonInWindowCoordinates;
-// Chop off the bottom of the toolbar by |compressByHeight|; needed when the
-// bookmark bar is attached.
-- (void)setHeightCompression:(CGFloat)compressByHeight;
+// Returns the desired toolbar height for the given compression factor.
+- (CGFloat)desiredHeightForCompression:(CGFloat)compressByHeight;
// Set the opacity of the divider (the line at the bottom) *if* we have a
// |ToolbarView| (0 means don't show it); no-op otherwise.
diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm
index cc719dd..6617c87 100644
--- a/chrome/browser/cocoa/toolbar_controller.mm
+++ b/chrome/browser/cocoa/toolbar_controller.mm
@@ -517,10 +517,8 @@ class PrefObserverBridge : public NotificationObserver {
fromView:starButton_];
}
-- (void)setHeightCompression:(CGFloat)compressByHeight {
- // Resize.
- CGFloat newToolbarHeight = kBaseToolbarHeight - compressByHeight;
- [resizeDelegate_ resizeView:[self view] newHeight:newToolbarHeight];
+- (CGFloat)desiredHeightForCompression:(CGFloat)compressByHeight {
+ return kBaseToolbarHeight - compressByHeight;
}
- (void)setDividerOpacity:(CGFloat)opacity {
diff --git a/chrome/browser/cocoa/toolbar_controller_unittest.mm b/chrome/browser/cocoa/toolbar_controller_unittest.mm
index a8be5fc..a6869c3 100644
--- a/chrome/browser/cocoa/toolbar_controller_unittest.mm
+++ b/chrome/browser/cocoa/toolbar_controller_unittest.mm
@@ -292,11 +292,4 @@ TEST_F(ToolbarControllerTest, PopulateEncodingMenu) {
EXPECT_NE(0, [encodings numberOfItems]);
}
-TEST_F(ToolbarControllerTest, HeightCompression) {
- for (int i = 0; i <= 10; i++) {
- [bar_ setHeightCompression:static_cast<CGFloat>(i)];
- EXPECT_EQ(static_cast<CGFloat>(36 - i), [resizeDelegate_ height]);
- }
-}
-
} // namespace