Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: ui/views/focus/focus_manager_unittest_win.cc

Issue 8642002: Enable FocusManager tests for Aura. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/focus/focus_manager.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "ui/views/focus/accelerator_handler.h"
9 #include "ui/views/focus/focus_manager_test.h"
10 #include "ui/views/widget/widget.h"
11 #include "views/controls/button/text_button.h"
12
13 namespace views {
14
15 namespace {
16
17 class MessageTrackingView : public View {
18 public:
19 MessageTrackingView() : accelerator_pressed_(false) {
20 }
21
22 void Reset() {
23 accelerator_pressed_ = false;
24 keys_pressed_.clear();
25 keys_released_.clear();
26 }
27
28 const std::vector<ui::KeyboardCode>& keys_pressed() const {
29 return keys_pressed_;
30 }
31
32 const std::vector<ui::KeyboardCode>& keys_released() const {
33 return keys_released_;
34 }
35
36 bool accelerator_pressed() const {
37 return accelerator_pressed_;
38 }
39
40 // Overridden from View:
41 virtual bool OnKeyPressed(const KeyEvent& e) OVERRIDE {
42 keys_pressed_.push_back(e.key_code());
43 return true;
44 }
45 virtual bool OnKeyReleased(const KeyEvent& e) OVERRIDE {
46 keys_released_.push_back(e.key_code());
47 return true;
48 }
49 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
50 accelerator_pressed_ = true;
51 return true;
52 }
53
54 private:
55 bool accelerator_pressed_;
56 std::vector<ui::KeyboardCode> keys_pressed_;
57 std::vector<ui::KeyboardCode> keys_released_;
58
59 DISALLOW_COPY_AND_ASSIGN(MessageTrackingView);
60 };
61
62 } // namespace
63
64 // Test that when activating/deactivating the top window, the focus is stored/
65 // restored properly.
66 TEST_F(FocusManagerTest, FocusStoreRestore) {
67 // Simulate an activate, otherwise the deactivate isn't going to do anything.
68 SimulateActivateWindow();
69
70 NativeTextButton* button = new NativeTextButton(NULL,
71 ASCIIToUTF16("Press me"));
72 View* view = new View();
73 view->set_focusable(true);
74
75 GetContentsView()->AddChildView(button);
76 button->SetBounds(10, 10, 200, 30);
77 GetContentsView()->AddChildView(view);
78 RunPendingMessages();
79
80 TestFocusChangeListener listener;
81 AddFocusChangeListener(&listener);
82
83 view->RequestFocus();
84 RunPendingMessages();
85 // MessageLoopForUI::current()->RunWithDispatcher(new AcceleratorHandler());
86
87 // Visual Studio 2010 has problems converting NULL to the null pointer for
88 // std::pair. See http://connect.microsoft.com/VisualStudio/feedback/details/ 520043/error-converting-from-null-to-a-pointer-type-in-std-pair
89 // It will work if we pass nullptr.
90 #if defined(_MSC_VER) && _MSC_VER >= 1600
91 views::View* null_view = nullptr;
92 #else
93 views::View* null_view = NULL;
94 #endif
95
96 // Deacivate the window, it should store its focus.
97 SimulateDeactivateWindow();
98 EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
99 ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
100 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
101 EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(view, null_view));
102 listener.ClearFocusChanges();
103
104 // Reactivate, focus should come-back to the previously focused view.
105 SimulateActivateWindow();
106 EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
107 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
108 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
109 listener.ClearFocusChanges();
110
111 // Same test with a NativeControl.
112 button->RequestFocus();
113 SimulateDeactivateWindow();
114 EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
115 ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
116 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view, button));
117 EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(button, null_view));
118 listener.ClearFocusChanges();
119
120 SimulateActivateWindow();
121 EXPECT_EQ(button, GetFocusManager()->GetFocusedView());
122 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
123 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, button));
124 listener.ClearFocusChanges();
125
126 /*
127 // Now test that while the window is inactive we can change the focused view
128 // (we do that in several places).
129 SimulateDeactivateWindow();
130 // TODO: would have to mock the window being inactive (with a TestWidgetWin
131 // that would return false on IsActive()).
132 GetFocusManager()->SetFocusedView(view);
133 ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
134
135 EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
136 ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
137 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(button, null_view));
138 EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(null_view, view));
139 */
140 }
141
142 // Test that the focus manager is created successfully for the first view
143 // window parented to a native dialog.
144 TEST_F(FocusManagerTest, CreationForNativeRoot) {
145 // Create a window class.
146 WNDCLASSEX class_ex;
147 memset(&class_ex, 0, sizeof(class_ex));
148 class_ex.cbSize = sizeof(WNDCLASSEX);
149 class_ex.lpfnWndProc = &DefWindowProc;
150 class_ex.lpszClassName = L"TestWindow";
151 ATOM atom = RegisterClassEx(&class_ex);
152 ASSERT_TRUE(atom);
153
154 // Create a native dialog window.
155 HWND hwnd = CreateWindowEx(0, class_ex.lpszClassName, NULL,
156 WS_OVERLAPPEDWINDOW, 0, 0, 200, 200,
157 NULL, NULL, NULL, NULL);
158 ASSERT_TRUE(hwnd);
159
160 // Create a view window parented to native dialog.
161 scoped_ptr<Widget> widget1(new Widget);
162 Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
163 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
164 params.parent = hwnd;
165 params.bounds = gfx::Rect(0, 0, 100, 100);
166 params.top_level = true; // This is top level in views hierarchy.
167 widget1->Init(params);
168
169 // Get the focus manager directly from the first window. Should exist
170 // because the first window is the root widget.
171 views::FocusManager* focus_manager1 = widget1->GetFocusManager();
172 EXPECT_TRUE(focus_manager1);
173
174 // Create another view window parented to the first view window.
175 scoped_ptr<Widget> widget2(new Widget);
176 params.parent = widget1->GetNativeView();
177 params.top_level = false; // This is child widget.
178 widget2->Init(params);
179
180 // Access the shared focus manager directly from the second window.
181 views::FocusManager* focus_manager2 = widget2->GetFocusManager();
182 EXPECT_EQ(focus_manager2, focus_manager1);
183
184 // Access the shared focus manager indirectly from the first window handle.
185 gfx::NativeWindow native_window = widget1->GetNativeWindow();
186 views::Widget* widget =
187 views::Widget::GetWidgetForNativeWindow(native_window);
188 EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
189
190 // Access the shared focus manager indirectly from the second window handle.
191 native_window = widget2->GetNativeWindow();
192 widget = views::Widget::GetWidgetForNativeWindow(native_window);
193 EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
194
195 // Access the shared focus manager indirectly from the first view handle.
196 gfx::NativeView native_view = widget1->GetNativeView();
197 widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
198 EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
199
200 // Access the shared focus manager indirectly from the second view handle.
201 native_view = widget2->GetNativeView();
202 widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
203 EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
204
205 DestroyWindow(hwnd);
206 }
207
208 // Tests that the keyup messages are eaten for accelerators.
209 // Windows-only, Windows is the only platform that handles accelerators in
210 // AcceleratorHandler. NativeWidgetAura/NativeWidgetGtk::OnKeyEvent handles
211 // them in other configurations.
212 TEST_F(FocusManagerTest, IgnoreKeyupForAccelerators) {
213 FocusManager* focus_manager = GetFocusManager();
214 MessageTrackingView* mtv = new MessageTrackingView();
215 mtv->AddAccelerator(ui::Accelerator(ui::VKEY_0, false, false, false));
216 mtv->AddAccelerator(ui::Accelerator(ui::VKEY_1, false, false, false));
217 GetContentsView()->AddChildView(mtv);
218 focus_manager->SetFocusedView(mtv);
219
220 // First send a non-accelerator key sequence.
221 PostKeyDown(ui::VKEY_9);
222 PostKeyUp(ui::VKEY_9);
223 AcceleratorHandler accelerator_handler;
224 MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
225 MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
226 // Make sure we get a key-up and key-down.
227 ASSERT_EQ(1U, mtv->keys_pressed().size());
228 EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
229 ASSERT_EQ(1U, mtv->keys_released().size());
230 EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
231 EXPECT_FALSE(mtv->accelerator_pressed());
232 mtv->Reset();
233
234 // Same thing with repeat and more than one key at once.
235 PostKeyDown(ui::VKEY_9);
236 PostKeyDown(ui::VKEY_9);
237 PostKeyDown(ui::VKEY_8);
238 PostKeyDown(ui::VKEY_9);
239 PostKeyDown(ui::VKEY_7);
240 PostKeyUp(ui::VKEY_9);
241 PostKeyUp(ui::VKEY_7);
242 PostKeyUp(ui::VKEY_8);
243 MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
244 MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
245 // Make sure we get a key-up and key-down.
246 ASSERT_EQ(5U, mtv->keys_pressed().size());
247 EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
248 EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[1]);
249 EXPECT_EQ(ui::VKEY_8, mtv->keys_pressed()[2]);
250 EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[3]);
251 EXPECT_EQ(ui::VKEY_7, mtv->keys_pressed()[4]);
252 ASSERT_EQ(3U, mtv->keys_released().size());
253 EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
254 EXPECT_EQ(ui::VKEY_7, mtv->keys_released()[1]);
255 EXPECT_EQ(ui::VKEY_8, mtv->keys_released()[2]);
256 EXPECT_FALSE(mtv->accelerator_pressed());
257 mtv->Reset();
258
259 // Now send an accelerator key sequence.
260 PostKeyDown(ui::VKEY_0);
261 PostKeyUp(ui::VKEY_0);
262 MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
263 MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
264 EXPECT_TRUE(mtv->keys_pressed().empty());
265 EXPECT_TRUE(mtv->keys_released().empty());
266 EXPECT_TRUE(mtv->accelerator_pressed());
267 mtv->Reset();
268
269 // Same thing with repeat and more than one key at once.
270 PostKeyDown(ui::VKEY_0);
271 PostKeyDown(ui::VKEY_1);
272 PostKeyDown(ui::VKEY_1);
273 PostKeyDown(ui::VKEY_0);
274 PostKeyDown(ui::VKEY_0);
275 PostKeyUp(ui::VKEY_1);
276 PostKeyUp(ui::VKEY_0);
277 MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
278 MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
279 EXPECT_TRUE(mtv->keys_pressed().empty());
280 EXPECT_TRUE(mtv->keys_released().empty());
281 EXPECT_TRUE(mtv->accelerator_pressed());
282 mtv->Reset();
283 }
284
285 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698