Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 976 if (!barVisibilityUpdatesEnabled_ || [barVisibilityLocks_ count]) | 751 if (!barVisibilityUpdatesEnabled_ || [barVisibilityLocks_ count]) |
| 977 return; | 752 return; |
| 978 [presentationModeController_ ensureOverlayHiddenWithAnimation:animation | 753 [presentationModeController_ ensureOverlayHiddenWithAnimation:animation |
| 979 delay:delay]; | 754 delay:delay]; |
| 980 } | 755 } |
| 981 | 756 |
| 982 - (CGFloat)toolbarDividerOpacity { | 757 - (CGFloat)toolbarDividerOpacity { |
| 983 return [bookmarkBarController_ toolbarDividerOpacity]; | 758 return [bookmarkBarController_ toolbarDividerOpacity]; |
| 984 } | 759 } |
| 985 | 760 |
| 986 // TODO(erikchen): The implementation of this method is quite fragile. The | 761 - (void)updateInfoBarTipVisibility { |
| 987 // method cr_ensureSubview:... does not check that the subview is /directly/ | 762 // If there's no toolbar then hide the infobar tip. |
| 988 // above/below the given view. e.g. There are 3 subviews: A, B, C, in that | 763 [infoBarContainerController_ |
| 989 // order. The method cr_ensureSubview:A isPositioned:NSWindowBelow | 764 setShouldSuppressTopInfoBarTip:![self hasToolbar]]; |
| 990 // relativeTo:C will have no effect, even though the desired result may have | 765 } |
| 991 // been: B, A, C. Consider changing it? | 766 |
| 992 - (void)updateSubviewZOrder:(BOOL)inAnyFullscreen { | 767 - (NSInteger)infoBarMaxTopArrowHeight { |
| 993 NSView* contentView = [[self window] contentView]; | 768 LocationBarViewMac* locationBarView = [self locationBarBridge]; |
| 994 NSView* toolbarView = [toolbarController_ view]; | 769 |
| 995 | 770 // The point, in window coordinates. |
| 996 if (inAnyFullscreen) { | 771 NSPoint iconBottom = locationBarView->GetPageInfoBubblePoint(); |
| 997 // Toolbar is above tab contents so that it can slide down from top of | 772 |
| 998 // screen. | 773 // The toolbar, in window coordinates. |
| 999 [contentView cr_ensureSubview:toolbarView | 774 NSView* toolbar = [toolbarController_ view]; |
| 1000 isPositioned:NSWindowAbove | 775 CGFloat toolbarY = NSMinY([toolbar convertRect:[toolbar bounds] toView:nil]); |
| 1001 relativeTo:[self tabContentArea]]; | 776 |
| 777 return iconBottom.y - toolbarY; | |
| 778 } | |
| 779 | |
| 780 - (void)enterAppKitFullscreen { | |
| 781 DCHECK(base::mac::IsOSLionOrLater()); | |
| 782 if (FramedBrowserWindow* framedBrowserWindow = | |
| 783 base::mac::ObjCCast<FramedBrowserWindow>([self window])) { | |
| 784 [framedBrowserWindow toggleSystemFullScreen]; | |
| 785 } | |
| 786 } | |
| 787 | |
| 788 - (void)exitAppKitFullscreen { | |
| 789 DCHECK(base::mac::IsOSLionOrLater()); | |
| 790 if (FramedBrowserWindow* framedBrowserWindow = | |
| 791 base::mac::ObjCCast<FramedBrowserWindow>([self window])) { | |
| 792 [framedBrowserWindow toggleSystemFullScreen]; | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 - (void)updateLayoutParameters:(BrowserWindowLayout*)layout { | |
| 797 [layout setContentViewSize:[[[self window] contentView] bounds].size]; | |
| 798 [layout setWindowSize:[[self window] frame].size]; | |
| 799 | |
| 800 [layout setInAnyFullscreen:[self isInFullscreenWithOmniboxSliding]]; | |
| 801 [layout | |
| 802 setFullscreenSlidingStyle:presentationModeController_.get().slidingStyle]; | |
| 803 [layout | |
| 804 setFullscreenMenubarOffset:[presentationModeController_ menubarOffset]]; | |
| 805 [layout setFullscreenToolbarFraction:[presentationModeController_ | |
| 806 toolbarFraction]]; | |
| 807 | |
| 808 [layout setHasTabStrip:[self hasTabStrip]]; | |
| 809 | |
| 810 [layout setHasToolbar:[self hasToolbar]]; | |
| 811 [layout setToolbarHeight:NSHeight([[toolbarController_ view] bounds])]; | |
| 812 | |
| 813 [layout setHasLocationBar:[self hasLocationBar]]; | |
| 814 | |
| 815 [layout setPlaceBookmarkBarBelowInfoBar:[self placeBookmarkBarBelowInfoBar]]; | |
| 816 [layout setBookmarkBarHidden:[bookmarkBarController_ view].isHidden]; | |
| 817 [layout | |
| 818 setBookmarkBarHeight:NSHeight([[bookmarkBarController_ view] bounds])]; | |
| 819 | |
| 820 [layout setInfoBarHeight:[infoBarContainerController_ heightOfInfoBars]]; | |
| 821 [layout setInfoBarMaxTopArrowHeight:[self infoBarMaxTopArrowHeight]]; | |
| 822 | |
| 823 [layout setHasDownloadShelf:(downloadShelfController_.get() != nil)]; | |
| 824 [layout setDownloadShelfHeight:NSHeight( | |
| 825 [[downloadShelfController_ view] bounds])]; | |
| 826 } | |
| 827 | |
| 828 - (void)applyLayout:(BrowserWindowLayout*)layout { | |
| 829 mac_browser::LayoutOutput output = [layout computeLayout]; | |
| 830 | |
| 831 if (!NSIsEmptyRect(output.tabStripFrame)) { | |
| 832 // Note: The fullscreen parameter passed to the method is different from | |
| 833 // the field in |parameters| with the similar name. | |
| 834 [self layoutTabStripAtMaxY:NSMaxY(output.tabStripFrame) | |
| 835 width:NSWidth(output.tabStripFrame) | |
| 836 fullscreen:[self isInAnyFullscreenMode]]; | |
| 837 } | |
| 838 | |
| 839 if (!NSIsEmptyRect(output.toolbarFrame)) { | |
| 840 [[toolbarController_ view] setFrame:output.toolbarFrame]; | |
| 841 } | |
| 842 | |
| 843 if (!NSIsEmptyRect(output.bookmarkFrame)) { | |
| 844 NSView* bookmarkBarView = [bookmarkBarController_ view]; | |
| 845 [bookmarkBarView setFrame:output.bookmarkFrame]; | |
| 846 [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; | |
| 847 // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be | |
| 848 // necessary in the non-NTP case. | |
| 849 [bookmarkBarController_ layoutSubviews]; | |
| 850 } | |
| 851 | |
| 852 // The info bar is never hidden. Sometimes it has zero effective height. | |
| 853 [[infoBarContainerController_ view] setFrame:output.infoBarFrame]; | |
| 854 [infoBarContainerController_ | |
| 855 setMaxTopArrowHeight:output.infoBarMaxTopArrowHeight]; | |
| 856 | |
| 857 if (!NSIsEmptyRect(output.downloadShelfFrame)) | |
| 858 [[downloadShelfController_ view] setFrame:output.downloadShelfFrame]; | |
| 859 | |
| 860 [self layoutTabContentArea:output.contentAreaFrame]; | |
| 861 | |
| 862 if (!NSIsEmptyRect(output.fullscreenBackingBarFrame)) { | |
| 863 [floatingBarBackingView_ setFrame:output.fullscreenBackingBarFrame]; | |
| 864 [presentationModeController_ | |
| 865 overlayFrameChanged:output.fullscreenBackingBarFrame]; | |
| 866 } | |
| 867 | |
| 868 [findBarCocoaController_ | |
| 869 positionFindBarViewAtMaxY:output.findBarMaxY | |
| 870 maxWidth:NSWidth(output.contentAreaFrame)]; | |
| 871 | |
| 872 [fullscreenExitBubbleController_ | |
| 873 positionInWindowAtTop:output.fullscreenExitButtonMaxY | |
| 874 width:NSWidth(output.contentAreaFrame)]; | |
| 875 } | |
| 876 | |
| 877 - (void)updateSubviewZOrder { | |
| 878 if ([self isInFullscreenWithOmniboxSliding]) | |
| 879 [self updateSubviewZOrderFullscreen]; | |
| 880 else | |
| 881 [self updateSubviewZOrderNormal]; | |
| 882 | |
| 883 [self updateSubviewZOrderHack]; | |
| 884 } | |
| 885 | |
| 886 - (void)updateSubviewZOrderNormal { | |
| 887 NSMutableArray* subviews = [NSMutableArray array]; | |
|
Andre
2014/09/10 20:59:59
scoped_nsobject
erikchen
2014/09/10 23:17:34
Done.
| |
| 888 if ([downloadShelfController_ view]) | |
| 889 [subviews addObject:[downloadShelfController_ view]]; | |
| 890 if ([bookmarkBarController_ view]) | |
| 891 [subviews addObject:[bookmarkBarController_ view]]; | |
| 892 if ([toolbarController_ view]) | |
| 893 [subviews addObject:[toolbarController_ view]]; | |
| 894 if ([infoBarContainerController_ view]) | |
| 895 [subviews addObject:[infoBarContainerController_ view]]; | |
| 896 if ([self tabContentArea]) | |
| 897 [subviews addObject:[self tabContentArea]]; | |
| 898 if ([findBarCocoaController_ view]) | |
| 899 [subviews addObject:[findBarCocoaController_ view]]; | |
| 900 | |
| 901 [self setContentViewSubviews:subviews]; | |
| 902 } | |
| 903 | |
| 904 - (void)updateSubviewZOrderFullscreen { | |
| 905 NSMutableArray* subviews = [NSMutableArray array]; | |
|
Andre
2014/09/10 20:59:59
scoped_nsobject
erikchen
2014/09/10 23:17:35
Done.
| |
| 906 if ([downloadShelfController_ view]) | |
| 907 [subviews addObject:[downloadShelfController_ view]]; | |
| 908 if ([infoBarContainerController_ view]) | |
| 909 [subviews addObject:[infoBarContainerController_ view]]; | |
| 910 if ([self tabContentArea]) | |
| 911 [subviews addObject:[self tabContentArea]]; | |
| 912 if ([self placeBookmarkBarBelowInfoBar]) { | |
| 913 if ([bookmarkBarController_ view]) | |
| 914 [subviews addObject:[bookmarkBarController_ view]]; | |
| 915 if (floatingBarBackingView_) | |
| 916 [subviews addObject:floatingBarBackingView_]; | |
| 1002 } else { | 917 } else { |
| 1003 // Toolbar is below tab contents so that the info bar arrow can appear above | 918 if (floatingBarBackingView_) |
| 1004 // it. | 919 [subviews addObject:floatingBarBackingView_]; |
| 1005 [contentView cr_ensureSubview:toolbarView | 920 if ([bookmarkBarController_ view]) |
| 1006 isPositioned:NSWindowBelow | 921 [subviews addObject:[bookmarkBarController_ view]]; |
| 1007 relativeTo:[self tabContentArea]]; | 922 } |
| 1008 } | 923 |
| 1009 | 924 if ([toolbarController_ view]) |
| 1010 // The bookmark bar is always below the toolbar. | 925 [subviews addObject:[toolbarController_ view]]; |
| 1011 [contentView cr_ensureSubview:[bookmarkBarController_ view] | 926 if ([findBarCocoaController_ view]) |
| 1012 isPositioned:NSWindowBelow | 927 [subviews addObject:[findBarCocoaController_ view]]; |
| 1013 relativeTo:toolbarView]; | 928 |
| 1014 | 929 [self setContentViewSubviews:subviews]; |
| 1015 if (inAnyFullscreen) { | 930 } |
| 1016 // In presentation mode the info bar is below all other views. | 931 |
| 1017 [contentView cr_ensureSubview:[infoBarContainerController_ view] | 932 - (void)setContentViewSubviews:(NSArray*)subviews { |
| 1018 isPositioned:NSWindowBelow | 933 // Subviews already match. |
| 1019 relativeTo:[self tabContentArea]]; | 934 if ([[self.window.contentView subviews] isEqual:subviews]) |
| 1020 } else { | 935 return; |
| 1021 // Above the toolbar but still below tab contents. Similar to the bookmark | 936 |
| 1022 // bar, this allows Instant results to be above the info bar. | 937 // The tabContentArea isn't a subview, so just set all the subviews. |
| 1023 [contentView cr_ensureSubview:[infoBarContainerController_ view] | 938 NSView* tabContentArea = [self tabContentArea]; |
| 1024 isPositioned:NSWindowAbove | 939 if (![[self.window.contentView subviews] containsObject:tabContentArea]) { |
| 1025 relativeTo:toolbarView]; | 940 [self.window.contentView setSubviews:subviews]; |
| 1026 } | 941 return; |
| 1027 | 942 } |
| 1028 // The find bar is above everything. | 943 |
| 1029 if (findBarCocoaController_) { | 944 // Remove all subviews that aren't the tabContentArea. |
| 1030 NSView* relativeView = nil; | 945 for (NSView* view in [[self.window.contentView subviews] copy]) { |
| 1031 if (inAnyFullscreen) | 946 if (view != tabContentArea) |
| 1032 relativeView = toolbarView; | 947 [view removeFromSuperview]; |
| 1033 else | 948 } |
| 1034 relativeView = [self tabContentArea]; | 949 |
| 1035 [contentView cr_ensureSubview:[findBarCocoaController_ view] | 950 // Add in the subviews below the tabContentArea. |
| 1036 isPositioned:NSWindowAbove | 951 NSInteger index = [subviews indexOfObject:tabContentArea]; |
| 1037 relativeTo:relativeView]; | 952 for (int i = index - 1; i >= 0; --i) { |
| 1038 } | 953 NSView* view = [subviews objectAtIndex:i]; |
| 1039 | 954 [self.window.contentView addSubview:view |
| 1040 if (floatingBarBackingView_) { | 955 positioned:NSWindowBelow |
| 1041 if ([floatingBarBackingView_ cr_isBelowView:[self tabContentArea]]) | 956 relativeTo:nil]; |
| 1042 [floatingBarBackingView_ removeFromSuperview]; | 957 } |
| 1043 if ([self placeBookmarkBarBelowInfoBar]) { | 958 |
| 1044 [contentView cr_ensureSubview:floatingBarBackingView_ | 959 // Add in the subviews above the tabContentArea. |
| 1045 isPositioned:NSWindowAbove | 960 for (int i = index + 1; i < (int)[subviews count]; ++i) { |
|
Andre
2014/09/10 20:59:59
Is this cast necessary?
Probably better to make i
erikchen
2014/09/10 23:17:35
Done.
| |
| 1046 relativeTo:[bookmarkBarController_ view]]; | 961 NSView* view = [subviews objectAtIndex:i]; |
| 1047 } else { | 962 [self.window.contentView addSubview:view |
| 1048 [contentView cr_ensureSubview:floatingBarBackingView_ | 963 positioned:NSWindowAbove |
| 1049 isPositioned:NSWindowBelow | 964 relativeTo:nil]; |
| 1050 relativeTo:[bookmarkBarController_ view]]; | 965 } |
| 1051 } | 966 } |
| 1052 | 967 |
| 1053 // TODO(erikchen): This constraint is necessary. See comment at the | 968 - (void)updateSubviewZOrderHack { |
| 1054 // beginning of the method. | |
| 1055 [contentView cr_ensureSubview:floatingBarBackingView_ | |
| 1056 isPositioned:NSWindowAbove | |
| 1057 relativeTo:[self tabContentArea]]; | |
| 1058 } | |
| 1059 | |
| 1060 // TODO(erikchen): Remove and then add the tabStripView to the root NSView. | 969 // TODO(erikchen): Remove and then add the tabStripView to the root NSView. |
| 1061 // This fixes a layer ordering problem that occurs between the contentView | 970 // This fixes a layer ordering problem that occurs between the contentView |
| 1062 // and the tabStripView. This is a hack required because NSThemeFrame is not | 971 // and the tabStripView. This is a hack required because NSThemeFrame is not |
| 1063 // layer backed, and because Chrome adds subviews directly to the | 972 // layer backed, and because Chrome adds subviews directly to the |
| 1064 // NSThemeFrame. | 973 // NSThemeFrame. |
| 1065 // http://crbug.com/407921 | 974 // http://crbug.com/407921 |
| 1066 if (enteringAppKitFullscreen_) { | 975 if (enteringAppKitFullscreen_) { |
| 1067 // The tabstrip frequently lies outside the bounds of its superview. | 976 // The tabstrip frequently lies outside the bounds of its superview. |
| 1068 // Repeatedly adding/removing the tabstrip from its superview during the | 977 // Repeatedly adding/removing the tabstrip from its superview during the |
| 1069 // AppKit Fullscreen transition causes graphical glitches on 10.10. The | 978 // AppKit Fullscreen transition causes graphical glitches on 10.10. The |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1098 } | 1007 } |
| 1099 | 1008 |
| 1100 [CATransaction commit]; | 1009 [CATransaction commit]; |
| 1101 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES; | 1010 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES; |
| 1102 } | 1011 } |
| 1103 } else { | 1012 } else { |
| 1104 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO; | 1013 hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO; |
| 1105 } | 1014 } |
| 1106 } | 1015 } |
| 1107 | 1016 |
| 1108 - (void)updateInfoBarTipVisibility { | |
| 1109 // If there's no toolbar then hide the infobar tip. | |
| 1110 [infoBarContainerController_ | |
| 1111 setShouldSuppressTopInfoBarTip:![self hasToolbar]]; | |
| 1112 } | |
| 1113 | |
| 1114 - (NSInteger)infoBarMaxTopArrowHeight { | |
| 1115 NSInteger topArrowHeight = 0; | |
| 1116 LocationBarViewMac* locationBarView = [self locationBarBridge]; | |
| 1117 NSPoint iconBottom = locationBarView->GetPageInfoBubblePoint(); | |
| 1118 | |
| 1119 CGFloat overlappingTipHeight = | |
| 1120 [infoBarContainerController_ overlappingTipHeight]; | |
| 1121 NSPoint infoBarTop = | |
| 1122 NSMakePoint(0, NSHeight([infoBarContainerController_ view].frame) - | |
| 1123 overlappingTipHeight); | |
| 1124 infoBarTop = [[infoBarContainerController_ view] convertPoint:infoBarTop | |
| 1125 toView:nil]; | |
| 1126 | |
| 1127 topArrowHeight = iconBottom.y - infoBarTop.y; | |
| 1128 return topArrowHeight; | |
| 1129 } | |
| 1130 | |
| 1131 - (void)enterAppKitFullscreen { | |
| 1132 DCHECK(base::mac::IsOSLionOrLater()); | |
| 1133 if (FramedBrowserWindow* framedBrowserWindow = | |
| 1134 base::mac::ObjCCast<FramedBrowserWindow>([self window])) { | |
| 1135 [framedBrowserWindow toggleSystemFullScreen]; | |
| 1136 } | |
| 1137 } | |
| 1138 | |
| 1139 - (void)exitAppKitFullscreen { | |
| 1140 DCHECK(base::mac::IsOSLionOrLater()); | |
| 1141 if (FramedBrowserWindow* framedBrowserWindow = | |
| 1142 base::mac::ObjCCast<FramedBrowserWindow>([self window])) { | |
| 1143 [framedBrowserWindow toggleSystemFullScreen]; | |
| 1144 } | |
| 1145 } | |
| 1146 | |
| 1147 @end // @implementation BrowserWindowController(Private) | 1017 @end // @implementation BrowserWindowController(Private) |
| OLD | NEW |