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.h" | 5 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 6 | 6 |
| 7 #import "base/mac/mac_util.h" | 7 #import "base/mac/mac_util.h" |
| 8 #include "base/mac/sdk_forward_declarations.h" | 8 #include "base/mac/sdk_forward_declarations.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 NSPoint icon_bottom = location_bar_view->GetPageInfoBubblePoint(); | 216 NSPoint icon_bottom = location_bar_view->GetPageInfoBubblePoint(); |
| 217 | 217 |
| 218 NSPoint info_bar_top = NSMakePoint(0, | 218 NSPoint info_bar_top = NSMakePoint(0, |
| 219 NSHeight([info_bar_container_controller view].frame) - | 219 NSHeight([info_bar_container_controller view].frame) - |
| 220 overlapping_tip_height); | 220 overlapping_tip_height); |
| 221 info_bar_top = [[info_bar_container_controller view] | 221 info_bar_top = [[info_bar_container_controller view] |
| 222 convertPoint:info_bar_top toView:nil]; | 222 convertPoint:info_bar_top toView:nil]; |
| 223 return icon_bottom.y - info_bar_top.y; | 223 return icon_bottom.y - info_bar_top.y; |
| 224 } | 224 } |
| 225 | 225 |
| 226 // The traffic lights should always be in front of the content view and the | 226 // Checks that |view| does not draw on top of |exposedView_|. |
| 227 // tab strip view. Since the traffic lights change across OSX versions, this | 227 void CheckViewDoesNotObscure(NSView* view) { |
| 228 // test verifies that the contentView is in the back, and if the tab strip | 228 NSRect viewWindowFrame = [view convertRect:[view bounds] toView:nil]; |
| 229 // view is a sibling, it is directly in front of the content view. | 229 NSRect viewBeingVerifiedWindowFrame = |
| 230 void VerifyTrafficLightZOrder() const { | 230 [exposedView_ convertRect:[exposedView_ bounds] toView:nil]; |
| 231 NSView* contentView = [[controller() window] contentView]; | |
| 232 NSView* rootView = [contentView superview]; | |
| 233 NSArray* subviews = [rootView subviews]; | |
| 234 | 231 |
| 235 EXPECT_EQ([controller() tabStripBackgroundView], | 232 // The views do not intersect. |
| 236 [subviews objectAtIndex:0]); | 233 if (!NSIntersectsRect(viewBeingVerifiedWindowFrame, viewWindowFrame)) |
| 237 EXPECT_EQ(contentView, [subviews objectAtIndex:1]); | 234 return; |
| 238 | 235 |
| 239 NSView* tabStripView = [controller() tabStripView]; | 236 // No view can be above the view being checked. |
| 240 if ([subviews containsObject:tabStripView]) | 237 EXPECT_TRUE(belowExposedView_); |
| 241 EXPECT_EQ(tabStripView, [subviews objectAtIndex:2]); | 238 |
| 239 // If |view| is a parent of |exposedView_|, then there's nothing else | |
| 240 // to check. | |
| 241 NSView* parent = exposedView_; | |
| 242 while (parent != nil) { | |
| 243 parent = [parent superview]; | |
| 244 if (parent == view) | |
| 245 return; | |
| 246 } | |
| 247 | |
| 248 if ([exposedView_ layer]) | |
| 249 return; | |
| 250 | |
| 251 // If the view being verified doesn't have a layer, then no views that | |
| 252 // intersect it can have a layer. The exceptions are the contentView, | |
| 253 // chromeContentView and tabStripView, which are layer backed but | |
| 254 // transparent. | |
| 255 NSArray* exceptions = @[ | |
| 256 [[view window] contentView], | |
| 257 controller().chromeContentView, | |
| 258 controller().tabStripView | |
| 259 ]; | |
| 260 if ([exceptions containsObject:view]) { | |
| 261 EXPECT_FALSE([view isOpaque]); | |
| 262 return; | |
| 263 } | |
| 264 | |
| 265 EXPECT_TRUE(![view layer]) << [[view description] UTF8String] << " " << | |
| 266 [NSStringFromRect(viewWindowFrame) UTF8String]; | |
| 267 } | |
| 268 | |
| 269 // Recursively checks that |view| and its subviews do not draw on top of | |
| 270 // |exposedView_|. The recursion passes through all views in order of | |
| 271 // back-most in Z-order to front-most in Z-order. | |
| 272 void CheckViewsDoNotObscure(NSView* view) { | |
| 273 // If this is the view being checked, don't recurse into its subviews. All | |
| 274 // future views encountered in the recursion are in front of the view being | |
| 275 // checked. | |
| 276 if (view == exposedView_) { | |
| 277 belowExposedView_ = NO; | |
| 278 return; | |
| 279 } | |
| 280 | |
| 281 CheckViewDoesNotObscure(view); | |
| 282 | |
| 283 // Perform the recursion. | |
| 284 for (NSView* subview in [view subviews]) | |
| 285 CheckViewsDoNotObscure(subview); | |
| 286 } | |
| 287 | |
| 288 // Checks that no views draw in front of |view|. | |
| 289 void CheckViewOnTop(NSView* view) { | |
| 290 belowExposedView_ = YES; | |
| 291 exposedView_ = view; | |
| 292 CheckViewsDoNotObscure([[[view window] contentView] superview]); | |
|
Andre
2014/10/10 04:37:13
I still think it is not ideal to use instance vari
erikchen
2014/10/10 17:38:08
I moved all of the logic into a new class.
| |
| 293 } | |
| 294 | |
| 295 // Nothing should draw on top of the window controls. | |
| 296 void VerifyWindowControlsZOrder() { | |
| 297 NSWindow* window = [controller() window]; | |
| 298 CheckViewOnTop([window standardWindowButton:NSWindowCloseButton]); | |
| 299 CheckViewOnTop([window standardWindowButton:NSWindowMiniaturizeButton]); | |
| 300 CheckViewOnTop([window standardWindowButton:NSWindowZoomButton]); | |
| 301 | |
| 302 // There is no fullscreen button on OSX 10.6 or OSX 10.10+. | |
| 303 NSView* view = [window standardWindowButton:NSWindowFullScreenButton]; | |
| 304 if (view) | |
| 305 CheckViewOnTop(view); | |
| 242 } | 306 } |
| 243 | 307 |
| 244 private: | 308 private: |
| 309 // The method CheckViewOnTop() recurses through the views in the view | |
| 310 // hierarchy and checks that none of the views obscure |exposedView_|. | |
| 311 NSView* exposedView_; | |
| 312 // While this flag is true, the views being recursed through are below | |
| 313 // |exposedView_| in Z-order. After the recursion passes |exposedView_|, this | |
| 314 // flag is set to false. | |
| 315 BOOL belowExposedView_; | |
| 316 | |
| 245 DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest); | 317 DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest); |
| 246 }; | 318 }; |
| 247 | 319 |
| 248 // Tests that adding the first profile moves the Lion fullscreen button over | 320 // Tests that adding the first profile moves the Lion fullscreen button over |
| 249 // correctly. | 321 // correctly. |
| 250 // DISABLED_ because it regularly times out: http://crbug.com/159002. | 322 // DISABLED_ because it regularly times out: http://crbug.com/159002. |
| 251 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, | 323 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, |
| 252 DISABLED_ProfileAvatarFullscreenButton) { | 324 DISABLED_ProfileAvatarFullscreenButton) { |
| 253 if (base::mac::IsOSSnowLeopard()) | 325 if (base::mac::IsOSSnowLeopard()) |
| 254 return; | 326 return; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 | 565 |
| 494 chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); | 566 chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); |
| 495 WaitForBookmarkBarAnimationToFinish(); | 567 WaitForBookmarkBarAnimationToFinish(); |
| 496 EXPECT_FALSE([controller() isBookmarkBarVisible]); | 568 EXPECT_FALSE([controller() isBookmarkBarVisible]); |
| 497 EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height), | 569 EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height), |
| 498 [[controller() infoBarContainerController] overlappingTipHeight]); | 570 [[controller() infoBarContainerController] overlappingTipHeight]); |
| 499 } | 571 } |
| 500 | 572 |
| 501 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) { | 573 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) { |
| 502 // Verify z order immediately after creation. | 574 // Verify z order immediately after creation. |
| 503 VerifyTrafficLightZOrder(); | 575 VerifyWindowControlsZOrder(); |
| 504 | 576 |
| 505 // Toggle overlay, then verify z order. | 577 // Verify z order in and out of overlay. |
| 506 [controller() showOverlay]; | 578 [controller() showOverlay]; |
| 579 VerifyWindowControlsZOrder(); | |
| 507 [controller() removeOverlay]; | 580 [controller() removeOverlay]; |
| 508 VerifyTrafficLightZOrder(); | 581 VerifyWindowControlsZOrder(); |
| 509 | 582 |
| 510 // Toggle immersive fullscreen, then verify z order. | 583 // Toggle immersive fullscreen, then verify z order. In immersive fullscreen, |
| 584 // there are no window controls. | |
| 511 [controller() enterImmersiveFullscreen]; | 585 [controller() enterImmersiveFullscreen]; |
| 512 [controller() exitImmersiveFullscreen]; | 586 [controller() exitImmersiveFullscreen]; |
| 513 VerifyTrafficLightZOrder(); | 587 VerifyWindowControlsZOrder(); |
| 514 } | 588 } |
| OLD | NEW |