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 |