Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / browser_window_controller_private.mm
index 6132d6e..9e760f3 100644 (file)
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/mac/mac_util.h"
 #import "base/mac/scoped_nsobject.h"
+#import "base/mac/sdk_forward_declarations.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window_state.h"
+#import "chrome/browser/ui/cocoa/browser_window_layout.h"
 #import "chrome/browser/ui/cocoa/dev_tools_controller.h"
 #import "chrome/browser/ui/cocoa/fast_resize_view.h"
 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h"
 #import "chrome/browser/ui/cocoa/floating_bar_backing_view.h"
 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
-#import "chrome/browser/ui/cocoa/fullscreen_mode_controller.h"
 #import "chrome/browser/ui/cocoa/fullscreen_window.h"
 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
-#import "chrome/browser/ui/cocoa/nsview_additions.h"
 #import "chrome/browser/ui/cocoa/presentation_mode_controller.h"
 #import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h"
 #import "chrome/browser/ui/cocoa/profiles/avatar_icon_controller.h"
@@ -44,6 +44,7 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #import "ui/base/cocoa/focus_tracker.h"
+#import "ui/base/cocoa/nsview_additions.h"
 #include "ui/base/ui_base_types.h"
 
 using content::RenderWidgetHostView;
@@ -54,21 +55,6 @@ namespace {
 // Space between the incognito badge and the right edge of the window.
 const CGFloat kAvatarRightOffset = 4;
 
-// The amount by which to shrink the tab strip (on the right) when the
-// incognito badge is present.
-const CGFloat kAvatarTabStripShrink = 18;
-
-// Width of the full screen icon. Used to position the AvatarButton to the
-// left of the icon.
-const CGFloat kFullscreenIconWidth = 32;
-
-// Insets for the location bar, used when the full toolbar is hidden.
-// TODO(viettrungluu): We can argue about the "correct" insetting; I like the
-// following best, though arguably 0 inset is better/more correct.
-const CGFloat kLocBarLeftRightInset = 1;
-const CGFloat kLocBarTopInset = 0;
-const CGFloat kLocBarBottomInset = 1;
-
 }  // namespace
 
 @implementation BrowserWindowController(Private)
@@ -90,7 +76,8 @@ const CGFloat kLocBarBottomInset = 1;
 
   // If we're in fullscreen mode, save the position of the regular window
   // instead.
-  NSWindow* window = [self isFullscreen] ? savedRegularWindow_ : [self window];
+  NSWindow* window =
+      [self isInAnyFullscreenMode] ? savedRegularWindow_ : [self window];
 
   // Window positions are stored relative to the origin of the primary monitor.
   NSRect monitorFrame = [[[NSScreen screens] objectAtIndex:0] frame];
@@ -105,7 +92,7 @@ const CGFloat kLocBarBottomInset = 1;
   ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL;
   if ([window isMiniaturized])
     show_state = ui::SHOW_STATE_MINIMIZED;
-  else if ([self isFullscreen])
+  else if ([self isInAnyFullscreenMode])
     show_state = ui::SHOW_STATE_FULLSCREEN;
   chrome::SaveWindowPlacement(browser_.get(), bounds, show_state);
 
@@ -126,10 +113,11 @@ const CGFloat kLocBarBottomInset = 1;
   gfx::Rect workArea(NSRectToCGRect([windowScreen visibleFrame]));
   workArea.set_y(monitorFrame.size.height - workArea.y() - workArea.height());
 
-  DictionaryPrefUpdate update(
-      prefs,
-      chrome::GetWindowPlacementKey(browser_.get()).c_str());
-  base::DictionaryValue* windowPreferences = update.Get();
+  scoped_ptr<DictionaryPrefUpdate> update =
+      chrome::GetWindowPlacementDictionaryReadWrite(
+          chrome::GetWindowName(browser_.get()),
+          browser_->profile()->GetPrefs());
+  base::DictionaryValue* windowPreferences = update->Get();
   windowPreferences->SetInteger("left", bounds.x());
   windowPreferences->SetInteger("top", bounds.y());
   windowPreferences->SetInteger("right", bounds.right());
@@ -177,131 +165,21 @@ willPositionSheet:(NSWindow*)sheet
 }
 
 - (void)layoutSubviews {
-  // With the exception of the top tab strip, the subviews which we lay out are
-  // subviews of the content view, so we mainly work in the content view's
-  // coordinate system. Note, however, that the content view's coordinate system
-  // and the window's base coordinate system should coincide.
-  NSWindow* window = [self window];
-  NSView* contentView = [window contentView];
-  NSRect contentBounds = [contentView bounds];
-  CGFloat minX = NSMinX(contentBounds);
-  CGFloat minY = NSMinY(contentBounds);
-  CGFloat width = NSWidth(contentBounds);
-
-  BOOL useSimplifiedFullscreen = CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableSimplifiedFullscreen);
-
   // Suppress title drawing if necessary.
-  if ([window respondsToSelector:@selector(setShouldHideTitle:)])
-    [(id)window setShouldHideTitle:![self hasTitleBar]];
+  if ([self.window respondsToSelector:@selector(setShouldHideTitle:)])
+    [(id)self.window setShouldHideTitle:![self hasTitleBar]];
 
-  // Update z-order. The code below depends on this.
-  [self updateSubviewZOrder:[self inPresentationMode]];
-
-  BOOL inPresentationMode = [self inPresentationMode];
-  CGFloat floatingBarHeight = [self floatingBarHeight];
-  // In presentation mode, |yOffset| accounts for the sliding position of the
-  // floating bar and the extra offset needed to dodge the menu bar.
-  CGFloat yOffset = inPresentationMode && !useSimplifiedFullscreen ?
-      (std::floor((1 - floatingBarShownFraction_) * floatingBarHeight) -
-          [presentationModeController_ floatingBarVerticalOffset]) : 0;
-  CGFloat maxY = NSMaxY(contentBounds) + yOffset;
-
-  if ([self hasTabStrip]) {
-    // If we need to lay out the top tab strip, replace |maxY| with a higher
-    // value, and then lay out the tab strip.
-    NSRect windowFrame = [contentView convertRect:[window frame] fromView:nil];
-    maxY = NSHeight(windowFrame) + yOffset;
-    if (useSimplifiedFullscreen && [self isFullscreen]) {
-      CGFloat tabStripHeight = NSHeight([[self tabStripView] frame]);
-      CGFloat revealAmount = (1 - floatingBarShownFraction_) * tabStripHeight;
-      // In simplified fullscreen, only the toolbar is visible by default, and
-      // the tabstrip and menu bar come down (each separately) when the user
-      // mouses near the top of the window. Push the maxY of the toolbar up by
-      // the amount of the tabstrip that is revealed, while removing the amount
-      // of space needed by the menu bar.
-      maxY += std::floor(
-          revealAmount - [fullscreenModeController_ menuBarHeight]);
-    }
-    maxY = [self layoutTabStripAtMaxY:maxY
-                                width:width
-                           fullscreen:[self isFullscreen]];
-  }
-
-  // Sanity-check |maxY|.
-  DCHECK_GE(maxY, minY);
-  DCHECK_LE(maxY, NSMaxY(contentBounds) + yOffset);
-
-  // Place the toolbar at the top of the reserved area.
-  maxY = [self layoutToolbarAtMinX:minX maxY:maxY width:width];
-
-  // If we're not displaying the bookmark bar below the info bar, then it goes
-  // immediately below the toolbar.
-  BOOL placeBookmarkBarBelowInfoBar = [self placeBookmarkBarBelowInfoBar];
-  if (!placeBookmarkBarBelowInfoBar)
-    maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
-
-  // The floating bar backing view doesn't actually add any height.
-  NSRect floatingBarBackingRect =
-      NSMakeRect(minX, maxY, width, floatingBarHeight);
-  [self layoutFloatingBarBackingView:floatingBarBackingRect
-                    presentationMode:inPresentationMode];
-
-  // Place the find bar immediately below the toolbar/attached bookmark bar. In
-  // presentation mode, it hangs off the top of the screen when the bar is
-  // hidden.
-  [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:width];
-  [fullscreenExitBubbleController_ positionInWindowAtTop:maxY width:width];
-
-  // If in presentation mode, reset |maxY| to top of screen, so that the
-  // floating bar slides over the things which appear to be in the content area.
-  if (inPresentationMode ||
-      (useSimplifiedFullscreen && !fullscreenUrl_.is_empty())) {
-    maxY = NSMaxY(contentBounds);
-  }
-
-  // Also place the info bar container immediate below the toolbar, except in
-  // presentation mode in which case it's at the top of the visual content area.
-  maxY = [self layoutInfoBarAtMinX:minX maxY:maxY width:width];
-
-  // If the bookmark bar is detached, place it next in the visual content area.
-  if (placeBookmarkBarBelowInfoBar)
-    maxY = [self layoutBookmarkBarAtMinX:minX maxY:maxY width:width];
-
-  // Place the download shelf, if any, at the bottom of the view.
-  minY = [self layoutDownloadShelfAtMinX:minX minY:minY width:width];
+  [bookmarkBarController_ updateHiddenState];
+  [self updateSubviewZOrder];
 
-  // Finally, the content area takes up all of the remaining space.
-  NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY);
-  [self layoutTabContentArea:contentAreaRect];
+  base::scoped_nsobject<BrowserWindowLayout> layout(
+      [[BrowserWindowLayout alloc] init]);
+  [self updateLayoutParameters:layout];
+  [self applyLayout:layout];
 
-  // Normally, we don't need to tell the toolbar whether or not to show the
-  // divider, but things break down during animation.
   [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]];
 }
 
-- (CGFloat)floatingBarHeight {
-  if (![self inPresentationMode])
-    return 0;
-
-  CGFloat totalHeight = [presentationModeController_ floatingBarVerticalOffset];
-
-  if ([self hasTabStrip])
-    totalHeight += NSHeight([[self tabStripView] frame]);
-
-  if ([self hasToolbar]) {
-    totalHeight += NSHeight([[toolbarController_ view] frame]);
-  } else if ([self hasLocationBar]) {
-    totalHeight += NSHeight([[toolbarController_ view] frame]) +
-                   kLocBarTopInset + kLocBarBottomInset;
-  }
-
-  if (![self placeBookmarkBarBelowInfoBar])
-    totalHeight += NSHeight([[bookmarkBarController_ view] frame]);
-
-  return totalHeight;
-}
-
 - (CGFloat)layoutTabStripAtMaxY:(CGFloat)maxY
                           width:(CGFloat)width
                      fullscreen:(BOOL)fullscreen {
@@ -312,26 +190,34 @@ willPositionSheet:(NSWindow*)sheet
   NSView* tabStripView = [self tabStripView];
   CGFloat tabStripHeight = NSHeight([tabStripView frame]);
   maxY -= tabStripHeight;
-  [tabStripView setFrame:NSMakeRect(0, maxY, width, tabStripHeight)];
+  NSRect tabStripFrame = NSMakeRect(0, maxY, width, tabStripHeight);
+  BOOL requiresRelayout = !NSEqualRects(tabStripFrame, [tabStripView frame]);
 
   // In Yosemite fullscreen, manually add the fullscreen controls to the tab
   // strip.
-  BOOL isInAppKitFullscreen =
-      [self isInSystemFullscreen] || enteringSystemFullscreen_;
   BOOL addControlsInFullscreen =
-      isInAppKitFullscreen && base::mac::IsOSYosemiteOrLater();
+      [self isInAppKitFullscreen] && base::mac::IsOSYosemiteOrLater();
 
   // Set left indentation based on fullscreen mode status.
   CGFloat leftIndent = 0;
   if (!fullscreen || addControlsInFullscreen)
     leftIndent = [[tabStripController_ class] defaultLeftIndentForControls];
-  [tabStripController_ setLeftIndentForControls:leftIndent];
+  if (leftIndent != [tabStripController_ leftIndentForControls]) {
+    [tabStripController_ setLeftIndentForControls:leftIndent];
+    requiresRelayout = YES;
+  }
 
   if (addControlsInFullscreen)
     [tabStripController_ addWindowControls];
   else
     [tabStripController_ removeWindowControls];
 
+  // fullScreenButton is non-nil when isInAnyFullscreenMode is NO, and OS
+  // version is in the range 10.7 <= version <= 10.9. Starting with 10.10, the
+  // zoom/maximize button acts as the fullscreen button.
+  NSButton* fullScreenButton =
+      [[self window] standardWindowButton:NSWindowFullScreenButton];
+
   // Lay out the icognito/avatar badge because calculating the indentation on
   // the right depends on it.
   NSView* avatarButton = [avatarButtonController_ view];
@@ -342,8 +228,8 @@ willPositionSheet:(NSWindow*)sheet
 
     if ([self shouldUseNewAvatarButton]) {
       // The fullscreen icon is displayed to the right of the avatar button.
-      if (![self isFullscreen])
-        badgeXOffset -= kFullscreenIconWidth;
+      if (![self isInAnyFullscreenMode] && fullScreenButton)
+        badgeXOffset -= width - NSMinX([fullScreenButton frame]);
       // Center the button vertically on the tabstrip.
       badgeYOffset = (tabStripHeight - buttonHeight) / 2;
     } else {
@@ -361,67 +247,37 @@ willPositionSheet:(NSWindow*)sheet
   }
 
   // Calculate the right indentation.  The default indentation built into the
-  // tabstrip leaves enough room for the fullscreen button or presentation mode
-  // toggle button on Lion.  On non-Lion systems, the right indent needs to be
+  // tabstrip leaves enough room for the fullscreen button on Lion (10.7) to
+  // Mavericks (10.9).  On 10.6 and >=10.10, the right indent needs to be
   // adjusted to make room for the new tab button when an avatar is present.
   CGFloat rightIndent = 0;
-  if (base::mac::IsOSLionOrLater() &&
-      [[self window] isKindOfClass:[FramedBrowserWindow class]]) {
-    FramedBrowserWindow* window =
-        static_cast<FramedBrowserWindow*>([self window]);
-    rightIndent += -[window fullScreenButtonOriginAdjustment].x;
+  if (![self isInAnyFullscreenMode] && fullScreenButton) {
+    rightIndent = width - NSMinX([fullScreenButton frame]);
 
     if ([self shouldUseNewAvatarButton]) {
-      // The new avatar is wider than the default indentation, so we need to
-      // account for its width.
-      rightIndent += NSWidth([avatarButton frame]) + kAvatarTabStripShrink;
-
-      // When the fullscreen icon is not displayed, return its width to the
-      // tabstrip.
-      if ([self isFullscreen])
-        rightIndent -= kFullscreenIconWidth;
+      // The new avatar button is to the left of the fullscreen button.
+      // (The old avatar button is to the right).
+      rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset;
     }
   } else if ([self shouldShowAvatar]) {
-    rightIndent += kAvatarTabStripShrink +
-        NSWidth([avatarButton frame]) + kAvatarRightOffset;
+    rightIndent += NSWidth([avatarButton frame]) + kAvatarRightOffset;
   }
-  [tabStripController_ setRightIndentForControls:rightIndent];
-
-  // Go ahead and layout the tabs.
-  [tabStripController_ layoutTabsWithoutAnimation];
 
-  return maxY;
-}
+  if (rightIndent != [tabStripController_ rightIndentForControls]) {
+    [tabStripController_ setRightIndentForControls:rightIndent];
+    requiresRelayout = YES;
+  }
 
-- (CGFloat)layoutToolbarAtMinX:(CGFloat)minX
-                          maxY:(CGFloat)maxY
-                         width:(CGFloat)width {
-  NSView* toolbarView = [toolbarController_ view];
-  NSRect toolbarFrame = [toolbarView frame];
-  if ([self hasToolbar]) {
-    // The toolbar is present in the window, so we make room for it.
-    DCHECK(![toolbarView isHidden]);
-    toolbarFrame.origin.x = minX;
-    toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame);
-    toolbarFrame.size.width = width;
-    maxY -= NSHeight(toolbarFrame);
-  } else {
-    if ([self hasLocationBar]) {
-      // Location bar is present with no toolbar. Put a border of
-      // |kLocBar...Inset| pixels around the location bar.
-      // TODO(viettrungluu): This is moderately ridiculous. The toolbar should
-      // really be aware of what its height should be (the way the toolbar
-      // compression stuff is currently set up messes things up).
-      DCHECK(![toolbarView isHidden]);
-      toolbarFrame.origin.x = kLocBarLeftRightInset;
-      toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame) - kLocBarTopInset;
-      toolbarFrame.size.width = width - 2 * kLocBarLeftRightInset;
-      maxY -= kLocBarTopInset + NSHeight(toolbarFrame) + kLocBarBottomInset;
-    } else {
-      DCHECK([toolbarView isHidden]);
-    }
+  // It is undesirable to force tabs relayout when the tap strip's frame did
+  // not change, because it will interrupt tab animations in progress.
+  // In addition, there appears to be an AppKit bug on <10.9 where interrupting
+  // a tab animation resulted in the tab frame being the animator's target
+  // frame instead of the interrupting setFrame. (See http://crbug.com/415093)
+  if (requiresRelayout) {
+    [tabStripView setFrame:tabStripFrame];
+    [tabStripController_ layoutTabsWithoutAnimation];
   }
-  [toolbarView setFrame:toolbarFrame];
+
   return maxY;
 }
 
@@ -434,79 +290,6 @@ willPositionSheet:(NSWindow*)sheet
          [bookmarkBarController_ isAnimatingFromState:BookmarkBar::DETACHED];
 }
 
-- (CGFloat)layoutBookmarkBarAtMinX:(CGFloat)minX
-                              maxY:(CGFloat)maxY
-                             width:(CGFloat)width {
-  [bookmarkBarController_ updateHiddenState];
-
-  NSView* bookmarkBarView = [bookmarkBarController_ view];
-  NSRect frame = [bookmarkBarView frame];
-  frame.origin.x = minX;
-  frame.origin.y = maxY - NSHeight(frame);
-  frame.size.width = width;
-  [bookmarkBarView setFrame:frame];
-  maxY -= NSHeight(frame);
-
-  // Pin the bookmark bar to the top of the window and make the width flexible.
-  [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
-
-  // TODO(viettrungluu): Does this really belong here? Calling it shouldn't be
-  // necessary in the non-NTP case.
-  [bookmarkBarController_ layoutSubviews];
-
-  return maxY;
-}
-
-- (void)layoutFloatingBarBackingView:(NSRect)frame
-                    presentationMode:(BOOL)presentationMode {
-  // Only display when in presentation mode.
-  if (presentationMode) {
-    // For certain window types such as app windows (e.g., the dev tools
-    // window), there's no actual overlay. (Displaying one would result in an
-    // overly sliding in only under the menu, which gives an ugly effect.)
-    if (floatingBarBackingView_.get()) {
-      // Set its frame.
-      [floatingBarBackingView_ setFrame:frame];
-    }
-
-    // But we want the logic to work as usual (for show/hide/etc. purposes).
-    [presentationModeController_ overlayFrameChanged:frame];
-  } else {
-    // Okay to call even if |floatingBarBackingView_| is nil.
-    if ([floatingBarBackingView_ superview])
-      [floatingBarBackingView_ removeFromSuperview];
-  }
-}
-
-- (CGFloat)layoutInfoBarAtMinX:(CGFloat)minX
-                          maxY:(CGFloat)maxY
-                         width:(CGFloat)width {
-  NSView* containerView = [infoBarContainerController_ view];
-  NSRect containerFrame = [containerView frame];
-  maxY -= NSHeight(containerFrame);
-  maxY += [infoBarContainerController_ overlappingTipHeight];
-  containerFrame.origin.x = minX;
-  containerFrame.origin.y = maxY;
-  containerFrame.size.width = width;
-  [containerView setFrame:containerFrame];
-  return maxY;
-}
-
-- (CGFloat)layoutDownloadShelfAtMinX:(CGFloat)minX
-                                minY:(CGFloat)minY
-                               width:(CGFloat)width {
-  if (downloadShelfController_.get()) {
-    NSView* downloadView = [downloadShelfController_ view];
-    NSRect downloadFrame = [downloadView frame];
-    downloadFrame.origin.x = minX;
-    downloadFrame.origin.y = minY;
-    downloadFrame.size.width = width;
-    [downloadView setFrame:downloadFrame];
-    minY += NSHeight(downloadFrame);
-  }
-  return minY;
-}
-
 - (void)layoutTabContentArea:(NSRect)newFrame {
   NSView* tabContentView = [self tabContentArea];
   NSRect tabContentFrame = [tabContentView frame];
@@ -654,63 +437,87 @@ willPositionSheet:(NSWindow*)sheet
                                delay:YES];
 }
 
-- (void)setPresentationModeInternal:(BOOL)presentationMode
-                      forceDropdown:(BOOL)forceDropdown {
-  if (presentationMode == [self inPresentationMode])
-    return;
+- (void)configurePresentationModeController {
+  BOOL fullscreen_for_tab =
+      browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending();
+  BOOL kiosk_mode =
+      CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode);
+  BOOL showDropdown =
+      !fullscreen_for_tab && !kiosk_mode && ([self floatingBarHasFocus]);
+  if (permissionBubbleCocoa_ && permissionBubbleCocoa_->IsVisible()) {
+    DCHECK(permissionBubbleCocoa_->window());
+    // A visible permission bubble will force the dropdown to remain visible.
+    [self lockBarVisibilityForOwner:permissionBubbleCocoa_->window()
+                      withAnimation:NO
+                              delay:NO];
+    showDropdown = YES;
+    // Register to be notified when the permission bubble is closed, to
+    // allow fullscreen to hide the dropdown.
+    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+    [center addObserver:self
+               selector:@selector(permissionBubbleWindowWillClose:)
+                   name:NSWindowWillCloseNotification
+                 object:permissionBubbleCocoa_->window()];
+  }
+  if (showDropdown) {
+    // Turn on layered mode for the window's root view for the entry
+    // animation.  Without this, the OS fullscreen animation for entering
+    // fullscreen mode does not correctly draw the tab strip.
+    // It will be turned off (set back to NO) when the animation finishes,
+    // in -windowDidEnterFullScreen:.
+    // Leaving wantsLayer on for the duration of presentation mode causes
+    // performance issues when the dropdown is animated in/out.  It also does
+    // not seem to be required for the exit animation.
+    windowViewWantsLayer_ = [[[self window] cr_windowView] wantsLayer];
+    [[[self window] cr_windowView] setWantsLayer:YES];
+  }
+
+  NSView* contentView = [[self window] contentView];
+  [presentationModeController_
+      enterPresentationModeForContentView:contentView
+                             showDropdown:showDropdown];
+}
+
+- (void)adjustUIForExitingFullscreenAndStopOmniboxSliding {
+  [presentationModeController_ exitPresentationMode];
+  presentationModeController_.reset();
+
+  // Force the bookmark bar z-order to update.
+  [[bookmarkBarController_ view] removeFromSuperview];
+  [self layoutSubviews];
+}
 
-  if (presentationMode) {
-    BOOL fullscreen_for_tab =
-        browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending();
-    BOOL kiosk_mode =
-        CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode);
-    BOOL showDropdown = !fullscreen_for_tab &&
-        !kiosk_mode &&
-        (forceDropdown || [self floatingBarHasFocus]);
+- (void)adjustUIForSlidingFullscreenStyle:(fullscreen_mac::SlidingStyle)style {
+  if (!presentationModeController_) {
     presentationModeController_.reset(
-        [[PresentationModeController alloc] initWithBrowserController:self]);
-
-    if (permissionBubbleCocoa_ && permissionBubbleCocoa_->IsVisible()) {
-      DCHECK(permissionBubbleCocoa_->window());
-      // A visible permission bubble will force the dropdown to remain visible.
-      [self lockBarVisibilityForOwner:permissionBubbleCocoa_->window()
-                        withAnimation:NO
-                                delay:NO];
-      showDropdown = YES;
-      // Register to be notified when the permission bubble is closed, to
-      // allow fullscreen to hide the dropdown.
-      NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
-      [center addObserver:self
-                 selector:@selector(permissionBubbleWindowWillClose:)
-                     name:NSWindowWillCloseNotification
-                   object:permissionBubbleCocoa_->window()];
-    }
-    if (showDropdown) {
-      // Turn on layered mode for the window's root view for the entry
-      // animation.  Without this, the OS fullscreen animation for entering
-      // fullscreen mode does not correctly draw the tab strip.
-      // It will be turned off (set back to NO) when the animation finishes,
-      // in -windowDidEnterFullScreen:.
-      // Leaving wantsLayer on for the duration of presentation mode causes
-      // performance issues when the dropdown is animated in/out.  It also does
-      // not seem to be required for the exit animation.
-      [[[self window] cr_windowView] setWantsLayer:YES];
-    }
-    NSView* contentView = [[self window] contentView];
-    [presentationModeController_ enterPresentationModeForContentView:contentView
-                                 showDropdown:showDropdown];
+        [self newPresentationModeControllerWithStyle:style]);
+    [self configurePresentationModeController];
   } else {
-    [presentationModeController_ exitPresentationMode];
-    presentationModeController_.reset();
+    presentationModeController_.get().slidingStyle = style;
+  }
+
+  if (!floatingBarBackingView_.get() &&
+      ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) {
+    floatingBarBackingView_.reset(
+        [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]);
+    [floatingBarBackingView_
+        setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
   }
 
-  [self adjustUIForPresentationMode:presentationMode];
+  // Force the bookmark bar z-order to update.
+  [[bookmarkBarController_ view] removeFromSuperview];
   [self layoutSubviews];
 }
 
+- (PresentationModeController*)newPresentationModeControllerWithStyle:
+    (fullscreen_mac::SlidingStyle)style {
+  return [[PresentationModeController alloc] initWithBrowserController:self
+                                                                 style:style];
+}
+
 - (void)enterImmersiveFullscreen {
-  // |-isFullscreen:| will return YES from here onwards.
-  enteringFullscreen_ = YES;  // Set to NO by |-windowDidEnterFullScreen:|.
+  // Set to NO by |-windowDidEnterFullScreen:|.
+  enteringImmersiveFullscreen_ = YES;
 
   // Fade to black.
   const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
@@ -732,14 +539,23 @@ willPositionSheet:(NSWindow*)sheet
                           regularWindow:[self window]
                        fullscreenWindow:fullscreenWindow_.get()];
 
-  // When simplified fullscreen is enabled, do not enter presentation mode.
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
-    // TODO(rohitrao): Add code to manage the menubar here.
-  } else {
-    [self adjustUIForPresentationMode:YES];
-    [self setPresentationModeInternal:YES forceDropdown:NO];
-  }
+  fullscreen_mac::SlidingStyle style = fullscreen_mac::OMNIBOX_TABS_HIDDEN;
+  [self adjustUIForSlidingFullscreenStyle:style];
+
+  // AppKit is helpful and prevents NSWindows from having the same height as
+  // the screen while the menu bar is showing. This only applies to windows on
+  // a secondary screen, in a separate space. Calling [NSWindow
+  // setFrame:display:] with the screen's height will always reduce the
+  // height by the height of the MenuBar. Calling the method with any other
+  // height works fine. The relevant method in the 10.10 AppKit SDK is called:
+  // _canAdjustSizeForScreensHaveSeparateSpacesIfFillingSecondaryScreen
+  //
+  // TODO(erikchen): Refactor the logic to allow the window to be shown after
+  // the menubar has been hidden. This would remove the need for this hack.
+  // http://crbug.com/403203
+  NSRect frame = [[[self window] screen] frame];
+  if (!NSEqualRects(frame, [fullscreenWindow_ frame]))
+    [fullscreenWindow_ setFrame:[[[self window] screen] frame] display:YES];
 
   [self layoutSubviews];
 
@@ -765,13 +581,6 @@ willPositionSheet:(NSWindow*)sheet
         kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true);
   }
 
-  // When simplified fullscreen is enabled, the menubar status is managed
-  // directly by BWC.
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
-    // TODO(rohitrao): Add code to manage the menubar here.
-  }
-
   [self windowWillExitFullScreen:nil];
 
   [self moveViewsForImmersiveFullscreen:NO
@@ -794,33 +603,14 @@ willPositionSheet:(NSWindow*)sheet
   }
 }
 
-// TODO(rohitrao): This function has shrunk into uselessness, and
-// |-setFullscreen:| has grown rather large.  Find a good way to break up
-// |-setFullscreen:| into smaller pieces.  http://crbug.com/36449
-- (void)adjustUIForPresentationMode:(BOOL)fullscreen {
-  // Create the floating bar backing view if necessary.
-  if (fullscreen && !floatingBarBackingView_.get() &&
-      ([self hasTabStrip] || [self hasToolbar] || [self hasLocationBar])) {
-    floatingBarBackingView_.reset(
-        [[FloatingBarBackingView alloc] initWithFrame:NSZeroRect]);
-    [floatingBarBackingView_ setAutoresizingMask:(NSViewWidthSizable |
-                                                  NSViewMinYMargin)];
-  }
-
-  // Force the bookmark bar z-order to update.
-  [[bookmarkBarController_ view] removeFromSuperview];
-  [self updateSubviewZOrder:fullscreen];
-  [self updateAllowOverlappingViews:fullscreen];
-}
-
 - (void)showFullscreenExitBubbleIfNecessary {
   // This method is called in response to
   // |-updateFullscreenExitBubbleURL:bubbleType:|. If we're in the middle of the
-  // transition into fullscreen (i.e., using the System Fullscreen API), do not
+  // transition into fullscreen (i.e., using the AppKit Fullscreen API), do not
   // show the bubble because it will cause visual jank
   // (http://crbug.com/130649). This will be called again as part of
   // |-windowDidEnterFullScreen:|, so arrange to do that work then instead.
-  if (enteringFullscreen_)
+  if (enteringAppKitFullscreen_)
     return;
 
   [self hideOverlayIfPossibleWithAnimation:NO delay:NO];
@@ -885,9 +675,13 @@ willPositionSheet:(NSWindow*)sheet
   savedRegularWindowFrame_ = [window frame];
   BOOL mode = enteringPresentationMode_ ||
        browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending();
-  enteringFullscreen_ = YES;
-  enteringSystemFullscreen_ = YES;
-  [self setPresentationModeInternal:mode forceDropdown:NO];
+  enteringAppKitFullscreen_ = YES;
+
+  fullscreen_mac::SlidingStyle style =
+      mode ? fullscreen_mac::OMNIBOX_TABS_HIDDEN
+           : fullscreen_mac::OMNIBOX_TABS_PRESENT;
+
+  [self adjustUIForSlidingFullscreenStyle:style];
 }
 
 - (void)windowDidEnterFullScreen:(NSNotification*)notification {
@@ -906,28 +700,20 @@ willPositionSheet:(NSWindow*)sheet
 
   if (notification)  // For System Fullscreen when non-nil.
     [self deregisterForContentViewResizeNotifications];
-  enteringFullscreen_ = NO;
-  enteringSystemFullscreen_ = NO;
+  enteringAppKitFullscreen_ = NO;
+  enteringImmersiveFullscreen_ = NO;
   enteringPresentationMode_ = NO;
 
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen) &&
-      fullscreenUrl_.is_empty()) {
-    fullscreenModeController_.reset([[FullscreenModeController alloc]
-        initWithBrowserWindowController:self]);
-  }
-
   [self showFullscreenExitBubbleIfNecessary];
   browser_->WindowFullscreenStateChanged();
-  [[[self window] cr_windowView] setWantsLayer:NO];
+  [[[self window] cr_windowView] setWantsLayer:windowViewWantsLayer_];
 }
 
 - (void)windowWillExitFullScreen:(NSNotification*)notification {
   if (notification)  // For System Fullscreen when non-nil.
     [self registerForContentViewResizeNotifications];
-  fullscreenModeController_.reset();
   [self destroyFullscreenExitBubbleIfNecessary];
-  [self setPresentationModeInternal:NO forceDropdown:NO];
+  [self adjustUIForExitingFullscreenAndStopOmniboxSliding];
 }
 
 - (void)windowDidExitFullScreen:(NSNotification*)notification {
@@ -938,12 +724,8 @@ willPositionSheet:(NSWindow*)sheet
 
 - (void)windowDidFailToEnterFullScreen:(NSWindow*)window {
   [self deregisterForContentViewResizeNotifications];
-  enteringFullscreen_ = NO;
-  enteringSystemFullscreen_ = NO;
-  [self setPresentationModeInternal:NO forceDropdown:NO];
-
-  // Force a relayout to try and get the window back into a reasonable state.
-  [self layoutSubviews];
+  enteringAppKitFullscreen_ = NO;
+  [self adjustUIForExitingFullscreenAndStopOmniboxSliding];
 }
 
 - (void)windowDidFailToExitFullScreen:(NSWindow*)window {
@@ -986,107 +768,274 @@ willPositionSheet:(NSWindow*)sheet
   return [bookmarkBarController_ toolbarDividerOpacity];
 }
 
-- (void)updateSubviewZOrder:(BOOL)inPresentationMode {
-  NSView* contentView = [[self window] contentView];
-  NSView* toolbarView = [toolbarController_ view];
-
-  if (inPresentationMode) {
-    // Toolbar is above tab contents so that it can slide down from top of
-    // screen.
-    [contentView cr_ensureSubview:toolbarView
-                     isPositioned:NSWindowAbove
-                       relativeTo:[self tabContentArea]];
-  } else {
-    // Toolbar is below tab contents so that the info bar arrow can appear above
-    // it.
-    [contentView cr_ensureSubview:toolbarView
-                     isPositioned:NSWindowBelow
-                       relativeTo:[self tabContentArea]];
-  }
+- (void)updateLayerOrdering:(NSView*)view {
+  // Hold a reference to the view so that it doesn't accidentally get
+  // dealloc'ed.
+  base::scoped_nsobject<NSView> reference([view retain]);
 
-  // The bookmark bar is always below the toolbar.
-  [contentView cr_ensureSubview:[bookmarkBarController_ view]
-                   isPositioned:NSWindowBelow
-                     relativeTo:toolbarView];
+  // If the superview has a layer, then this hack isn't required.
+  NSView* superview = [view superview];
+  if ([superview layer])
+    return;
 
-  if (inPresentationMode) {
-    // In presentation mode the info bar is below all other views.
-    [contentView cr_ensureSubview:[infoBarContainerController_ view]
-                     isPositioned:NSWindowBelow
-                       relativeTo:[self tabContentArea]];
+  // Get the current position of the view.
+  NSArray* subviews = [superview subviews];
+  NSInteger index = [subviews indexOfObject:view];
+  NSView* siblingBelow = nil;
+  if (index > 0)
+    siblingBelow = [subviews objectAtIndex:index - 1];
+
+  // Remove the view.
+  [view removeFromSuperview];
+
+  // Add it to the same position.
+  if (siblingBelow) {
+    [superview addSubview:view
+               positioned:NSWindowAbove
+               relativeTo:siblingBelow];
   } else {
-    // Above the toolbar but still below tab contents. Similar to the bookmark
-    // bar, this allows Instant results to be above the info bar.
-    [contentView cr_ensureSubview:[infoBarContainerController_ view]
-                     isPositioned:NSWindowAbove
-                       relativeTo:toolbarView];
+    [superview addSubview:view
+               positioned:NSWindowBelow
+               relativeTo:nil];
   }
+}
+
+- (void)updateInfoBarTipVisibility {
+  // If there's no toolbar then hide the infobar tip.
+  [infoBarContainerController_
+      setShouldSuppressTopInfoBarTip:![self hasToolbar]];
+}
+
+- (NSInteger)pageInfoBubblePointY {
+  LocationBarViewMac* locationBarView = [self locationBarBridge];
+
+  // The point, in window coordinates.
+  NSPoint iconBottom = locationBarView->GetPageInfoBubblePoint();
 
-  // The find bar is above everything.
-  if (findBarCocoaController_) {
-    NSView* relativeView = nil;
-    if (inPresentationMode)
-      relativeView = toolbarView;
-    else
-      relativeView = [self tabContentArea];
-    [contentView cr_ensureSubview:[findBarCocoaController_ view]
-                     isPositioned:NSWindowAbove
-                       relativeTo:relativeView];
+  // The toolbar, in window coordinates.
+  NSView* toolbar = [toolbarController_ view];
+  CGFloat toolbarY = NSMinY([toolbar convertRect:[toolbar bounds] toView:nil]);
+
+  return iconBottom.y - toolbarY;
+}
+
+- (void)enterAppKitFullscreen {
+  DCHECK(base::mac::IsOSLionOrLater());
+  if (FramedBrowserWindow* framedBrowserWindow =
+          base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
+    [framedBrowserWindow toggleSystemFullScreen];
   }
+}
 
-  if (floatingBarBackingView_) {
-    if ([floatingBarBackingView_ cr_isBelowView:[self tabContentArea]])
-      [floatingBarBackingView_ removeFromSuperview];
-    if ([self placeBookmarkBarBelowInfoBar]) {
-      [contentView cr_ensureSubview:floatingBarBackingView_
-                       isPositioned:NSWindowAbove
-                         relativeTo:[bookmarkBarController_ view]];
-    } else {
-      [contentView cr_ensureSubview:floatingBarBackingView_
-                       isPositioned:NSWindowBelow
-                         relativeTo:[bookmarkBarController_ view]];
-    }
+- (void)exitAppKitFullscreen {
+  DCHECK(base::mac::IsOSLionOrLater());
+  if (FramedBrowserWindow* framedBrowserWindow =
+          base::mac::ObjCCast<FramedBrowserWindow>([self window])) {
+    [framedBrowserWindow toggleSystemFullScreen];
   }
 }
 
-- (BOOL)shouldAllowOverlappingViews:(BOOL)inPresentationMode {
-  if (inPresentationMode)
-    return YES;
+- (void)updateLayoutParameters:(BrowserWindowLayout*)layout {
+  [layout setContentViewSize:[[[self window] contentView] bounds].size];
+  [layout setWindowSize:[[self window] frame].size];
+
+  [layout setInAnyFullscreen:[self isInAnyFullscreenMode]];
+  [layout setFullscreenSlidingStyle:
+      presentationModeController_.get().slidingStyle];
+  [layout setFullscreenMenubarOffset:
+      [presentationModeController_ menubarOffset]];
+  [layout setFullscreenToolbarFraction:
+      [presentationModeController_ toolbarFraction]];
+
+  [layout setHasTabStrip:[self hasTabStrip]];
+
+  [layout setHasToolbar:[self hasToolbar]];
+  [layout setToolbarHeight:NSHeight([[toolbarController_ view] bounds])];
+
+  [layout setHasLocationBar:[self hasLocationBar]];
 
-  if (findBarCocoaController_ &&
-      ![[findBarCocoaController_ findBarView] isHidden]) {
-    return YES;
+  [layout setPlaceBookmarkBarBelowInfoBar:[self placeBookmarkBarBelowInfoBar]];
+  [layout setBookmarkBarHidden:[bookmarkBarController_ view].isHidden];
+  [layout setBookmarkBarHeight:
+      NSHeight([[bookmarkBarController_ view] bounds])];
+
+  [layout setInfoBarHeight:[infoBarContainerController_ heightOfInfoBars]];
+  [layout setPageInfoBubblePointY:[self pageInfoBubblePointY]];
+
+  [layout setHasDownloadShelf:(downloadShelfController_.get() != nil)];
+  [layout setDownloadShelfHeight:
+      NSHeight([[downloadShelfController_ view] bounds])];
+}
+
+- (void)applyLayout:(BrowserWindowLayout*)layout {
+  chrome::LayoutOutput output = [layout computeLayout];
+
+  if (!NSIsEmptyRect(output.tabStripFrame)) {
+    // Note: The fullscreen parameter passed to the method is different from
+    // the field in |parameters| with the similar name.
+    [self layoutTabStripAtMaxY:NSMaxY(output.tabStripFrame)
+                         width:NSWidth(output.tabStripFrame)
+                    fullscreen:[self isInAnyFullscreenMode]];
+  }
+
+  if (!NSIsEmptyRect(output.toolbarFrame)) {
+    [[toolbarController_ view] setFrame:output.toolbarFrame];
+  }
+
+  if (!NSIsEmptyRect(output.bookmarkFrame)) {
+    NSView* bookmarkBarView = [bookmarkBarController_ view];
+    [bookmarkBarView setFrame:output.bookmarkFrame];
+
+    // Pin the bookmark bar to the top of the window and make the width
+    // flexible.
+    [bookmarkBarView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
+
+    [bookmarkBarController_ layoutSubviews];
+  }
+
+  // The info bar is never hidden. Sometimes it has zero effective height.
+  [[infoBarContainerController_ view] setFrame:output.infoBarFrame];
+  [infoBarContainerController_
+      setMaxTopArrowHeight:output.infoBarMaxTopArrowHeight];
+
+  if (!NSIsEmptyRect(output.downloadShelfFrame))
+    [[downloadShelfController_ view] setFrame:output.downloadShelfFrame];
+
+  [self layoutTabContentArea:output.contentAreaFrame];
+
+  if (!NSIsEmptyRect(output.fullscreenBackingBarFrame)) {
+    [floatingBarBackingView_ setFrame:output.fullscreenBackingBarFrame];
+    [presentationModeController_
+        overlayFrameChanged:output.fullscreenBackingBarFrame];
   }
 
-  if (overlappedViewCount_)
-    return YES;
+  [findBarCocoaController_
+      positionFindBarViewAtMaxY:output.findBarMaxY
+                       maxWidth:NSWidth(output.contentAreaFrame)];
+
+  [fullscreenExitBubbleController_
+      positionInWindowAtTop:output.fullscreenExitButtonMaxY
+                      width:NSWidth(output.contentAreaFrame)];
+}
+
+- (void)updateSubviewZOrder {
+  if ([self isInAnyFullscreenMode])
+    [self updateSubviewZOrderFullscreen];
+  else
+    [self updateSubviewZOrderNormal];
+
+  [self updateSubviewZOrderHack];
+}
+
+- (void)updateSubviewZOrderNormal {
+  base::scoped_nsobject<NSMutableArray> subviews([[NSMutableArray alloc] init]);
+  if ([downloadShelfController_ view])
+    [subviews addObject:[downloadShelfController_ view]];
+  if ([bookmarkBarController_ view])
+    [subviews addObject:[bookmarkBarController_ view]];
+  if ([toolbarController_ view])
+    [subviews addObject:[toolbarController_ view]];
+  if ([infoBarContainerController_ view])
+    [subviews addObject:[infoBarContainerController_ view]];
+  if ([self tabContentArea])
+    [subviews addObject:[self tabContentArea]];
+  if ([findBarCocoaController_ view])
+    [subviews addObject:[findBarCocoaController_ view]];
+
+  [self setContentViewSubviews:subviews];
+}
 
-  return NO;
+- (void)updateSubviewZOrderFullscreen {
+  base::scoped_nsobject<NSMutableArray> subviews([[NSMutableArray alloc] init]);
+  if ([downloadShelfController_ view])
+    [subviews addObject:[downloadShelfController_ view]];
+  if ([self tabContentArea])
+    [subviews addObject:[self tabContentArea]];
+  if ([self placeBookmarkBarBelowInfoBar]) {
+    if ([bookmarkBarController_ view])
+      [subviews addObject:[bookmarkBarController_ view]];
+    if (floatingBarBackingView_)
+      [subviews addObject:floatingBarBackingView_];
+  } else {
+    if (floatingBarBackingView_)
+      [subviews addObject:floatingBarBackingView_];
+    if ([bookmarkBarController_ view])
+      [subviews addObject:[bookmarkBarController_ view]];
+  }
+  if ([toolbarController_ view])
+    [subviews addObject:[toolbarController_ view]];
+  if ([infoBarContainerController_ view])
+    [subviews addObject:[infoBarContainerController_ view]];
+  if ([findBarCocoaController_ view])
+    [subviews addObject:[findBarCocoaController_ view]];
+
+  [self setContentViewSubviews:subviews];
 }
 
-- (void)updateAllowOverlappingViews:(BOOL)inPresentationMode {
-  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
-  if (!contents)
+- (void)setContentViewSubviews:(NSArray*)subviews {
+  // Subviews already match.
+  if ([[self.window.contentView subviews] isEqual:subviews])
     return;
 
-  BOOL allowOverlappingViews =
-      [self shouldAllowOverlappingViews:inPresentationMode];
+  // The tabContentArea isn't a subview, so just set all the subviews.
+  NSView* tabContentArea = [self tabContentArea];
+  if (![[self.window.contentView subviews] containsObject:tabContentArea]) {
+    [self.window.contentView setSubviews:subviews];
+    return;
+  }
+
+  // Remove all subviews that aren't the tabContentArea.
+  for (NSView* view in [[self.window.contentView subviews] copy]) {
+    if (view != tabContentArea)
+      [view removeFromSuperview];
+  }
 
-  // The rendering path with overlapping views disabled causes bugs when
-  // transitioning between composited and non-composited mode.
-  // http://crbug.com/279472
-  allowOverlappingViews = YES;
-  contents->SetAllowOverlappingViews(allowOverlappingViews);
+  // Add in the subviews below the tabContentArea.
+  NSInteger index = [subviews indexOfObject:tabContentArea];
+  for (int i = index - 1; i >= 0; --i) {
+    NSView* view = [subviews objectAtIndex:i];
+    [self.window.contentView addSubview:view
+                             positioned:NSWindowBelow
+                             relativeTo:nil];
+  }
 
-  WebContents* devTools = DevToolsWindow::GetInTabWebContents(contents, NULL);
-  if (devTools)
-    devTools->SetAllowOverlappingViews(allowOverlappingViews);
+  // Add in the subviews above the tabContentArea.
+  for (NSUInteger i = index + 1; i < [subviews count]; ++i) {
+    NSView* view = [subviews objectAtIndex:i];
+    [self.window.contentView addSubview:view
+                             positioned:NSWindowAbove
+                             relativeTo:nil];
+  }
 }
 
-- (void)updateInfoBarTipVisibility {
-  // If there's no toolbar then hide the infobar tip.
-  [infoBarContainerController_
-      setShouldSuppressTopInfoBarTip:![self hasToolbar]];
+- (void)updateSubviewZOrderHack {
+  // TODO(erikchen): Remove and then add the tabStripView to the root NSView.
+  // This fixes a layer ordering problem that occurs between the contentView
+  // and the tabStripView. This is a hack required because NSThemeFrame is not
+  // layer backed, and because Chrome adds subviews directly to the
+  // NSThemeFrame.
+  // http://crbug.com/407921
+  if (enteringAppKitFullscreen_) {
+    // The tabstrip frequently lies outside the bounds of its superview.
+    // Repeatedly adding/removing the tabstrip from its superview during the
+    // AppKit Fullscreen transition causes graphical glitches on 10.10. The
+    // correct solution is to use the AppKit fullscreen transition APIs added
+    // in 10.7+.
+    // http://crbug.com/408791
+    if (!hasAdjustedTabStripWhileEnteringAppKitFullscreen_) {
+      // Disable implicit animations.
+      [CATransaction begin];
+      [CATransaction setDisableActions:YES];
+
+      [self updateLayerOrdering:[self tabStripView]];
+      [self updateLayerOrdering:[avatarButtonController_ view]];
+
+      [CATransaction commit];
+      hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = YES;
+    }
+  } else {
+    hasAdjustedTabStripWhileEnteringAppKitFullscreen_ = NO;
+  }
 }
 
 @end  // @implementation BrowserWindowController(Private)