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 |viewBeingVerified_|. |
| 227 // tab strip view. Since the traffic lights change across OSX versions, this | 227 void CheckView(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 [viewBeingVerified_ convertRect:[viewBeingVerified_ 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 verified. |
| 240 if ([subviews containsObject:tabStripView]) | 237 EXPECT_TRUE(belowViewBeingVerified_); |
| 241 EXPECT_EQ(tabStripView, [subviews objectAtIndex:2]); | 238 |
| 239 // If |view| is a parent of |viewBeingVerified_|, then there's nothing else | |
| 240 // to check. | |
| 241 NSView* parent = viewBeingVerified_; | |
| 242 while (parent != nil) { | |
| 243 parent = [parent superview]; | |
| 244 if (parent == view) | |
| 245 return; | |
| 246 } | |
| 247 | |
| 248 if ([viewBeingVerified_ 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 std::vector<NSView*> exceptions; | |
|
Andre
2014/10/09 23:15:48
How about something like this,
NSArray* exceptions
erikchen
2014/10/10 00:47:45
I used your suggestion of an array literal, althou
| |
| 256 exceptions.push_back([[view window] contentView]); | |
| 257 exceptions.push_back(controller().chromeContentView); | |
| 258 exceptions.push_back(controller().tabStripView); | |
| 259 for (NSView* exception : exceptions) { | |
| 260 if (view != exception) | |
| 261 continue; | |
| 262 | |
| 263 EXPECT_FALSE([exception isOpaque]); | |
| 264 return; | |
| 265 } | |
| 266 | |
| 267 EXPECT_TRUE(![view layer]) << [[view description] UTF8String] << " " << | |
| 268 [NSStringFromRect(viewWindowFrame) UTF8String]; | |
| 269 } | |
| 270 | |
| 271 // Recursively checks that |view| and its subviews do not draw on top of | |
| 272 // |viewBeingVerified_|. | |
| 273 void CheckViewAndSubviews(NSView* view) { | |
| 274 // If this is the view being verified, then there's nothing to check. Don't | |
| 275 // recurse into its subviews. All future views encountered in the recursion | |
| 276 // are above the view being verified. | |
| 277 if (view == viewBeingVerified_) { | |
| 278 belowViewBeingVerified_ = NO; | |
| 279 return; | |
| 280 } | |
| 281 | |
| 282 CheckView(view); | |
| 283 | |
| 284 // Perform the recursion. | |
| 285 for (NSView* subview in [view subviews]) | |
| 286 CheckViewAndSubviews(subview); | |
| 287 } | |
| 288 | |
| 289 void CheckViewOnTop(NSView* view) { | |
| 290 belowViewBeingVerified_ = YES; | |
| 291 viewBeingVerified_ = view; | |
| 292 CheckViewAndSubviews([[[view window] contentView] superview]); | |
| 293 } | |
| 294 | |
| 295 // Nothing should draw on top of the window controls. | |
| 296 void VerifyWindowControlsZOrder() { | |
| 297 CheckViewOnTop( | |
| 298 [[controller() window] standardWindowButton:NSWindowCloseButton]); | |
| 299 CheckViewOnTop( | |
| 300 [[controller() window] standardWindowButton:NSWindowMiniaturizeButton]); | |
| 301 | |
| 302 // There is no zoom button on OSX 10.10+. | |
|
Andre
2014/10/09 23:15:48
I may have misremembered this, but I thought in 10
erikchen
2014/10/10 00:47:45
You're right. I was mistaken. Although the new nom
| |
| 303 NSView* view = | |
| 304 [[controller() window] standardWindowButton:NSWindowZoomButton]; | |
| 305 if (view) | |
| 306 CheckViewOnTop(view); | |
| 307 | |
| 308 // There is no fullscreen button on OSX 10.6. | |
| 309 view = | |
| 310 [[controller() window] standardWindowButton:NSWindowFullScreenButton]; | |
| 311 if (view) | |
| 312 CheckViewOnTop(view); | |
| 242 } | 313 } |
| 243 | 314 |
| 244 private: | 315 private: |
| 316 NSView* viewBeingVerified_; | |
| 317 BOOL belowViewBeingVerified_; | |
|
Andre
2014/10/09 23:15:48
Can we pass these as parameters and return values
erikchen
2014/10/10 00:47:45
I think that passing the parameters would reduce t
| |
| 318 | |
| 245 DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest); | 319 DISALLOW_COPY_AND_ASSIGN(BrowserWindowControllerTest); |
| 246 }; | 320 }; |
| 247 | 321 |
| 248 // Tests that adding the first profile moves the Lion fullscreen button over | 322 // Tests that adding the first profile moves the Lion fullscreen button over |
| 249 // correctly. | 323 // correctly. |
| 250 // DISABLED_ because it regularly times out: http://crbug.com/159002. | 324 // DISABLED_ because it regularly times out: http://crbug.com/159002. |
| 251 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, | 325 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, |
| 252 DISABLED_ProfileAvatarFullscreenButton) { | 326 DISABLED_ProfileAvatarFullscreenButton) { |
| 253 if (base::mac::IsOSSnowLeopard()) | 327 if (base::mac::IsOSSnowLeopard()) |
| 254 return; | 328 return; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 | 567 |
| 494 chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); | 568 chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); |
| 495 WaitForBookmarkBarAnimationToFinish(); | 569 WaitForBookmarkBarAnimationToFinish(); |
| 496 EXPECT_FALSE([controller() isBookmarkBarVisible]); | 570 EXPECT_FALSE([controller() isBookmarkBarVisible]); |
| 497 EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height), | 571 EXPECT_EQ(std::min(GetExpectedTopInfoBarTipHeight(), max_tip_height), |
| 498 [[controller() infoBarContainerController] overlappingTipHeight]); | 572 [[controller() infoBarContainerController] overlappingTipHeight]); |
| 499 } | 573 } |
| 500 | 574 |
| 501 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) { | 575 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest, TrafficLightZOrder) { |
| 502 // Verify z order immediately after creation. | 576 // Verify z order immediately after creation. |
| 503 VerifyTrafficLightZOrder(); | 577 VerifyWindowControlsZOrder(); |
| 504 | 578 |
| 505 // Toggle overlay, then verify z order. | 579 // Verify z order in and out of overlay. |
| 506 [controller() showOverlay]; | 580 [controller() showOverlay]; |
| 581 VerifyWindowControlsZOrder(); | |
| 507 [controller() removeOverlay]; | 582 [controller() removeOverlay]; |
| 508 VerifyTrafficLightZOrder(); | 583 VerifyWindowControlsZOrder(); |
| 509 | 584 |
| 510 // Toggle immersive fullscreen, then verify z order. | 585 // Toggle immersive fullscreen, then verify z order. In immersive fullscreen, |
| 586 // there are no window controls. | |
| 511 [controller() enterImmersiveFullscreen]; | 587 [controller() enterImmersiveFullscreen]; |
| 512 [controller() exitImmersiveFullscreen]; | 588 [controller() exitImmersiveFullscreen]; |
| 513 VerifyTrafficLightZOrder(); | 589 VerifyWindowControlsZOrder(); |
| 514 } | 590 } |
| OLD | NEW |