Commit 9e9bbb50 authored by erikchen's avatar erikchen Committed by Commit bot

mac, yosemite: Resize button causes fullscreen effect.

In Yosemite, no views can be in front of the traffic lights controls. Move the
content view and the tab strip view to the back of the NSThemeFrame.

BUG=408094

Review URL: https://codereview.chromium.org/520733004

Cr-Commit-Position: refs/heads/master@{#293080}
parent dc463a9f
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/nsview_additions.h"
#import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h" #import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h"
#import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h" #import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
#include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar.h"
...@@ -213,6 +214,19 @@ class BrowserWindowControllerTest : public InProcessBrowserTest { ...@@ -213,6 +214,19 @@ class BrowserWindowControllerTest : public InProcessBrowserTest {
convertPoint:info_bar_top toView:nil]; convertPoint:info_bar_top toView:nil];
return icon_bottom.y - info_bar_top.y; return icon_bottom.y - info_bar_top.y;
} }
// The traffic lights should always be in front of the content view and the
// tab strip view. Since the traffic lights change across OSX versions, this
// test verifies that the contentView is in the back, and if the tab strip
// view is a sibling, it is directly in front of the content view.
void VerifyTrafficLightZOrder() const {
NSView* contentView = [[controller() window] contentView];
NSView* rootView = [contentView superview];
EXPECT_EQ(contentView, [[rootView subviews] objectAtIndex:0]);
NSView* tabStripView = [controller() tabStripView];
if ([[rootView subviews] containsObject:tabStripView])
EXPECT_EQ(tabStripView, [[rootView subviews] objectAtIndex:1]);
}
private: private:
DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest); DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest);
...@@ -462,3 +476,18 @@ IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, ...@@ -462,3 +476,18 @@ IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest,
EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height), EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height),
[[controller() infoBarContainerController] overlappingTipHeight]); [[controller() infoBarContainerController] overlappingTipHeight]);
} }
IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) {
// Verify z order immediately after creation.
VerifyTrafficLightZOrder();
// Toggle overlay, then verify z order.
[controller() showOverlay];
[controller() removeOverlay];
VerifyTrafficLightZOrder();
// Toggle immersive fullscreen, then verify z order.
[controller() enterImmersiveFullscreen];
[controller() exitImmersiveFullscreen];
VerifyTrafficLightZOrder();
}
...@@ -584,6 +584,7 @@ willPositionSheet:(NSWindow*)sheet ...@@ -584,6 +584,7 @@ willPositionSheet:(NSWindow*)sheet
// or view manipulation Cocoa calls. Stack added to suppressions_mac.txt. // or view manipulation Cocoa calls. Stack added to suppressions_mac.txt.
[contentView setAutoresizesSubviews:YES]; [contentView setAutoresizesSubviews:YES];
[destWindow setContentView:contentView]; [destWindow setContentView:contentView];
[self moveContentViewToBack:contentView];
// Move the incognito badge if present. // Move the incognito badge if present.
if ([self shouldShowAvatar]) { if ([self shouldShowAvatar]) {
...@@ -597,7 +598,7 @@ willPositionSheet:(NSWindow*)sheet ...@@ -597,7 +598,7 @@ willPositionSheet:(NSWindow*)sheet
// Add the tab strip after setting the content view and moving the incognito // Add the tab strip after setting the content view and moving the incognito
// badge (if any), so that the tab strip will be on top (in the z-order). // badge (if any), so that the tab strip will be on top (in the z-order).
if ([self hasTabStrip]) if ([self hasTabStrip])
[[destWindow cr_windowView] addSubview:tabStripView]; [self insertTabStripView:tabStripView intoWindow:[self window]];
[sourceWindow setWindowController:nil]; [sourceWindow setWindowController:nil];
[self setWindow:destWindow]; [self setWindow:destWindow];
......
...@@ -141,6 +141,20 @@ ...@@ -141,6 +141,20 @@
// during a drag. // during a drag.
- (void)deferPerformClose; - (void)deferPerformClose;
// There are 2 view hierarchy constraints that must be enforced:
// - The tab strip must be above the content view.
// - The tab strip must be below the traffic lights.
// AppKit does not enforce these constraints, because it assumes that Chrome
// does not mess with the NSThemeFrame. Chrome must manually enforce these
// constraints.
//
// Immediately after creation of the window, or after the window's content view
// is changed, the content view must be moved to the back.
- (void)moveContentViewToBack:(NSView*)contentView;
// The tab strip should always be inserted directly above the content view.
- (void)insertTabStripView:(NSView*)tabStripView intoWindow:(NSWindow*)window;
@end @end
@interface TabWindowController(ProtectedMethods) @interface TabWindowController(ProtectedMethods)
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
base::scoped_nsobject<FramedBrowserWindow> window( base::scoped_nsobject<FramedBrowserWindow> window(
[[FramedBrowserWindow alloc] initWithContentRect:contentRect [[FramedBrowserWindow alloc] initWithContentRect:contentRect
hasTabStrip:hasTabStrip]); hasTabStrip:hasTabStrip]);
[self moveContentViewToBack:[window contentView]];
[window setReleasedWhenClosed:YES]; [window setReleasedWhenClosed:YES];
[window setAutorecalculatesKeyViewLoop:YES]; [window setAutorecalculatesKeyViewLoop:YES];
...@@ -68,7 +69,7 @@ ...@@ -68,7 +69,7 @@
[tabStripView_ setAutoresizingMask:NSViewWidthSizable | [tabStripView_ setAutoresizingMask:NSViewWidthSizable |
NSViewMinYMargin]; NSViewMinYMargin];
if (hasTabStrip) if (hasTabStrip)
[self addTabStripToWindow]; [self insertTabStripView:tabStripView_ intoWindow:[self window]];
} }
return self; return self;
} }
...@@ -81,16 +82,6 @@ ...@@ -81,16 +82,6 @@
return tabContentArea_; return tabContentArea_;
} }
// Add the top tab strop to the window, above the content box and add it to the
// view hierarchy as a sibling of the content view so it can overlap with the
// window frame.
- (void)addTabStripToWindow {
// The frame doesn't matter. This class relies on subclasses to do tab strip
// layout.
NSView* contentParent = [[self window] cr_windowView];
[contentParent addSubview:tabStripView_];
}
- (void)removeOverlay { - (void)removeOverlay {
[self setUseOverlay:NO]; [self setUseOverlay:NO];
if (closeDeferred_) { if (closeDeferred_) {
...@@ -154,7 +145,8 @@ ...@@ -154,7 +145,8 @@
// content view and therefore it should always be added after the content // content view and therefore it should always be added after the content
// view is set. // view is set.
[window setContentView:originalContentView_]; [window setContentView:originalContentView_];
[[window cr_windowView] addSubview:[self tabStripView]]; [self moveContentViewToBack:originalContentView_];
[self insertTabStripView:[self tabStripView] intoWindow:window];
[[window cr_windowView] updateTrackingAreas]; [[window cr_windowView] updateTrackingAreas];
[focusBeforeOverlay_ restoreFocusInWindow:window]; [focusBeforeOverlay_ restoreFocusInWindow:window];
...@@ -292,6 +284,25 @@ ...@@ -292,6 +284,25 @@
closeDeferred_ = YES; closeDeferred_ = YES;
} }
- (void)moveContentViewToBack:(NSView*)cv {
base::scoped_nsobject<NSView> contentView([cv retain]);
NSView* superview = [contentView superview];
[contentView removeFromSuperview];
[superview addSubview:contentView positioned:NSWindowBelow relativeTo:nil];
}
- (void)insertTabStripView:(NSView*)tabStripView intoWindow:(NSWindow*)window {
NSView* contentParent = [window cr_windowView];
if (contentParent == [[window contentView] superview]) {
// Add the tab strip directly above the content view, if they are siblings.
[contentParent addSubview:tabStripView
positioned:NSWindowAbove
relativeTo:[window contentView]];
} else {
[contentParent addSubview:tabStripView];
}
}
// Called when the size of the window content area has changed. Override to // Called when the size of the window content area has changed. Override to
// position specific views. Base class implementation does nothing. // position specific views. Base class implementation does nothing.
- (void)layoutSubviews { - (void)layoutSubviews {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment