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/base_bubble_controller.h" | 5 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
| 8 #import "base/mac/scoped_nsobject.h" | 8 #import "base/mac/scoped_nsobject.h" |
| 9 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" | 9 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" |
| 10 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 10 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 11 #import "chrome/browser/ui/cocoa/run_loop_testing.h" | 11 #import "chrome/browser/ui/cocoa/run_loop_testing.h" |
|
Robert Sesek
2014/06/06 14:00:34
Remove this #import.
| |
| 12 #import "ui/events/test/cocoa_test_event_utils.h" | 12 #import "ui/events/test/cocoa_test_event_utils.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 const CGFloat kBubbleWindowWidth = 100; | 15 const CGFloat kBubbleWindowWidth = 100; |
| 16 const CGFloat kBubbleWindowHeight = 50; | 16 const CGFloat kBubbleWindowHeight = 50; |
| 17 const CGFloat kAnchorPointX = 400; | 17 const CGFloat kAnchorPointX = 400; |
| 18 const CGFloat kAnchorPointY = 300; | 18 const CGFloat kAnchorPointY = 300; |
| 19 } // namespace | 19 } // namespace |
| 20 | 20 |
| 21 @interface ContextMenuController : NSObject<NSMenuDelegate> { | |
| 22 @private | |
| 23 NSMenu* menu_; | |
| 24 NSWindow* window_; | |
| 25 BOOL isMenuOpen_; | |
| 26 BOOL didOpen_; | |
| 27 } | |
| 28 | |
| 29 - (id)initWithMenu:(NSMenu*)menu andWindow:(NSWindow*)window; | |
| 30 | |
| 31 - (BOOL)isMenuOpen; | |
| 32 - (BOOL)didOpen; | |
| 33 - (BOOL)isWindowVisible; | |
| 34 | |
| 35 // NSMenuDelegate methods | |
| 36 - (void)menuWillOpen:(NSMenu*)menu; | |
| 37 - (void)menuDidClose:(NSMenu*)menu; | |
| 38 | |
| 39 @end | |
| 40 | |
| 41 @implementation ContextMenuController | |
| 42 | |
| 43 - (id)initWithMenu:(NSMenu*)menu andWindow:(NSWindow*)window { | |
| 44 if (self = [super init]) { | |
| 45 menu_ = menu; | |
| 46 window_ = window; | |
| 47 isMenuOpen_ = NO; | |
| 48 didOpen_ = NO; | |
| 49 [menu_ setDelegate:self]; | |
| 50 } | |
| 51 return self; | |
| 52 } | |
| 53 | |
| 54 - (BOOL)isMenuOpen { | |
| 55 return isMenuOpen_; | |
| 56 } | |
| 57 | |
| 58 - (BOOL)didOpen { | |
| 59 return didOpen_; | |
| 60 } | |
| 61 | |
| 62 - (BOOL)isWindowVisible { | |
| 63 if (window_) { | |
| 64 return [window_ isVisible]; | |
| 65 } | |
| 66 return NO; | |
| 67 } | |
| 68 | |
| 69 - (void)menuWillOpen:(NSMenu*)menu { | |
| 70 isMenuOpen_ = YES; | |
| 71 didOpen_ = NO; | |
| 72 | |
| 73 NSArray* modes = @[NSEventTrackingRunLoopMode, NSDefaultRunLoopMode]; | |
| 74 [menu_ performSelector:@selector(cancelTracking) | |
| 75 withObject:nil | |
| 76 afterDelay:0.1 | |
| 77 inModes:modes]; | |
| 78 } | |
| 79 | |
| 80 - (void)menuDidClose:(NSMenu*)menu { | |
| 81 isMenuOpen_ = NO; | |
| 82 didOpen_ = YES; | |
| 83 } | |
| 84 | |
| 85 @end | |
| 86 | |
| 21 class BaseBubbleControllerTest : public CocoaTest { | 87 class BaseBubbleControllerTest : public CocoaTest { |
| 22 public: | 88 public: |
| 23 virtual void SetUp() OVERRIDE { | 89 virtual void SetUp() OVERRIDE { |
| 24 bubbleWindow_.reset([[NSWindow alloc] | 90 bubbleWindow_.reset([[NSWindow alloc] |
| 25 initWithContentRect:NSMakeRect(0, 0, kBubbleWindowWidth, | 91 initWithContentRect:NSMakeRect(0, 0, kBubbleWindowWidth, |
| 26 kBubbleWindowHeight) | 92 kBubbleWindowHeight) |
| 27 styleMask:NSBorderlessWindowMask | 93 styleMask:NSBorderlessWindowMask |
| 28 backing:NSBackingStoreBuffered | 94 backing:NSBackingStoreBuffered |
| 29 defer:YES]); | 95 defer:YES]); |
| 30 | 96 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 else | 233 else |
| 168 [controller_ windowDidResignKey:notif]; | 234 [controller_ windowDidResignKey:notif]; |
| 169 | 235 |
| 170 | 236 |
| 171 EXPECT_FALSE([bubble_window isVisible]); | 237 EXPECT_FALSE([bubble_window isVisible]); |
| 172 EXPECT_TRUE([other_window isVisible]); | 238 EXPECT_TRUE([other_window isVisible]); |
| 173 } | 239 } |
| 174 | 240 |
| 175 // Test that clicking outside the window causes the bubble to close if | 241 // Test that clicking outside the window causes the bubble to close if |
| 176 // shouldCloseOnResignKey is YES. | 242 // shouldCloseOnResignKey is YES. |
| 177 TEST_F(BaseBubbleControllerTest, LionClickOutsideCloses) { | 243 TEST_F(BaseBubbleControllerTest, LionClickOutsideClosesWithoutContextMenu) { |
| 178 // The event tap is only installed on 10.7+. | 244 // The event tap is only installed on 10.7+. |
| 179 if (!base::mac::IsOSLionOrLater()) | 245 if (!base::mac::IsOSLionOrLater()) |
| 180 return; | 246 return; |
| 181 | 247 |
| 182 // Closing the bubble will autorelease the controller. | 248 // Closing the bubble will autorelease the controller. |
| 183 base::scoped_nsobject<BaseBubbleController> keep_alive([controller_ retain]); | 249 base::scoped_nsobject<BaseBubbleController> keep_alive([controller_ retain]); |
| 184 NSWindow* window = [controller_ window]; | 250 NSWindow* window = [controller_ window]; |
| 185 | 251 |
| 186 EXPECT_TRUE([controller_ shouldCloseOnResignKey]); // Verify default value. | 252 EXPECT_TRUE([controller_ shouldCloseOnResignKey]); // Verify default value. |
| 187 EXPECT_FALSE([window isVisible]); | 253 EXPECT_FALSE([window isVisible]); |
| 188 | 254 |
| 189 [controller_ showWindow:nil]; | 255 [controller_ showWindow:nil]; |
| 190 | 256 |
| 191 EXPECT_TRUE([window isVisible]); | 257 EXPECT_TRUE([window isVisible]); |
| 192 | 258 |
| 193 [controller_ setShouldCloseOnResignKey:NO]; | 259 [controller_ setShouldCloseOnResignKey:NO]; |
| 194 NSEvent* event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 260 NSEvent* event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 195 NSMakePoint(10, 10), test_window()); | 261 NSMakePoint(10, 10), test_window()); |
| 196 [NSApp sendEvent:event]; | 262 [NSApp sendEvent:event]; |
| 197 chrome::testing::NSRunLoopRunAllPending(); | |
| 198 | 263 |
| 199 EXPECT_TRUE([window isVisible]); | 264 EXPECT_TRUE([window isVisible]); |
| 200 | 265 |
| 266 event = cocoa_test_event_utils::RightMouseDownAtPointInWindow( | |
| 267 NSMakePoint(10, 10), test_window()); | |
| 268 [NSApp sendEvent:event]; | |
| 269 | |
| 270 EXPECT_TRUE([window isVisible]); | |
| 271 | |
| 201 [controller_ setShouldCloseOnResignKey:YES]; | 272 [controller_ setShouldCloseOnResignKey:YES]; |
| 202 event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 273 event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 203 NSMakePoint(10, 10), test_window()); | 274 NSMakePoint(10, 10), test_window()); |
| 204 [NSApp sendEvent:event]; | 275 [NSApp sendEvent:event]; |
| 205 chrome::testing::NSRunLoopRunAllPending(); | 276 |
| 277 EXPECT_FALSE([window isVisible]); | |
| 278 | |
| 279 [controller_ showWindow:nil]; // Show it again | |
| 280 EXPECT_TRUE([window isVisible]); | |
| 281 EXPECT_TRUE([controller_ shouldCloseOnResignKey]); // Verify. | |
| 282 | |
| 283 event = cocoa_test_event_utils::RightMouseDownAtPointInWindow( | |
| 284 NSMakePoint(10, 10), test_window()); | |
| 285 [NSApp sendEvent:event]; | |
| 206 | 286 |
| 207 EXPECT_FALSE([window isVisible]); | 287 EXPECT_FALSE([window isVisible]); |
| 208 } | 288 } |
| 289 | |
| 290 // Test that right-clicking the window with displaying a context menu causes | |
| 291 // the bubble to close. | |
| 292 TEST_F(BaseBubbleControllerTest, LionRightClickOutsideClosesWithContextMenu) { | |
| 293 // The event tap is only installed on 10.7+. | |
| 294 if (!base::mac::IsOSLionOrLater()) | |
| 295 return; | |
| 296 | |
| 297 // Closing the bubble will autorelease the controller. | |
| 298 base::scoped_nsobject<BaseBubbleController> keep_alive([controller_ retain]); | |
| 299 NSWindow* window = [controller_ window]; | |
| 300 | |
| 301 EXPECT_TRUE([controller_ shouldCloseOnResignKey]); // Verify default value. | |
| 302 EXPECT_FALSE([window isVisible]); | |
| 303 | |
| 304 [controller_ showWindow:nil]; | |
| 305 | |
| 306 EXPECT_TRUE([window isVisible]); | |
| 307 | |
| 308 base::scoped_nsobject<NSMenu> context_menu( | |
| 309 [[NSMenu alloc] initWithTitle:@""]); | |
| 310 [context_menu addItemWithTitle: @"ContextMenuTest" | |
| 311 action: nil | |
|
Robert Sesek
2014/06/06 14:00:34
nit: align the colons and remove space after
| |
| 312 keyEquivalent:@""]; | |
| 313 base::scoped_nsobject<ContextMenuController> menu_controller( | |
| 314 [[ContextMenuController alloc] initWithMenu:context_menu | |
| 315 andWindow:window]); | |
| 316 | |
| 317 // Set the menu as the contextual menu of contentView of test_window(). | |
| 318 [[test_window() contentView] setMenu:context_menu]; | |
| 319 | |
| 320 // RightMouseDown in test_window() would close the bubble window and then | |
| 321 // dispaly the contextual menu. | |
| 322 NSEvent* event = cocoa_test_event_utils::RightMouseDownAtPointInWindow( | |
| 323 NSMakePoint(10, 10), test_window()); | |
| 324 // Verify bubble's window is closed when contextual menu is open. | |
| 325 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), NSEventTrackingRunLoopMode, ^{ | |
| 326 EXPECT_TRUE([menu_controller isMenuOpen]); | |
| 327 EXPECT_FALSE([menu_controller isWindowVisible]); | |
| 328 }); | |
| 329 | |
| 330 EXPECT_FALSE([menu_controller isMenuOpen]); | |
| 331 EXPECT_FALSE([menu_controller didOpen]); | |
| 332 | |
| 333 [NSApp sendEvent:event]; | |
| 334 | |
| 335 // When we got here, menu has already run its RunLoop. | |
| 336 // See -[ContextualMenuController MenuWillOpen:]. | |
|
Robert Sesek
2014/06/06 14:00:34
nit: lowercase menuWillOpen:
| |
| 337 EXPECT_FALSE([window isVisible]); | |
| 338 | |
| 339 EXPECT_FALSE([menu_controller isMenuOpen]); | |
| 340 EXPECT_TRUE([menu_controller didOpen]); | |
| 341 } | |
| 342 | |
| OLD | NEW |