Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: chrome/browser/ui/cocoa/browser_window_controller_private.mm

Issue 607723002: mac: Refactor tab strip layout logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tabstrip_relayout_bug_base
Patch Set: Fix unit test. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" 5 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 #include "chrome/common/pref_names.h" 43 #include "chrome/common/pref_names.h"
44 #include "content/public/browser/render_widget_host_view.h" 44 #include "content/public/browser/render_widget_host_view.h"
45 #include "content/public/browser/web_contents.h" 45 #include "content/public/browser/web_contents.h"
46 #import "ui/base/cocoa/focus_tracker.h" 46 #import "ui/base/cocoa/focus_tracker.h"
47 #import "ui/base/cocoa/nsview_additions.h" 47 #import "ui/base/cocoa/nsview_additions.h"
48 #include "ui/base/ui_base_types.h" 48 #include "ui/base/ui_base_types.h"
49 49
50 using content::RenderWidgetHostView; 50 using content::RenderWidgetHostView;
51 using content::WebContents; 51 using content::WebContents;
52 52
53 namespace {
54
55 // Space between the incognito badge and the right edge of the window.
56 const CGFloat kAvatarRightOffset = 4;
57
58 } // namespace
59
60 @implementation BrowserWindowController(Private) 53 @implementation BrowserWindowController(Private)
61 54
62 // Create the tab strip controller. 55 // Create the tab strip controller.
63 - (void)createTabStripController { 56 - (void)createTabStripController {
64 DCHECK([overlayableContentsController_ activeContainer]); 57 DCHECK([overlayableContentsController_ activeContainer]);
65 DCHECK([[overlayableContentsController_ activeContainer] window]); 58 DCHECK([[overlayableContentsController_ activeContainer] window]);
66 tabStripController_.reset([[TabStripController alloc] 59 tabStripController_.reset([[TabStripController alloc]
67 initWithView:[self tabStripView] 60 initWithView:[self tabStripView]
68 switchView:[overlayableContentsController_ activeContainer] 61 switchView:[overlayableContentsController_ activeContainer]
69 browser:browser_.get() 62 browser:browser_.get()
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 [self updateSubviewZOrder]; 166 [self updateSubviewZOrder];
174 167
175 base::scoped_nsobject<BrowserWindowLayout> layout( 168 base::scoped_nsobject<BrowserWindowLayout> layout(
176 [[BrowserWindowLayout alloc] init]); 169 [[BrowserWindowLayout alloc] init]);
177 [self updateLayoutParameters:layout]; 170 [self updateLayoutParameters:layout];
178 [self applyLayout:layout]; 171 [self applyLayout:layout];
179 172
180 [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]]; 173 [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]];
181 } 174 }
182 175
183 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY 176 - (void)applyTabStripLayout:(const chrome::TabStripLayout&)layout {
184 width:(CGFloat)width 177 // Update the presence of the window controls.
185 fullscreen:(BOOL)fullscreen { 178 if (layout.addCustomWindowControls)
186 // Nothing to do if no tab strip. 179 [tabStripController_ addCustomWindowControls];
187 if (![self hasTabStrip]) 180 else
188 return maxY; 181 [tabStripController_ removeCustomWindowControls];
189 182
190 NSView* tabStripView = [self tabStripView]; 183 // Update the layout of the avatar.
191 CGFloat tabStripHeight = NSHeight([tabStripView frame]); 184 if (!NSIsEmptyRect(layout.avatarFrame)) {
192 maxY -= tabStripHeight; 185 NSView* avatarButton = [avatarButtonController_ view];
193 NSRect tabStripFrame = NSMakeRect(0, maxY, width, tabStripHeight); 186 [avatarButton setFrame:layout.avatarFrame];
194 BOOL requiresRelayout = !NSEqualRects(tabStripFrame, [tabStripView frame]); 187 [avatarButton setHidden:NO];
188 }
195 189
196 // In Yosemite fullscreen, manually add the fullscreen controls to the tab 190 // Check if the tab strip's frame has changed.
197 // strip. 191 BOOL requiresRelayout =
198 BOOL addControlsInFullscreen = 192 !NSEqualRects([[self tabStripView] frame], layout.frame);
199 [self isInAppKitFullscreen] && base::mac::IsOSYosemiteOrLater();
200 193
201 // Set left indentation based on fullscreen mode status. 194 // Check if the left indent has changed.
202 CGFloat leftIndent = 0; 195 if (layout.leftIndent != [tabStripController_ leftIndentForControls]) {
203 if (!fullscreen || addControlsInFullscreen) 196 [tabStripController_ setLeftIndentForControls:layout.leftIndent];
204 leftIndent = [[tabStripController_ class] defaultLeftIndentForControls];
205 if (leftIndent != [tabStripController_ leftIndentForControls]) {
206 [tabStripController_ setLeftIndentForControls:leftIndent];
207 requiresRelayout = YES; 197 requiresRelayout = YES;
208 } 198 }
209 199
210 if (addControlsInFullscreen) 200 // Check if the right indent has changed.
211 [tabStripController_ addWindowControls]; 201 if (layout.rightIndent != [tabStripController_ rightIndentForControls]) {
212 else 202 [tabStripController_ setRightIndentForControls:layout.rightIndent];
213 [tabStripController_ removeWindowControls];
214
215 // fullScreenButton is non-nil when isInAnyFullscreenMode is NO, and OS
216 // version is in the range 10.7 <= version <= 10.9. Starting with 10.10, the
217 // zoom/maximize button acts as the fullscreen button.
218 NSButton* fullScreenButton =
219 [[self window] standardWindowButton:NSWindowFullScreenButton];
220
221 // Lay out the icognito/avatar badge because calculating the indentation on
222 // the right depends on it.
223 NSView* avatarButton = [avatarButtonController_ view];
224 if ([self shouldShowAvatar]) {
225 CGFloat badgeXOffset = -kAvatarRightOffset;
226 CGFloat badgeYOffset = 0;
227 CGFloat buttonHeight = NSHeight([avatarButton frame]);
228
229 if ([self shouldUseNewAvatarButton]) {
230 // The fullscreen icon is displayed to the right of the avatar button.
231 if (![self isInAnyFullscreenMode] && fullScreenButton)
232 badgeXOffset -= width - NSMinX([fullScreenButton frame]);
233 // Center the button vertically on the tabstrip.
234 badgeYOffset = (tabStripHeight - buttonHeight) / 2;
235 } else {
236 // Actually place the badge *above* |maxY|, by +2 to miss the divider.
237 badgeYOffset = 2 * [[avatarButton superview] cr_lineWidth];
238 }
239
240 [avatarButton setFrameSize:NSMakeSize(NSWidth([avatarButton frame]),
241 std::min(buttonHeight, tabStripHeight))];
242 NSPoint origin =
243 NSMakePoint(width - NSWidth([avatarButton frame]) + badgeXOffset,
244 maxY + badgeYOffset);
245 [avatarButton setFrameOrigin:origin];
246 [avatarButton setHidden:NO]; // Make sure it's shown.
247 }
248
249 // Calculate the right indentation. The default indentation built into the
250 // tabstrip leaves enough room for the fullscreen button on Lion (10.7) to
251 // Mavericks (10.9). On 10.6 and >=10.10, the right indent needs to be
252 // adjusted to make room for the new tab button when an avatar is present.
253 CGFloat rightIndent = 0;
254 if (![self isInAnyFullscreenMode] && fullScreenButton) {
255 rightIndent = width - NSMinX([fullScreenButton frame]);
256
257 if ([self shouldUseNewAvatarButton]) {
258 // The new avatar button is to the left of the fullscreen button.
259 // (The old avatar button is to the right).
260 rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset;
261 }
262 } else if ([self shouldShowAvatar]) {
263 rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset;
264 }
265
266 if (rightIndent != [tabStripController_ rightIndentForControls]) {
267 [tabStripController_ setRightIndentForControls:rightIndent];
268 requiresRelayout = YES; 203 requiresRelayout = YES;
269 } 204 }
270 205
271 // It is undesirable to force tabs relayout when the tap strip's frame did 206 // It is undesirable to force tabs relayout when the tap strip's frame did
272 // not change, because it will interrupt tab animations in progress. 207 // not change, because it will interrupt tab animations in progress.
273 // In addition, there appears to be an AppKit bug on <10.9 where interrupting 208 // In addition, there appears to be an AppKit bug on <10.9 where interrupting
274 // a tab animation resulted in the tab frame being the animator's target 209 // a tab animation resulted in the tab frame being the animator's target
275 // frame instead of the interrupting setFrame. (See http://crbug.com/415093) 210 // frame instead of the interrupting setFrame. (See http://crbug.com/415093)
276 if (requiresRelayout) { 211 if (requiresRelayout) {
277 [tabStripView setFrame:tabStripFrame]; 212 [[self tabStripView] setFrame:layout.frame];
278 [tabStripController_ layoutTabsWithoutAnimation]; 213 [tabStripController_ layoutTabsWithoutAnimation];
279 } 214 }
280
281 return maxY;
282 } 215 }
283 216
284 - (BOOL)placeBookmarkBarBelowInfoBar { 217 - (BOOL)placeBookmarkBarBelowInfoBar {
285 // If we are currently displaying the NTP detached bookmark bar or animating 218 // If we are currently displaying the NTP detached bookmark bar or animating
286 // to/from it (from/to anything else), we display the bookmark bar below the 219 // to/from it (from/to anything else), we display the bookmark bar below the
287 // info bar. 220 // info bar.
288 return [bookmarkBarController_ isInState:BookmarkBar::DETACHED] || 221 return [bookmarkBarController_ isInState:BookmarkBar::DETACHED] ||
289 [bookmarkBarController_ isAnimatingToState:BookmarkBar::DETACHED] || 222 [bookmarkBarController_ isAnimatingToState:BookmarkBar::DETACHED] ||
290 [bookmarkBarController_ isAnimatingFromState:BookmarkBar::DETACHED]; 223 [bookmarkBarController_ isAnimatingFromState:BookmarkBar::DETACHED];
291 } 224 }
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 774
842 [layout setInAnyFullscreen:[self isInAnyFullscreenMode]]; 775 [layout setInAnyFullscreen:[self isInAnyFullscreenMode]];
843 [layout setFullscreenSlidingStyle: 776 [layout setFullscreenSlidingStyle:
844 presentationModeController_.get().slidingStyle]; 777 presentationModeController_.get().slidingStyle];
845 [layout setFullscreenMenubarOffset: 778 [layout setFullscreenMenubarOffset:
846 [presentationModeController_ menubarOffset]]; 779 [presentationModeController_ menubarOffset]];
847 [layout setFullscreenToolbarFraction: 780 [layout setFullscreenToolbarFraction:
848 [presentationModeController_ toolbarFraction]]; 781 [presentationModeController_ toolbarFraction]];
849 782
850 [layout setHasTabStrip:[self hasTabStrip]]; 783 [layout setHasTabStrip:[self hasTabStrip]];
784 NSButton* fullScreenButton =
785 [[self window] standardWindowButton:NSWindowFullScreenButton];
786 [layout setFullscreenButtonFrame:fullScreenButton ? [fullScreenButton frame]
787 : NSZeroRect];
788 if ([self shouldShowAvatar]) {
789 NSView* avatar = [avatarButtonController_ view];
790 [layout setShouldShowAvatar:YES];
791 [layout setShouldUseNewAvatar:[self shouldUseNewAvatarButton]];
792 [layout setAvatarSize:[avatar frame].size];
793 [layout setAvatarLineWidth:[[avatar superview] cr_lineWidth]];
794 }
851 795
852 [layout setHasToolbar:[self hasToolbar]]; 796 [layout setHasToolbar:[self hasToolbar]];
853 [layout setToolbarHeight:NSHeight([[toolbarController_ view] bounds])]; 797 [layout setToolbarHeight:NSHeight([[toolbarController_ view] bounds])];
854 798
855 [layout setHasLocationBar:[self hasLocationBar]]; 799 [layout setHasLocationBar:[self hasLocationBar]];
856 800
857 [layout setPlaceBookmarkBarBelowInfoBar:[self placeBookmarkBarBelowInfoBar]]; 801 [layout setPlaceBookmarkBarBelowInfoBar:[self placeBookmarkBarBelowInfoBar]];
858 [layout setBookmarkBarHidden:[bookmarkBarController_ view].isHidden]; 802 [layout setBookmarkBarHidden:[bookmarkBarController_ view].isHidden];
859 [layout setBookmarkBarHeight: 803 [layout setBookmarkBarHeight:
860 NSHeight([[bookmarkBarController_ view] bounds])]; 804 NSHeight([[bookmarkBarController_ view] bounds])];
861 805
862 [layout setInfoBarHeight:[infoBarContainerController_ heightOfInfoBars]]; 806 [layout setInfoBarHeight:[infoBarContainerController_ heightOfInfoBars]];
863 [layout setPageInfoBubblePointY:[self pageInfoBubblePointY]]; 807 [layout setPageInfoBubblePointY:[self pageInfoBubblePointY]];
864 808
865 [layout setHasDownloadShelf:(downloadShelfController_.get() != nil)]; 809 [layout setHasDownloadShelf:(downloadShelfController_.get() != nil)];
866 [layout setDownloadShelfHeight: 810 [layout setDownloadShelfHeight:
867 NSHeight([[downloadShelfController_ view] bounds])]; 811 NSHeight([[downloadShelfController_ view] bounds])];
868 } 812 }
869 813
870 - (void)applyLayout:(BrowserWindowLayout*)layout { 814 - (void)applyLayout:(BrowserWindowLayout*)layout {
871 chrome::LayoutOutput output = [layout computeLayout]; 815 chrome::LayoutOutput output = [layout computeLayout];
872 816
873 if (!NSIsEmptyRect(output.tabStripFrame)) { 817 if (!NSIsEmptyRect(output.tabStripLayout.frame))
874 // Note: The fullscreen parameter passed to the method is different from 818 [self applyTabStripLayout:output.tabStripLayout];
875 // the field in |parameters| with the similar name.
876 [self layoutTabStripAtMaxY:NSMaxY(output.tabStripFrame)
877 width:NSWidth(output.tabStripFrame)
878 fullscreen:[self isInAnyFullscreenMode]];
879 }
880 819
881 if (!NSIsEmptyRect(output.toolbarFrame)) { 820 if (!NSIsEmptyRect(output.toolbarFrame))
882 [[toolbarController_ view] setFrame:output.toolbarFrame]; 821 [[toolbarController_ view] setFrame:output.toolbarFrame];
883 }
884 822
885 if (!NSIsEmptyRect(output.bookmarkFrame)) { 823 if (!NSIsEmptyRect(output.bookmarkFrame)) {
886 NSView* bookmarkBarView = [bookmarkBarController_ view]; 824 NSView* bookmarkBarView = [bookmarkBarController_ view];
887 [bookmarkBarView setFrame:output.bookmarkFrame]; 825 [bookmarkBarView setFrame:output.bookmarkFrame];
888 826
889 // Pin the bookmark bar to the top of the window and make the width 827 // Pin the bookmark bar to the top of the window and make the width
890 // flexible. 828 // flexible.
891 [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; 829 [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
892 830
893 [bookmarkBarController_ layoutSubviews]; 831 [bookmarkBarController_ layoutSubviews];
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 970
1033 [CATransaction commit]; 971 [CATransaction commit];
1034 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES; 972 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES;
1035 } 973 }
1036 } else { 974 } else {
1037 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO; 975 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO;
1038 } 976 }
1039 } 977 }
1040 978
1041 @end // @implementation BrowserWindowController(Private) 979 @end // @implementation BrowserWindowController(Private)
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/browser_window_controller_private.h ('k') | chrome/browser/ui/cocoa/browser_window_layout.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698