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 <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
| 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/run_loop.h" |
| 9 #include "base/test/test_timeouts.h" |
7 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
8 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
9 #include "chrome/browser/ui/browser_commands.h" | 12 #include "chrome/browser/ui/browser_commands.h" |
10 #include "chrome/browser/ui/browser_finder.h" | 13 #include "chrome/browser/ui/browser_finder.h" |
| 14 #include "chrome/browser/ui/browser_window.h" |
11 #include "chrome/browser/ui/panels/base_panel_browser_test.h" | 15 #include "chrome/browser/ui/panels/base_panel_browser_test.h" |
12 #include "chrome/browser/ui/panels/panel.h" | 16 #include "chrome/browser/ui/panels/panel.h" |
13 #include "content/public/test/test_utils.h" | 17 #include "content/public/test/test_utils.h" |
14 | 18 |
| 19 // Class that spins a run loop until an NSWindow gains key status. |
| 20 @interface CocoaActivationWaiter : NSObject { |
| 21 @private |
| 22 base::RunLoop* runLoop_; |
| 23 BOOL observed_; |
| 24 } |
| 25 |
| 26 - (id)initWithWindow:(NSWindow*)window; |
| 27 - (void)windowDidBecomeKey:(NSNotification*)notification; |
| 28 - (BOOL)waitUntilActive; |
| 29 |
| 30 @end |
| 31 |
| 32 @implementation CocoaActivationWaiter |
| 33 |
| 34 - (id)initWithWindow:(NSWindow*)window { |
| 35 EXPECT_FALSE([window isKeyWindow]); |
| 36 if ((self = [super init])) { |
| 37 [[NSNotificationCenter defaultCenter] |
| 38 addObserver:self |
| 39 selector:@selector(windowDidBecomeKey:) |
| 40 name:NSWindowDidBecomeKeyNotification |
| 41 object:window]; |
| 42 } |
| 43 return self; |
| 44 } |
| 45 |
| 46 - (void)dealloc { |
| 47 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 48 [super dealloc]; |
| 49 } |
| 50 |
| 51 - (void)windowDidBecomeKey:(NSNotification*)notification { |
| 52 observed_ = YES; |
| 53 if (runLoop_) |
| 54 runLoop_->Quit(); |
| 55 } |
| 56 |
| 57 - (BOOL)waitUntilActive { |
| 58 if (observed_) |
| 59 return YES; |
| 60 |
| 61 base::RunLoop runLoop; |
| 62 base::MessageLoop::current()->task_runner()->PostDelayedTask( |
| 63 FROM_HERE, runLoop.QuitClosure(), TestTimeouts::action_timeout()); |
| 64 runLoop_ = &runLoop; |
| 65 runLoop.Run(); |
| 66 runLoop_ = nullptr; |
| 67 return observed_; |
| 68 } |
| 69 |
| 70 @end |
| 71 |
15 typedef BasePanelBrowserTest PanelCocoaBrowserTest; | 72 typedef BasePanelBrowserTest PanelCocoaBrowserTest; |
16 | 73 |
17 IN_PROC_BROWSER_TEST_F(PanelCocoaBrowserTest, MenuItems) { | 74 IN_PROC_BROWSER_TEST_F(PanelCocoaBrowserTest, MenuItems) { |
18 Panel* panel = CreatePanel("Panel"); | 75 Panel* panel = CreatePanel("Panel"); |
19 | 76 |
20 // Close main tabbed window. | 77 // Close main tabbed window. |
21 content::WindowedNotificationObserver signal( | 78 content::WindowedNotificationObserver signal( |
22 chrome::NOTIFICATION_BROWSER_CLOSED, | 79 chrome::NOTIFICATION_BROWSER_CLOSED, |
23 content::Source<Browser>(browser())); | 80 content::Source<Browser>(browser())); |
24 chrome::CloseWindow(browser()); | 81 chrome::CloseWindow(browser()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 if ([i action] == @selector(performClose:)) { | 133 if ([i action] == @selector(performClose:)) { |
77 item = i; | 134 item = i; |
78 break; | 135 break; |
79 } | 136 } |
80 } | 137 } |
81 EXPECT_TRUE(item); | 138 EXPECT_TRUE(item); |
82 EXPECT_TRUE([item isEnabled]); | 139 EXPECT_TRUE([item isEnabled]); |
83 | 140 |
84 panel->Close(); | 141 panel->Close(); |
85 } | 142 } |
| 143 |
| 144 // Test that panels do not become active when closing a window, even when a |
| 145 // panel is otherwise the topmost window. |
| 146 IN_PROC_BROWSER_TEST_F(PanelCocoaBrowserTest, InactivePanelsNotActivated) { |
| 147 // Note CreateDockedPanel() sets wait_for_fully_created and SHOW_AS_ACTIVE, |
| 148 // so the following spins a run loop until the respective panel is activated. |
| 149 Panel* docked_panel_1 = CreateDockedPanel("Panel1", gfx::Rect()); |
| 150 EXPECT_TRUE([docked_panel_1->GetNativeWindow() isKeyWindow]); |
| 151 |
| 152 // Activate the browser. Otherwise closing the second panel will correctly |
| 153 // raise the first panel since panels are allowed to become key if they were |
| 154 // actually the most recently focused window (as opposed to being merely the |
| 155 // topmost window on the z-order stack). |
| 156 NSWindow* browser_window = browser()->window()->GetNativeWindow(); |
| 157 base::scoped_nsobject<CocoaActivationWaiter> waiter( |
| 158 [[CocoaActivationWaiter alloc] initWithWindow:browser_window]); |
| 159 browser()->window()->Activate(); |
| 160 EXPECT_TRUE([waiter waitUntilActive]); |
| 161 |
| 162 // Creating a second panel will activate it (and make it topmost). |
| 163 Panel* docked_panel_2 = CreateDockedPanel("Panel2", gfx::Rect()); |
| 164 EXPECT_TRUE([docked_panel_2->GetNativeWindow() isKeyWindow]); |
| 165 |
| 166 // Verify the assumptions that the panels are actually topmost. |
| 167 EXPECT_EQ(docked_panel_2->GetNativeWindow(), |
| 168 [[NSApp orderedWindows] objectAtIndex:0]); |
| 169 EXPECT_EQ(docked_panel_1->GetNativeWindow(), |
| 170 [[NSApp orderedWindows] objectAtIndex:1]); |
| 171 |
| 172 // Close the second panel and wait for the browser to become active. |
| 173 waiter.reset([[CocoaActivationWaiter alloc] initWithWindow:browser_window]); |
| 174 docked_panel_2->Close(); |
| 175 |
| 176 EXPECT_TRUE([waiter waitUntilActive]); |
| 177 EXPECT_TRUE([browser_window isKeyWindow]); |
| 178 } |
OLD | NEW |