diff options
Diffstat (limited to 'chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm')
-rw-r--r-- | chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm | 141 |
1 files changed, 120 insertions, 21 deletions
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm index c8c0e22..a01111c 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm @@ -68,6 +68,96 @@ enum ViewID { VIEW_ID_COUNT, }; +// Checks that no views draw on top of the supposedly exposed view. +class ViewExposedChecker { + public: + ViewExposedChecker() : below_exposed_view_(YES) {} + ~ViewExposedChecker() {} + + void SetExceptions(NSArray* exceptions) { + exceptions_.reset([exceptions retain]); + } + + // Checks that no views draw in front of |view|, with the exception of + // |exceptions|. + void CheckViewExposed(NSView* view) { + below_exposed_view_ = YES; + exposed_view_.reset([view retain]); + CheckViewsDoNotObscure([[[view window] contentView] superview]); + } + + private: + // Checks that |view| does not draw on top of |exposed_view_|. + void CheckViewDoesNotObscure(NSView* view) { + NSRect viewWindowFrame = [view convertRect:[view bounds] toView:nil]; + NSRect viewBeingVerifiedWindowFrame = + [exposed_view_ convertRect:[exposed_view_ bounds] toView:nil]; + + // The views do not intersect. + if (!NSIntersectsRect(viewBeingVerifiedWindowFrame, viewWindowFrame)) + return; + + // No view can be above the view being checked. + EXPECT_TRUE(below_exposed_view_); + + // If |view| is a parent of |exposed_view_|, then there's nothing else + // to check. + NSView* parent = exposed_view_; + while (parent != nil) { + parent = [parent superview]; + if (parent == view) + return; + } + + if ([exposed_view_ layer]) + return; + + // If the view being verified doesn't have a layer, then no views that + // intersect it can have a layer. + if ([exceptions_ containsObject:view]) { + EXPECT_FALSE([view isOpaque]); + return; + } + + EXPECT_TRUE(![view layer]) << [[view description] UTF8String] << " " << + [NSStringFromRect(viewWindowFrame) UTF8String]; + } + + // Recursively checks that |view| and its subviews do not draw on top of + // |exposed_view_|. The recursion passes through all views in order of + // back-most in Z-order to front-most in Z-order. + void CheckViewsDoNotObscure(NSView* view) { + // If this is the view being checked, don't recurse into its subviews. All + // future views encountered in the recursion are in front of the view being + // checked. + if (view == exposed_view_) { + below_exposed_view_ = NO; + return; + } + + CheckViewDoesNotObscure(view); + + // Perform the recursion. + for (NSView* subview in [view subviews]) + CheckViewsDoNotObscure(subview); + } + + // The method CheckViewExposed() recurses through the views in the view + // hierarchy and checks that none of the views obscure |exposed_view_|. + base::scoped_nsobject<NSView> exposed_view_; + + // While this flag is true, the views being recursed through are below + // |exposed_view_| in Z-order. After the recursion passes |exposed_view_|, + // this flag is set to false. + BOOL below_exposed_view_; + + // Exceptions are allowed to overlap |exposed_view_|. Exceptions must still + // be Z-order behind |exposed_view_|. + base::scoped_nsobject<NSArray> exceptions_; + + DISALLOW_COPY_AND_ASSIGN(ViewExposedChecker); +}; + } // namespace @interface InfoBarContainerController(TestingAPI) @@ -223,22 +313,29 @@ class BrowserWindowControllerTest : public InProcessBrowserTest { 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]; - NSArray* subviews = [rootView subviews]; - - EXPECT_EQ([controller() tabStripBackgroundView], - [subviews objectAtIndex:0]); - EXPECT_EQ(contentView, [subviews objectAtIndex:1]); - - NSView* tabStripView = [controller() tabStripView]; - if ([subviews containsObject:tabStripView]) - EXPECT_EQ(tabStripView, [subviews objectAtIndex:2]); + // Nothing should draw on top of the window controls. + void VerifyWindowControlsZOrder() { + NSWindow* window = [controller() window]; + ViewExposedChecker checker; + + // The exceptions are the contentView, chromeContentView and tabStripView, + // which are layer backed but transparent. + NSArray* exceptions = @[ + [window contentView], + controller().chromeContentView, + controller().tabStripView + ]; + checker.SetExceptions(exceptions); + + checker.CheckViewExposed([window standardWindowButton:NSWindowCloseButton]); + checker.CheckViewExposed( + [window standardWindowButton:NSWindowMiniaturizeButton]); + checker.CheckViewExposed([window standardWindowButton:NSWindowZoomButton]); + + // There is no fullscreen button on OSX 10.6 or OSX 10.10+. + NSView* view = [window standardWindowButton:NSWindowFullScreenButton]; + if (view) + checker.CheckViewExposed(view); } private: @@ -500,15 +597,17 @@ IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) { // Verify z order immediately after creation. - VerifyTrafficLightZOrder(); + VerifyWindowControlsZOrder(); - // Toggle overlay, then verify z order. + // Verify z order in and out of overlay. [controller() showOverlay]; + VerifyWindowControlsZOrder(); [controller() removeOverlay]; - VerifyTrafficLightZOrder(); + VerifyWindowControlsZOrder(); - // Toggle immersive fullscreen, then verify z order. + // Toggle immersive fullscreen, then verify z order. In immersive fullscreen, + // there are no window controls. [controller() enterImmersiveFullscreen]; [controller() exitImmersiveFullscreen]; - VerifyTrafficLightZOrder(); + VerifyWindowControlsZOrder(); } |