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 |