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

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

Issue 555243002: mac: Refactor browser_window_controller layout logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fullscreen_layout
Patch Set: Ensure location bar in consistent state after initialization. Created 6 years, 3 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"
11 #import "base/mac/scoped_nsobject.h" 11 #import "base/mac/scoped_nsobject.h"
12 #import "base/mac/sdk_forward_declarations.h" 12 #import "base/mac/sdk_forward_declarations.h"
13 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h" 14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/fullscreen.h" 16 #include "chrome/browser/fullscreen.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_avatar_icon_util.h" 18 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
19 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" 19 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
20 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_window_state.h" 21 #include "chrome/browser/ui/browser_window_state.h"
22 #import "chrome/browser/ui/cocoa/browser_window_layout.h"
22 #import "chrome/browser/ui/cocoa/dev_tools_controller.h" 23 #import "chrome/browser/ui/cocoa/dev_tools_controller.h"
23 #import "chrome/browser/ui/cocoa/fast_resize_view.h" 24 #import "chrome/browser/ui/cocoa/fast_resize_view.h"
24 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" 25 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h"
25 #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h" 26 #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h"
26 #import "chrome/browser/ui/cocoa/framed_browser_window.h" 27 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
27 #import "chrome/browser/ui/cocoa/fullscreen_window.h" 28 #import "chrome/browser/ui/cocoa/fullscreen_window.h"
28 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" 29 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
29 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h" 30 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
30 #import "chrome/browser/ui/cocoa/nsview_additions.h" 31 #import "chrome/browser/ui/cocoa/nsview_additions.h"
31 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h" 32 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h"
(...skipping 15 matching lines...) Expand all
47 #include "ui/base/ui_base_types.h" 48 #include "ui/base/ui_base_types.h"
48 49
49 using content::RenderWidgetHostView; 50 using content::RenderWidgetHostView;
50 using content::WebContents; 51 using content::WebContents;
51 52
52 namespace { 53 namespace {
53 54
54 // Space between the incognito badge and the right edge of the window. 55 // Space between the incognito badge and the right edge of the window.
55 const CGFloat kAvatarRightOffset = 4; 56 const CGFloat kAvatarRightOffset = 4;
56 57
57 // Insets for the location bar, used when the full toolbar is hidden.
58 // TODO(viettrungluu): We can argue about the "correct" insetting; I like the
59 // following best, though arguably 0 inset is better/more correct.
60 const CGFloat kLocBarLeftRightInset = 1;
61 const CGFloat kLocBarTopInset = 0;
62 const CGFloat kLocBarBottomInset = 1;
63
64 } // namespace 58 } // namespace
65 59
66 @implementation BrowserWindowController(Private) 60 @implementation BrowserWindowController(Private)
67 61
68 // Create the tab strip controller. 62 // Create the tab strip controller.
69 - (void)createTabStripController { 63 - (void)createTabStripController {
70 DCHECK([overlayableContentsController_ activeContainer]); 64 DCHECK([overlayableContentsController_ activeContainer]);
71 DCHECK([[overlayableContentsController_ activeContainer] window]); 65 DCHECK([[overlayableContentsController_ activeContainer] window]);
72 tabStripController_.reset([[TabStripController alloc] 66 tabStripController_.reset([[TabStripController alloc]
73 initWithView:[self tabStripView] 67 initWithView:[self tabStripView]
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 defaultSheetRect.origin.y = NSHeight([[window contentView] frame]) - 157 defaultSheetRect.origin.y = NSHeight([[window contentView] frame]) -
164 defaultSheetRect.size.height; 158 defaultSheetRect.size.height;
165 } 159 }
166 break; 160 break;
167 } 161 }
168 } 162 }
169 return defaultSheetRect; 163 return defaultSheetRect;
170 } 164 }
171 165
172 - (void)layoutSubviews { 166 - (void)layoutSubviews {
173 // With the exception of the top tab strip, the subviews which we lay out are 167 // Suppress title drawing if necessary.
174 // subviews of the content view, so we mainly work in the content view's 168 if ([self.window respondsToSelector:@selector(setShouldHideTitle:)])
175 // coordinate system. Note, however, that the content view's coordinate system 169 [(id)self.window setShouldHideTitle:![self hasTitleBar]];
176 // and the window's base coordinate system should coincide.
177 NSWindow* window = [self window];
178 NSView* contentView = [window contentView];
179 NSRect contentBounds = [contentView bounds];
180 CGFloat minX = NSMinX(contentBounds);
181 CGFloat minY = NSMinY(contentBounds);
182 CGFloat width = NSWidth(contentBounds);
183 170
184 // Suppress title drawing if necessary. 171 [bookmarkBarController_ updateHiddenState];
185 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) 172 [self updateSubviewZOrder];
186 [(id)window setShouldHideTitle:![self hasTitleBar]];
187 173
188 // Update z-order. The code below depends on this. 174 base::scoped_nsobject<BrowserWindowLayout> layout(
189 [self updateSubviewZOrder:[self isInFullscreenWithOmniboxSliding]]; 175 [[BrowserWindowLayout alloc] init]);
176 [self updateLayoutParameters:layout];
177 [self applyLayout:layout];
190 178
191 CGFloat floatingBarHeight = [self floatingBarHeight];
192 CGFloat yOffset = 0;
193 if ([self isInFullscreenWithOmniboxSliding]) {
194 yOffset += [presentationModeController_ menubarOffset];
195 switch (presentationModeController_.get().slidingStyle) {
196 case fullscreen_mac::OMNIBOX_TABS_PRESENT:
197 break;
198 case fullscreen_mac::OMNIBOX_TABS_HIDDEN:
199 // In presentation mode, |yOffset| accounts for the sliding position of
200 // the floating bar and the extra offset needed to dodge the menu bar.
201 yOffset +=
202 std::floor((1 - presentationModeController_.get().toolbarFraction) *
203 floatingBarHeight);
204 break;
205 }
206 }
207
208 CGFloat maxY = NSMaxY(contentBounds) + yOffset;
209
210 if ([self hasTabStrip]) {
211 // If we need to lay out the top tab strip, replace |maxY| with a higher
212 // value, and then lay out the tab strip.
213 NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil];
214 maxY = NSHeight(windowFrame) + yOffset;
215 maxY = [self layoutTabStripAtMaxY:maxY
216 width:width
217 fullscreen:[self isInAnyFullscreenMode]];
218 }
219
220 // Sanity-check |maxY|.
221 DCHECK_GE(maxY, minY);
222 DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
223
224 // Place the toolbar at the top of the reserved area.
225 maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width];
226
227 // If we're not displaying the bookmark bar below the info bar, then it goes
228 // immediately below the toolbar.
229 BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
230 if (!placeBookmarkBarBelowInfoBar)
231 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
232
233 // The floating bar backing view doesn't actually add any height.
234 NSRect floatingBarBackingRect =
235 NSMakeRect(minX, maxY, width, floatingBarHeight);
236 [self layoutFloatingBarBackingView:floatingBarBackingRect
237 presentationMode:[self isInFullscreenWithOmniboxSliding]];
238
239 // Place the find bar immediately below the toolbar/attached bookmark bar. In
240 // presentation mode, it hangs off the top of the screen when the bar is
241 // hidden.
242 [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width];
243 [fullscreenExitBubbleController_ positionInWindowAtTop:maxY width:width];
244
245 if ([self isInFullscreenWithOmniboxSliding]) {
246 switch (presentationModeController_.get().slidingStyle) {
247 case fullscreen_mac::OMNIBOX_TABS_PRESENT:
248 // Do nothing in Canonical Fullscreen. All content slides.
249 break;
250 case fullscreen_mac::OMNIBOX_TABS_HIDDEN:
251 // If in presentation mode, reset |maxY| to top of screen, so that the
252 // floating bar slides over the things which appear to be in the content
253 // area.
254 maxY = NSMaxY(contentBounds);
255 break;
256 }
257 }
258
259 // Also place the info bar container immediate below the toolbar, except in
260 // presentation mode in which case it's at the top of the visual content area.
261 maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width];
262
263 // If the bookmark bar is detached, place it next in the visual content area.
264 if (placeBookmarkBarBelowInfoBar)
265 maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
266
267 // Place the download shelf, if any, at the bottom of the view.
268 minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width];
269
270 // Finally, the content area takes up all of the remaining space.
271 NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY);
272 [self layoutTabContentArea:contentAreaRect];
273
274 // Normally, we don't need to tell the toolbar whether or not to show the
275 // divider, but things break down during animation.
276 [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]]; 179 [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]];
277 } 180 }
278 181
279 - (CGFloat)floatingBarHeight {
280 if (![self isInFullscreenWithOmniboxSliding])
281 return 0;
282
283 CGFloat totalHeight = 0;
284 if ([self hasTabStrip])
285 totalHeight += NSHeight([[self tabStripView] frame]);
286
287 if ([self hasToolbar]) {
288 totalHeight += NSHeight([[toolbarController_ view] frame]);
289 } else if ([self hasLocationBar]) {
290 totalHeight += NSHeight([[toolbarController_ view] frame]) +
291 kLocBarTopInset + kLocBarBottomInset;
292 }
293
294 if (![self placeBookmarkBarBelowInfoBar])
295 totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
296
297 return totalHeight;
298 }
299
300 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY 182 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
301 width:(CGFloat)width 183 width:(CGFloat)width
302 fullscreen:(BOOL)fullscreen { 184 fullscreen:(BOOL)fullscreen {
303 // Nothing to do if no tab strip. 185 // Nothing to do if no tab strip.
304 if (![self hasTabStrip]) 186 if (![self hasTabStrip])
305 return maxY; 187 return maxY;
306 188
307 NSView* tabStripView = [self tabStripView]; 189 NSView* tabStripView = [self tabStripView];
308 CGFloat tabStripHeight = NSHeight([tabStripView frame]); 190 CGFloat tabStripHeight = NSHeight([tabStripView frame]);
309 maxY -= tabStripHeight; 191 maxY -= tabStripHeight;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset; 258 rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset;
377 } 259 }
378 [tabStripController_ setRightIndentForControls:rightIndent]; 260 [tabStripController_ setRightIndentForControls:rightIndent];
379 261
380 // Go ahead and layout the tabs. 262 // Go ahead and layout the tabs.
381 [tabStripController_ layoutTabsWithoutAnimation]; 263 [tabStripController_ layoutTabsWithoutAnimation];
382 264
383 return maxY; 265 return maxY;
384 } 266 }
385 267
386 - (CGFloat)layoutToolbarAtMinX:(CGFloat)minX
387 maxY:(CGFloat)maxY
388 width:(CGFloat)width {
389 NSView* toolbarView = [toolbarController_ view];
390 NSRect toolbarFrame = [toolbarView frame];
391 if ([self hasToolbar]) {
392 // The toolbar is present in the window, so we make room for it.
393 DCHECK(![toolbarView isHidden]);
394 toolbarFrame.origin.x = minX;
395 toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame);
396 toolbarFrame.size.width = width;
397 maxY -= NSHeight(toolbarFrame);
398 } else {
399 if ([self hasLocationBar]) {
400 // Location bar is present with no toolbar. Put a border of
401 // |kLocBar...Inset| pixels around the location bar.
402 // TODO(viettrungluu): This is moderately ridiculous. The toolbar should
403 // really be aware of what its height should be (the way the toolbar
404 // compression stuff is currently set up messes things up).
405 DCHECK(![toolbarView isHidden]);
406 toolbarFrame.origin.x = kLocBarLeftRightInset;
407 toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame) - kLocBarTopInset;
408 toolbarFrame.size.width = width - 2 * kLocBarLeftRightInset;
409 maxY -= kLocBarTopInset + NSHeight(toolbarFrame) + kLocBarBottomInset;
410 } else {
411 DCHECK([toolbarView isHidden]);
412 }
413 }
414 [toolbarView setFrame:toolbarFrame];
415 return maxY;
416 }
417
418 - (BOOL)placeBookmarkBarBelowInfoBar { 268 - (BOOL)placeBookmarkBarBelowInfoBar {
419 // If we are currently displaying the NTP detached bookmark bar or animating 269 // If we are currently displaying the NTP detached bookmark bar or animating
420 // to/from it (from/to anything else), we display the bookmark bar below the 270 // to/from it (from/to anything else), we display the bookmark bar below the
421 // info bar. 271 // info bar.
422 return [bookmarkBarController_ isInState:BookmarkBar::DETACHED] || 272 return [bookmarkBarController_ isInState:BookmarkBar::DETACHED] ||
423 [bookmarkBarController_ isAnimatingToState:BookmarkBar::DETACHED] || 273 [bookmarkBarController_ isAnimatingToState:BookmarkBar::DETACHED] ||
424 [bookmarkBarController_ isAnimatingFromState:BookmarkBar::DETACHED]; 274 [bookmarkBarController_ isAnimatingFromState:BookmarkBar::DETACHED];
425 } 275 }
426 276
427 - (CGFloat)layoutBookmarkBarAtMinX:(CGFloat)minX
428 maxY:(CGFloat)maxY
429 width:(CGFloat)width {
430 [bookmarkBarController_ updateHiddenState];
431
432 NSView* bookmarkBarView = [bookmarkBarController_ view];
433 NSRect frame = [bookmarkBarView frame];
434 frame.origin.x = minX;
435 frame.origin.y = maxY - NSHeight(frame);
436 frame.size.width = width;
437 [bookmarkBarView setFrame:frame];
438 maxY -= NSHeight(frame);
439
440 // Pin the bookmark bar to the top of the window and make the width flexible.
441 [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
442
443 // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be
444 // necessary in the non-NTP case.
445 [bookmarkBarController_ layoutSubviews];
446
447 return maxY;
448 }
449
450 - (void)layoutFloatingBarBackingView:(NSRect)frame
451 presentationMode:(BOOL)presentationMode {
452 // Only display when in presentation mode.
453 if (presentationMode) {
454 // For certain window types such as app windows (e.g., the dev tools
455 // window), there's no actual overlay. (Displaying one would result in an
456 // overly sliding in only under the menu, which gives an ugly effect.)
457 if (floatingBarBackingView_.get()) {
458 // Set its frame.
459 [floatingBarBackingView_ setFrame:frame];
460 }
461
462 // But we want the logic to work as usual (for show/hide/etc. purposes).
463 [presentationModeController_ overlayFrameChanged:frame];
464 } else {
465 // Okay to call even if |floatingBarBackingView_| is nil.
466 if ([floatingBarBackingView_ superview])
467 [floatingBarBackingView_ removeFromSuperview];
468 }
469 }
470
471 - (CGFloat)layoutInfoBarAtMinX:(CGFloat)minX
472 maxY:(CGFloat)maxY
473 width:(CGFloat)width {
474 NSView* containerView = [infoBarContainerController_ view];
475 NSRect containerFrame = [containerView frame];
476 maxY -= NSHeight(containerFrame);
477 maxY += [infoBarContainerController_ overlappingTipHeight];
478 containerFrame.origin.x = minX;
479 containerFrame.origin.y = maxY;
480 containerFrame.size.width = width;
481 [containerView setFrame:containerFrame];
482 [infoBarContainerController_ setMaxTopArrowHeight:[self
483 infoBarMaxTopArrowHeight]];
484 return maxY;
485 }
486
487 - (CGFloat)layoutDownloadShelfAtMinX:(CGFloat)minX
488 minY:(CGFloat)minY
489 width:(CGFloat)width {
490 if (downloadShelfController_.get()) {
491 NSView* downloadView = [downloadShelfController_ view];
492 NSRect downloadFrame = [downloadView frame];
493 downloadFrame.origin.x = minX;
494 downloadFrame.origin.y = minY;
495 downloadFrame.size.width = width;
496 [downloadView setFrame:downloadFrame];
497 minY += NSHeight(downloadFrame);
498 }
499 return minY;
500 }
501
502 - (void)layoutTabContentArea:(NSRect)newFrame { 277 - (void)layoutTabContentArea:(NSRect)newFrame {
503 NSView* tabContentView = [self tabContentArea]; 278 NSView* tabContentView = [self tabContentArea];
504 NSRect tabContentFrame = [tabContentView frame]; 279 NSRect tabContentFrame = [tabContentView frame];
505 280
506 bool contentShifted = 281 bool contentShifted =
507 NSMaxY(tabContentFrame) != NSMaxY(newFrame) || 282 NSMaxY(tabContentFrame) != NSMaxY(newFrame) ||
508 NSMinX(tabContentFrame) != NSMinX(newFrame); 283 NSMinX(tabContentFrame) != NSMinX(newFrame);
509 284
510 tabContentFrame = newFrame; 285 tabContentFrame = newFrame;
511 [tabContentView setFrame:tabContentFrame]; 286 [tabContentView setFrame:tabContentFrame];
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 [superview addSubview:view 777 [superview addSubview:view
1003 positioned:NSWindowAbove 778 positioned:NSWindowAbove
1004 relativeTo:siblingBelow]; 779 relativeTo:siblingBelow];
1005 } else { 780 } else {
1006 [superview addSubview:view 781 [superview addSubview:view
1007 positioned:NSWindowBelow 782 positioned:NSWindowBelow
1008 relativeTo:nil]; 783 relativeTo:nil];
1009 } 784 }
1010 } 785 }
1011 786
1012 // TODO(erikchen): The implementation of this method is quite fragile. The 787 - (void)updateInfoBarTipVisibility {
1013 // method cr_ensureSubview:... does not check that the subview is /directly/ 788 // If there's no toolbar then hide the infobar tip.
1014 // above/below the given view. e.g. There are 3 subviews: A, B, C, in that 789 [infoBarContainerController_
1015 // order. The method cr_ensureSubview:A isPositioned:NSWindowBelow 790 setShouldSuppressTopInfoBarTip:![self hasToolbar]];
1016 // relativeTo:C will have no effect, even though the desired result may have 791 }
1017 // been: B, A, C. Consider changing it? 792
1018 - (void)updateSubviewZOrder:(BOOL)inAnyFullscreen { 793 - (NSInteger)pageInfoBubblePointY {
1019 NSView* contentView = [[self window] contentView]; 794 LocationBarViewMac* locationBarView = [self locationBarBridge];
1020 NSView* toolbarView = [toolbarController_ view]; 795
1021 796 // The point, in window coordinates.
1022 if (inAnyFullscreen) { 797 NSPoint iconBottom = locationBarView->GetPageInfoBubblePoint();
1023 // Toolbar is above tab contents so that it can slide down from top of 798
1024 // screen. 799 // The toolbar, in window coordinates.
1025 [contentView cr_ensureSubview:toolbarView 800 NSView* toolbar = [toolbarController_ view];
1026 isPositioned:NSWindowAbove 801 CGFloat toolbarY = NSMinY([toolbar convertRect:[toolbar bounds] toView:nil]);
1027 relativeTo:[self tabContentArea]]; 802
803 return iconBottom.y - toolbarY;
804 }
805
806 - (void)enterAppKitFullscreen {
807 DCHECK(base::mac::IsOSLionOrLater());
808 if (FramedBrowserWindow* framedBrowserWindow =
809 base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
810 [framedBrowserWindow toggleSystemFullScreen];
811 }
812 }
813
814 - (void)exitAppKitFullscreen {
815 DCHECK(base::mac::IsOSLionOrLater());
816 if (FramedBrowserWindow* framedBrowserWindow =
817 base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
818 [framedBrowserWindow toggleSystemFullScreen];
819 }
820 }
821
822 - (void)updateLayoutParameters:(BrowserWindowLayout*)layout {
823 [layout setContentViewSize:[[[self window] contentView] bounds].size];
824 [layout setWindowSize:[[self window] frame].size];
825
826 [layout setInAnyFullscreen:[self isInFullscreenWithOmniboxSliding]];
827 [layout setFullscreenSlidingStyle:
828 presentationModeController_.get().slidingStyle];
829 [layout setFullscreenMenubarOffset:
830 [presentationModeController_ menubarOffset]];
831 [layout setFullscreenToolbarFraction:
832 [presentationModeController_ toolbarFraction]];
833
834 [layout setHasTabStrip:[self hasTabStrip]];
835
836 [layout setHasToolbar:[self hasToolbar]];
837 [layout setToolbarHeight:NSHeight([[toolbarController_ view] bounds])];
838
839 [layout setHasLocationBar:[self hasLocationBar]];
840
841 [layout setPlaceBookmarkBarBelowInfoBar:[self placeBookmarkBarBelowInfoBar]];
842 [layout setBookmarkBarHidden:[bookmarkBarController_ view].isHidden];
843 [layout setBookmarkBarHeight:
844 NSHeight([[bookmarkBarController_ view] bounds])];
845
846 [layout setInfoBarHeight:[infoBarContainerController_ heightOfInfoBars]];
847 [layout setPageInfoBubblePointY:[self pageInfoBubblePointY]];
848
849 [layout setHasDownloadShelf:(downloadShelfController_.get() != nil)];
850 [layout setDownloadShelfHeight:
851 NSHeight([[downloadShelfController_ view] bounds])];
852 }
853
854 - (void)applyLayout:(BrowserWindowLayout*)layout {
855 chrome::LayoutOutput output = [layout computeLayout];
856
857 if (!NSIsEmptyRect(output.tabStripFrame)) {
858 // Note: The fullscreen parameter passed to the method is different from
859 // the field in |parameters| with the similar name.
860 [self layoutTabStripAtMaxY:NSMaxY(output.tabStripFrame)
861 width:NSWidth(output.tabStripFrame)
862 fullscreen:[self isInAnyFullscreenMode]];
863 }
864
865 if (!NSIsEmptyRect(output.toolbarFrame)) {
866 [[toolbarController_ view] setFrame:output.toolbarFrame];
867 }
868
869 if (!NSIsEmptyRect(output.bookmarkFrame)) {
870 NSView* bookmarkBarView = [bookmarkBarController_ view];
871 [bookmarkBarView setFrame:output.bookmarkFrame];
872
873 // Pin the bookmark bar to the top of the window and make the width
874 // flexible.
875 [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
876
877 [bookmarkBarController_ layoutSubviews];
878 }
879
880 // The info bar is never hidden. Sometimes it has zero effective height.
881 [[infoBarContainerController_ view] setFrame:output.infoBarFrame];
882 [infoBarContainerController_
883 setMaxTopArrowHeight:output.infoBarMaxTopArrowHeight];
884
885 if (!NSIsEmptyRect(output.downloadShelfFrame))
886 [[downloadShelfController_ view] setFrame:output.downloadShelfFrame];
887
888 [self layoutTabContentArea:output.contentAreaFrame];
889
890 if (!NSIsEmptyRect(output.fullscreenBackingBarFrame)) {
891 [floatingBarBackingView_ setFrame:output.fullscreenBackingBarFrame];
892 [presentationModeController_
893 overlayFrameChanged:output.fullscreenBackingBarFrame];
894 }
895
896 [findBarCocoaController_
897 positionFindBarViewAtMaxY:output.findBarMaxY
898 maxWidth:NSWidth(output.contentAreaFrame)];
899
900 [fullscreenExitBubbleController_
901 positionInWindowAtTop:output.fullscreenExitButtonMaxY
902 width:NSWidth(output.contentAreaFrame)];
903 }
904
905 - (void)updateSubviewZOrder {
906 if ([self isInFullscreenWithOmniboxSliding])
907 [self updateSubviewZOrderFullscreen];
908 else
909 [self updateSubviewZOrderNormal];
910
911 [self updateSubviewZOrderHack];
912 }
913
914 - (void)updateSubviewZOrderNormal {
915 base::scoped_nsobject<NSMutableArray> subviews([[NSMutableArray alloc] init]);
916 if ([downloadShelfController_ view])
917 [subviews addObject:[downloadShelfController_ view]];
918 if ([bookmarkBarController_ view])
919 [subviews addObject:[bookmarkBarController_ view]];
920 if ([toolbarController_ view])
921 [subviews addObject:[toolbarController_ view]];
922 if ([infoBarContainerController_ view])
923 [subviews addObject:[infoBarContainerController_ view]];
924 if ([self tabContentArea])
925 [subviews addObject:[self tabContentArea]];
926 if ([findBarCocoaController_ view])
927 [subviews addObject:[findBarCocoaController_ view]];
928
929 [self setContentViewSubviews:subviews];
930 }
931
932 - (void)updateSubviewZOrderFullscreen {
933 base::scoped_nsobject<NSMutableArray> subviews([[NSMutableArray alloc] init]);
934 if ([downloadShelfController_ view])
935 [subviews addObject:[downloadShelfController_ view]];
936 if ([infoBarContainerController_ view])
937 [subviews addObject:[infoBarContainerController_ view]];
938 if ([self tabContentArea])
939 [subviews addObject:[self tabContentArea]];
940 if ([self placeBookmarkBarBelowInfoBar]) {
941 if ([bookmarkBarController_ view])
942 [subviews addObject:[bookmarkBarController_ view]];
943 if (floatingBarBackingView_)
944 [subviews addObject:floatingBarBackingView_];
1028 } else { 945 } else {
1029 // Toolbar is below tab contents so that the info bar arrow can appear above 946 if (floatingBarBackingView_)
1030 // it. 947 [subviews addObject:floatingBarBackingView_];
1031 [contentView cr_ensureSubview:toolbarView 948 if ([bookmarkBarController_ view])
1032 isPositioned:NSWindowBelow 949 [subviews addObject:[bookmarkBarController_ view]];
1033 relativeTo:[self tabContentArea]]; 950 }
1034 } 951
1035 952 if ([toolbarController_ view])
1036 // The bookmark bar is always below the toolbar. 953 [subviews addObject:[toolbarController_ view]];
1037 [contentView cr_ensureSubview:[bookmarkBarController_ view] 954 if ([findBarCocoaController_ view])
1038 isPositioned:NSWindowBelow 955 [subviews addObject:[findBarCocoaController_ view]];
1039 relativeTo:toolbarView]; 956
1040 957 [self setContentViewSubviews:subviews];
1041 if (inAnyFullscreen) { 958 }
1042 // In presentation mode the info bar is below all other views. 959
1043 [contentView cr_ensureSubview:[infoBarContainerController_ view] 960 - (void)setContentViewSubviews:(NSArray*)subviews {
1044 isPositioned:NSWindowBelow 961 // Subviews already match.
1045 relativeTo:[self tabContentArea]]; 962 if ([[self.window.contentView subviews] isEqual:subviews])
1046 } else { 963 return;
1047 // Above the toolbar but still below tab contents. Similar to the bookmark 964
1048 // bar, this allows Instant results to be above the info bar. 965 // The tabContentArea isn't a subview, so just set all the subviews.
1049 [contentView cr_ensureSubview:[infoBarContainerController_ view] 966 NSView* tabContentArea = [self tabContentArea];
1050 isPositioned:NSWindowAbove 967 if (![[self.window.contentView subviews] containsObject:tabContentArea]) {
1051 relativeTo:toolbarView]; 968 [self.window.contentView setSubviews:subviews];
1052 } 969 return;
1053 970 }
1054 // The find bar is above everything. 971
1055 if (findBarCocoaController_) { 972 // Remove all subviews that aren't the tabContentArea.
1056 NSView* relativeView = nil; 973 for (NSView* view in [[self.window.contentView subviews] copy]) {
1057 if (inAnyFullscreen) 974 if (view != tabContentArea)
1058 relativeView = toolbarView; 975 [view removeFromSuperview];
1059 else 976 }
1060 relativeView = [self tabContentArea]; 977
1061 [contentView cr_ensureSubview:[findBarCocoaController_ view] 978 // Add in the subviews below the tabContentArea.
1062 isPositioned:NSWindowAbove 979 NSInteger index = [subviews indexOfObject:tabContentArea];
1063 relativeTo:relativeView]; 980 for (int i = index - 1; i >= 0; --i) {
1064 } 981 NSView* view = [subviews objectAtIndex:i];
1065 982 [self.window.contentView addSubview:view
1066 if (floatingBarBackingView_) { 983 positioned:NSWindowBelow
1067 if ([floatingBarBackingView_ cr_isBelowView:[self tabContentArea]]) 984 relativeTo:nil];
1068 [floatingBarBackingView_ removeFromSuperview]; 985 }
1069 if ([self placeBookmarkBarBelowInfoBar]) { 986
1070 [contentView cr_ensureSubview:floatingBarBackingView_ 987 // Add in the subviews above the tabContentArea.
1071 isPositioned:NSWindowAbove 988 for (NSUInteger i = index + 1; i < [subviews count]; ++i) {
1072 relativeTo:[bookmarkBarController_ view]]; 989 NSView* view = [subviews objectAtIndex:i];
1073 } else { 990 [self.window.contentView addSubview:view
1074 [contentView cr_ensureSubview:floatingBarBackingView_ 991 positioned:NSWindowAbove
1075 isPositioned:NSWindowBelow 992 relativeTo:nil];
1076 relativeTo:[bookmarkBarController_ view]]; 993 }
1077 } 994 }
1078 995
1079 // TODO(erikchen): This constraint is necessary. See comment at the 996 - (void)updateSubviewZOrderHack {
1080 // beginning of the method.
1081 [contentView cr_ensureSubview:floatingBarBackingView_
1082 isPositioned:NSWindowAbove
1083 relativeTo:[self tabContentArea]];
1084 }
1085
1086 // TODO(erikchen): Remove and then add the tabStripView to the root NSView. 997 // TODO(erikchen): Remove and then add the tabStripView to the root NSView.
1087 // This fixes a layer ordering problem that occurs between the contentView 998 // This fixes a layer ordering problem that occurs between the contentView
1088 // and the tabStripView. This is a hack required because NSThemeFrame is not 999 // and the tabStripView. This is a hack required because NSThemeFrame is not
1089 // layer backed, and because Chrome adds subviews directly to the 1000 // layer backed, and because Chrome adds subviews directly to the
1090 // NSThemeFrame. 1001 // NSThemeFrame.
1091 // http://crbug.com/407921 1002 // http://crbug.com/407921
1092 if (enteringAppKitFullscreen_) { 1003 if (enteringAppKitFullscreen_) {
1093 // The tabstrip frequently lies outside the bounds of its superview. 1004 // The tabstrip frequently lies outside the bounds of its superview.
1094 // Repeatedly adding/removing the tabstrip from its superview during the 1005 // Repeatedly adding/removing the tabstrip from its superview during the
1095 // AppKit Fullscreen transition causes graphical glitches on 10.10. The 1006 // AppKit Fullscreen transition causes graphical glitches on 10.10. The
1096 // correct solution is to use the AppKit fullscreen transition APIs added 1007 // correct solution is to use the AppKit fullscreen transition APIs added
1097 // in 10.7+. 1008 // in 10.7+.
1098 // http://crbug.com/408791 1009 // http://crbug.com/408791
1099 if (!hasAdjustedTabStripWhileEnteringAppKitFullscreen_) { 1010 if (!hasAdjustedTabStripWhileEnteringAppKitFullscreen_) {
1100 // Disable implicit animations. 1011 // Disable implicit animations.
1101 [CATransaction begin]; 1012 [CATransaction begin];
1102 [CATransaction setDisableActions:YES]; 1013 [CATransaction setDisableActions:YES];
1103 1014
1104 [self updateLayerOrdering:[self tabStripView]]; 1015 [self updateLayerOrdering:[self tabStripView]];
1105 [self updateLayerOrdering:[avatarButtonController_ view]]; 1016 [self updateLayerOrdering:[avatarButtonController_ view]];
1106 1017
1107 [CATransaction commit]; 1018 [CATransaction commit];
1108 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES; 1019 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES;
1109 } 1020 }
1110 } else { 1021 } else {
1111 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO; 1022 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO;
1112 } 1023 }
1113 } 1024 }
1114 1025
1115 - (void)updateInfoBarTipVisibility {
1116 // If there's no toolbar then hide the infobar tip.
1117 [infoBarContainerController_
1118 setShouldSuppressTopInfoBarTip:![self hasToolbar]];
1119 }
1120
1121 - (NSInteger)infoBarMaxTopArrowHeight {
1122 NSInteger topArrowHeight = 0;
1123 LocationBarViewMac* locationBarView = [self locationBarBridge];
1124 NSPoint iconBottom = locationBarView->GetPageInfoBubblePoint();
1125
1126 CGFloat overlappingTipHeight =
1127 [infoBarContainerController_ overlappingTipHeight];
1128 NSPoint infoBarTop =
1129 NSMakePoint(0, NSHeight([infoBarContainerController_ view].frame) -
1130 overlappingTipHeight);
1131 infoBarTop = [[infoBarContainerController_ view] convertPoint:infoBarTop
1132 toView:nil];
1133
1134 topArrowHeight = iconBottom.y - infoBarTop.y;
1135 return topArrowHeight;
1136 }
1137
1138 - (void)enterAppKitFullscreen {
1139 DCHECK(base::mac::IsOSLionOrLater());
1140 if (FramedBrowserWindow* framedBrowserWindow =
1141 base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
1142 [framedBrowserWindow toggleSystemFullScreen];
1143 }
1144 }
1145
1146 - (void)exitAppKitFullscreen {
1147 DCHECK(base::mac::IsOSLionOrLater());
1148 if (FramedBrowserWindow* framedBrowserWindow =
1149 base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
1150 [framedBrowserWindow toggleSystemFullScreen];
1151 }
1152 }
1153
1154 @end // @implementation BrowserWindowController(Private) 1026 @end // @implementation BrowserWindowController(Private)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698