Correct blacklist entry message
[chromium-blink-merge.git] / ui / views / focus / focus_manager_unittest.cc
bloba2c9d48f6fa38c02467ee7a1fb0fba8cc4e26f32
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
3 // found in the LICENSE file.
5 #include <utility>
6 #include <vector>
8 #include "base/strings/utf_string_conversions.h"
9 #include "ui/base/accelerators/accelerator.h"
10 #include "ui/events/keycodes/keyboard_codes.h"
11 #include "ui/views/accessible_pane_view.h"
12 #include "ui/views/controls/button/label_button.h"
13 #include "ui/views/controls/textfield/textfield.h"
14 #include "ui/views/focus/accelerator_handler.h"
15 #include "ui/views/focus/focus_manager_factory.h"
16 #include "ui/views/focus/focus_manager_test.h"
17 #include "ui/views/focus/widget_focus_manager.h"
18 #include "ui/views/widget/widget.h"
20 #if defined(USE_AURA)
21 #include "ui/aura/client/focus_client.h"
22 #include "ui/aura/window.h"
23 #endif
25 namespace views {
27 void FocusNativeView(gfx::NativeView view) {
28 #if defined(USE_AURA)
29 aura::client::GetFocusClient(view)->FocusWindow(view);
30 #elif defined(OS_WIN)
31 SetFocus(view);
32 #else
33 #error
34 #endif
37 enum FocusTestEventType {
38 ON_FOCUS = 0,
39 ON_BLUR
42 struct FocusTestEvent {
43 FocusTestEvent(FocusTestEventType type, int view_id)
44 : type(type),
45 view_id(view_id) {
48 FocusTestEventType type;
49 int view_id;
52 class SimpleTestView : public View {
53 public:
54 SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id)
55 : event_list_(event_list) {
56 set_focusable(true);
57 set_id(view_id);
60 virtual void OnFocus() OVERRIDE {
61 event_list_->push_back(FocusTestEvent(ON_FOCUS, id()));
64 virtual void OnBlur() OVERRIDE {
65 event_list_->push_back(FocusTestEvent(ON_BLUR, id()));
68 private:
69 std::vector<FocusTestEvent>* event_list_;
72 // Tests that the appropriate Focus related methods are called when a View
73 // gets/loses focus.
74 TEST_F(FocusManagerTest, ViewFocusCallbacks) {
75 std::vector<FocusTestEvent> event_list;
76 const int kView1ID = 1;
77 const int kView2ID = 2;
79 SimpleTestView* view1 = new SimpleTestView(&event_list, kView1ID);
80 SimpleTestView* view2 = new SimpleTestView(&event_list, kView2ID);
81 GetContentsView()->AddChildView(view1);
82 GetContentsView()->AddChildView(view2);
84 view1->RequestFocus();
85 ASSERT_EQ(1, static_cast<int>(event_list.size()));
86 EXPECT_EQ(ON_FOCUS, event_list[0].type);
87 EXPECT_EQ(kView1ID, event_list[0].view_id);
89 event_list.clear();
90 view2->RequestFocus();
91 ASSERT_EQ(2, static_cast<int>(event_list.size()));
92 EXPECT_EQ(ON_BLUR, event_list[0].type);
93 EXPECT_EQ(kView1ID, event_list[0].view_id);
94 EXPECT_EQ(ON_FOCUS, event_list[1].type);
95 EXPECT_EQ(kView2ID, event_list[1].view_id);
97 event_list.clear();
98 GetFocusManager()->ClearFocus();
99 ASSERT_EQ(1, static_cast<int>(event_list.size()));
100 EXPECT_EQ(ON_BLUR, event_list[0].type);
101 EXPECT_EQ(kView2ID, event_list[0].view_id);
104 TEST_F(FocusManagerTest, FocusChangeListener) {
105 View* view1 = new View();
106 view1->set_focusable(true);
107 View* view2 = new View();
108 view2->set_focusable(true);
109 GetContentsView()->AddChildView(view1);
110 GetContentsView()->AddChildView(view2);
112 TestFocusChangeListener listener;
113 AddFocusChangeListener(&listener);
115 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
116 views::View* null_view = NULL;
118 view1->RequestFocus();
119 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
120 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view1));
121 listener.ClearFocusChanges();
123 view2->RequestFocus();
124 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
125 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2));
126 listener.ClearFocusChanges();
128 GetFocusManager()->ClearFocus();
129 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
130 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, null_view));
133 TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
134 TestWidgetFocusChangeListener widget_listener;
135 AddWidgetFocusChangeListener(&widget_listener);
137 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
138 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
139 params.bounds = gfx::Rect(10, 10, 100, 100);
140 params.parent = GetWidget()->GetNativeView();
142 scoped_ptr<Widget> widget1(new Widget);
143 widget1->Init(params);
144 widget1->Show();
146 scoped_ptr<Widget> widget2(new Widget);
147 widget2->Init(params);
148 widget2->Show();
150 widget_listener.ClearFocusChanges();
151 gfx::NativeView native_view1 = widget1->GetNativeView();
152 FocusNativeView(native_view1);
153 ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
154 EXPECT_EQ(native_view1, widget_listener.focus_changes()[0].second);
155 EXPECT_EQ(native_view1, widget_listener.focus_changes()[1].second);
157 widget_listener.ClearFocusChanges();
158 gfx::NativeView native_view2 = widget2->GetNativeView();
159 FocusNativeView(native_view2);
160 ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
161 EXPECT_EQ(NativeViewPair(native_view1, native_view2),
162 widget_listener.focus_changes()[0]);
163 EXPECT_EQ(NativeViewPair(native_view1, native_view2),
164 widget_listener.focus_changes()[1]);
167 #if !defined(USE_AURA)
168 class TestTextfield : public Textfield {
169 public:
170 TestTextfield() {}
171 virtual gfx::NativeView TestGetNativeControlView() {
172 return native_wrapper_->GetTestingHandle();
176 // Tests that NativeControls do set the focused View appropriately on the
177 // FocusManager.
178 TEST_F(FocusManagerTest, DISABLED_FocusNativeControls) {
179 TestTextfield* textfield = new TestTextfield();
180 GetContentsView()->AddChildView(textfield);
181 // Simulate the native view getting the native focus (such as by user click).
182 FocusNativeView(textfield->TestGetNativeControlView());
183 EXPECT_EQ(textfield, GetFocusManager()->GetFocusedView());
185 #endif
187 // Counts accelerator calls.
188 class TestAcceleratorTarget : public ui::AcceleratorTarget {
189 public:
190 explicit TestAcceleratorTarget(bool process_accelerator)
191 : accelerator_count_(0),
192 process_accelerator_(process_accelerator),
193 can_handle_accelerators_(true) {}
195 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
196 ++accelerator_count_;
197 return process_accelerator_;
200 virtual bool CanHandleAccelerators() const OVERRIDE {
201 return can_handle_accelerators_;
204 int accelerator_count() const { return accelerator_count_; }
206 void set_can_handle_accelerators(bool can_handle_accelerators) {
207 can_handle_accelerators_ = can_handle_accelerators;
210 private:
211 int accelerator_count_; // number of times that the accelerator is activated
212 bool process_accelerator_; // return value of AcceleratorPressed
213 bool can_handle_accelerators_; // return value of CanHandleAccelerators
215 DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget);
218 TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
219 FocusManager* focus_manager = GetFocusManager();
220 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
221 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
223 TestAcceleratorTarget return_target(true);
224 TestAcceleratorTarget escape_target(true);
225 EXPECT_EQ(return_target.accelerator_count(), 0);
226 EXPECT_EQ(escape_target.accelerator_count(), 0);
227 EXPECT_EQ(NULL,
228 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
229 EXPECT_EQ(NULL,
230 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
232 // Register targets.
233 focus_manager->RegisterAccelerator(return_accelerator,
234 ui::AcceleratorManager::kNormalPriority,
235 &return_target);
236 focus_manager->RegisterAccelerator(escape_accelerator,
237 ui::AcceleratorManager::kNormalPriority,
238 &escape_target);
240 // Checks if the correct target is registered.
241 EXPECT_EQ(&return_target,
242 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
243 EXPECT_EQ(&escape_target,
244 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
246 // Hitting the return key.
247 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
248 EXPECT_EQ(return_target.accelerator_count(), 1);
249 EXPECT_EQ(escape_target.accelerator_count(), 0);
251 // Hitting the escape key.
252 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
253 EXPECT_EQ(return_target.accelerator_count(), 1);
254 EXPECT_EQ(escape_target.accelerator_count(), 1);
256 // Register another target for the return key.
257 TestAcceleratorTarget return_target2(true);
258 EXPECT_EQ(return_target2.accelerator_count(), 0);
259 focus_manager->RegisterAccelerator(return_accelerator,
260 ui::AcceleratorManager::kNormalPriority,
261 &return_target2);
262 EXPECT_EQ(&return_target2,
263 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
265 // Hitting the return key; return_target2 has the priority.
266 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
267 EXPECT_EQ(return_target.accelerator_count(), 1);
268 EXPECT_EQ(return_target2.accelerator_count(), 1);
270 // Register a target that does not process the accelerator event.
271 TestAcceleratorTarget return_target3(false);
272 EXPECT_EQ(return_target3.accelerator_count(), 0);
273 focus_manager->RegisterAccelerator(return_accelerator,
274 ui::AcceleratorManager::kNormalPriority,
275 &return_target3);
276 EXPECT_EQ(&return_target3,
277 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
279 // Hitting the return key.
280 // Since the event handler of return_target3 returns false, return_target2
281 // should be called too.
282 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
283 EXPECT_EQ(return_target.accelerator_count(), 1);
284 EXPECT_EQ(return_target2.accelerator_count(), 2);
285 EXPECT_EQ(return_target3.accelerator_count(), 1);
287 // Unregister return_target2.
288 focus_manager->UnregisterAccelerator(return_accelerator, &return_target2);
289 EXPECT_EQ(&return_target3,
290 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
292 // Hitting the return key. return_target3 and return_target should be called.
293 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
294 EXPECT_EQ(return_target.accelerator_count(), 2);
295 EXPECT_EQ(return_target2.accelerator_count(), 2);
296 EXPECT_EQ(return_target3.accelerator_count(), 2);
298 // Unregister targets.
299 focus_manager->UnregisterAccelerator(return_accelerator, &return_target);
300 focus_manager->UnregisterAccelerator(return_accelerator, &return_target3);
301 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target);
303 // Now there is no target registered.
304 EXPECT_EQ(NULL,
305 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
306 EXPECT_EQ(NULL,
307 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
309 // Hitting the return key and the escape key. Nothing should happen.
310 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
311 EXPECT_EQ(return_target.accelerator_count(), 2);
312 EXPECT_EQ(return_target2.accelerator_count(), 2);
313 EXPECT_EQ(return_target3.accelerator_count(), 2);
314 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
315 EXPECT_EQ(escape_target.accelerator_count(), 1);
318 TEST_F(FocusManagerTest, HighPriorityHandlers) {
319 FocusManager* focus_manager = GetFocusManager();
320 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
322 TestAcceleratorTarget escape_target_high(true);
323 TestAcceleratorTarget escape_target_normal(true);
324 EXPECT_EQ(escape_target_high.accelerator_count(), 0);
325 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
326 EXPECT_EQ(NULL,
327 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
328 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
330 // Register high priority target.
331 focus_manager->RegisterAccelerator(escape_accelerator,
332 ui::AcceleratorManager::kHighPriority,
333 &escape_target_high);
334 EXPECT_EQ(&escape_target_high,
335 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
336 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
338 // Hit the escape key.
339 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
340 EXPECT_EQ(escape_target_high.accelerator_count(), 1);
341 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
343 // Add a normal priority target and make sure it doesn't see the key.
344 focus_manager->RegisterAccelerator(escape_accelerator,
345 ui::AcceleratorManager::kNormalPriority,
346 &escape_target_normal);
348 // Checks if the correct target is registered (same as before, the high
349 // priority one).
350 EXPECT_EQ(&escape_target_high,
351 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
352 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
354 // Hit the escape key.
355 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
356 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
357 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
359 // Unregister the high priority accelerator.
360 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
361 EXPECT_EQ(&escape_target_normal,
362 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
363 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
365 // Hit the escape key.
366 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
367 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
368 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
370 // Add the high priority target back and make sure it starts seeing the key.
371 focus_manager->RegisterAccelerator(escape_accelerator,
372 ui::AcceleratorManager::kHighPriority,
373 &escape_target_high);
374 EXPECT_EQ(&escape_target_high,
375 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
376 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
378 // Hit the escape key.
379 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
380 EXPECT_EQ(escape_target_high.accelerator_count(), 3);
381 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
383 // Unregister the normal priority accelerator.
384 focus_manager->UnregisterAccelerator(
385 escape_accelerator, &escape_target_normal);
386 EXPECT_EQ(&escape_target_high,
387 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
388 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
390 // Hit the escape key.
391 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
392 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
393 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
395 // Unregister the high priority accelerator.
396 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
397 EXPECT_EQ(NULL,
398 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
399 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
401 // Hit the escape key (no change, no targets registered).
402 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
403 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
404 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
407 TEST_F(FocusManagerTest, CallsEnabledAcceleratorTargetsOnly) {
408 FocusManager* focus_manager = GetFocusManager();
409 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
411 TestAcceleratorTarget return_target1(true);
412 TestAcceleratorTarget return_target2(true);
414 focus_manager->RegisterAccelerator(return_accelerator,
415 ui::AcceleratorManager::kNormalPriority,
416 &return_target1);
417 focus_manager->RegisterAccelerator(return_accelerator,
418 ui::AcceleratorManager::kNormalPriority,
419 &return_target2);
420 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
421 EXPECT_EQ(0, return_target1.accelerator_count());
422 EXPECT_EQ(1, return_target2.accelerator_count());
424 // If CanHandleAccelerators() return false, FocusManager shouldn't call
425 // AcceleratorPressed().
426 return_target2.set_can_handle_accelerators(false);
427 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
428 EXPECT_EQ(1, return_target1.accelerator_count());
429 EXPECT_EQ(1, return_target2.accelerator_count());
431 // If no accelerator targets are enabled, ProcessAccelerator() should fail.
432 return_target1.set_can_handle_accelerators(false);
433 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
434 EXPECT_EQ(1, return_target1.accelerator_count());
435 EXPECT_EQ(1, return_target2.accelerator_count());
437 // Enabling the target again causes the accelerators to be processed again.
438 return_target1.set_can_handle_accelerators(true);
439 return_target2.set_can_handle_accelerators(true);
440 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
441 EXPECT_EQ(1, return_target1.accelerator_count());
442 EXPECT_EQ(2, return_target2.accelerator_count());
445 // Unregisters itself when its accelerator is invoked.
446 class SelfUnregisteringAcceleratorTarget : public ui::AcceleratorTarget {
447 public:
448 SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator,
449 FocusManager* focus_manager)
450 : accelerator_(accelerator),
451 focus_manager_(focus_manager),
452 accelerator_count_(0) {
455 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
456 ++accelerator_count_;
457 focus_manager_->UnregisterAccelerator(accelerator, this);
458 return true;
461 virtual bool CanHandleAccelerators() const OVERRIDE {
462 return true;
465 int accelerator_count() const { return accelerator_count_; }
467 private:
468 ui::Accelerator accelerator_;
469 FocusManager* focus_manager_;
470 int accelerator_count_;
472 DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget);
475 TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) {
476 FocusManager* focus_manager = GetFocusManager();
477 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
478 SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager);
479 EXPECT_EQ(target.accelerator_count(), 0);
480 EXPECT_EQ(NULL,
481 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
483 // Register the target.
484 focus_manager->RegisterAccelerator(return_accelerator,
485 ui::AcceleratorManager::kNormalPriority,
486 &target);
487 EXPECT_EQ(&target,
488 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
490 // Hitting the return key. The target will be unregistered.
491 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
492 EXPECT_EQ(target.accelerator_count(), 1);
493 EXPECT_EQ(NULL,
494 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
496 // Hitting the return key again; nothing should happen.
497 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
498 EXPECT_EQ(target.accelerator_count(), 1);
501 class FocusManagerDtorTest : public FocusManagerTest {
502 protected:
503 typedef std::vector<std::string> DtorTrackVector;
505 class FocusManagerDtorTracked : public FocusManager {
506 public:
507 FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker)
508 : FocusManager(widget, NULL /* delegate */),
509 dtor_tracker_(dtor_tracker) {
512 virtual ~FocusManagerDtorTracked() {
513 dtor_tracker_->push_back("FocusManagerDtorTracked");
516 DtorTrackVector* dtor_tracker_;
518 private:
519 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked);
522 class TestFocusManagerFactory : public FocusManagerFactory {
523 public:
524 explicit TestFocusManagerFactory(DtorTrackVector* dtor_tracker)
525 : dtor_tracker_(dtor_tracker) {
528 virtual FocusManager* CreateFocusManager(Widget* widget,
529 bool desktop_widget) OVERRIDE {
530 return new FocusManagerDtorTracked(widget, dtor_tracker_);
533 private:
534 DtorTrackVector* dtor_tracker_;
535 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory);
538 class LabelButtonDtorTracked : public LabelButton {
539 public:
540 LabelButtonDtorTracked(const string16& text, DtorTrackVector* dtor_tracker)
541 : LabelButton(NULL, text),
542 dtor_tracker_(dtor_tracker) {
543 SetStyle(STYLE_NATIVE_TEXTBUTTON);
545 virtual ~LabelButtonDtorTracked() {
546 dtor_tracker_->push_back("LabelButtonDtorTracked");
549 DtorTrackVector* dtor_tracker_;
552 class WindowDtorTracked : public Widget {
553 public:
554 explicit WindowDtorTracked(DtorTrackVector* dtor_tracker)
555 : dtor_tracker_(dtor_tracker) {
558 virtual ~WindowDtorTracked() {
559 dtor_tracker_->push_back("WindowDtorTracked");
562 DtorTrackVector* dtor_tracker_;
565 virtual void SetUp() {
566 ViewsTestBase::SetUp();
567 FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_));
568 // Create WindowDtorTracked that uses FocusManagerDtorTracked.
569 Widget* widget = new WindowDtorTracked(&dtor_tracker_);
570 Widget::InitParams params;
571 params.delegate = this;
572 params.bounds = gfx::Rect(0, 0, 100, 100);
573 widget->Init(params);
575 tracked_focus_manager_ =
576 static_cast<FocusManagerDtorTracked*>(GetFocusManager());
577 widget->Show();
580 virtual void TearDown() {
581 FocusManagerFactory::Install(NULL);
582 ViewsTestBase::TearDown();
585 FocusManager* tracked_focus_manager_;
586 DtorTrackVector dtor_tracker_;
589 #if !defined(USE_AURA)
590 TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) {
591 // Setup views hierarchy.
592 GetContentsView()->AddChildView(new TestTextfield());
593 GetContentsView()->AddChildView(new LabelButtonDtorTracked(
594 ASCIIToUTF16("button"), &dtor_tracker_));
596 // Close the window.
597 GetWidget()->Close();
598 RunPendingMessages();
600 // Test window, button and focus manager should all be destructed.
601 ASSERT_EQ(3, static_cast<int>(dtor_tracker_.size()));
603 // Focus manager should be the last one to destruct.
604 ASSERT_STREQ("FocusManagerDtorTracked", dtor_tracker_[2].c_str());
606 #endif
608 namespace {
610 class FocusInAboutToRequestFocusFromTabTraversalView : public View {
611 public:
612 FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL) {}
614 void set_view_to_focus(View* view) { view_to_focus_ = view; }
616 virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE {
617 view_to_focus_->RequestFocus();
620 private:
621 views::View* view_to_focus_;
623 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView);
625 } // namespace
627 // Verifies a focus change done during a call to
628 // AboutToRequestFocusFromTabTraversal() is honored.
629 TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) {
630 // Create 3 views focuses the 3 and advances to the second. The 2nd views
631 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
632 views::View* v1 = new View;
633 v1->set_focusable(true);
634 GetContentsView()->AddChildView(v1);
636 FocusInAboutToRequestFocusFromTabTraversalView* v2 =
637 new FocusInAboutToRequestFocusFromTabTraversalView;
638 v2->set_focusable(true);
639 v2->set_view_to_focus(v1);
640 GetContentsView()->AddChildView(v2);
642 views::View* v3 = new View;
643 v3->set_focusable(true);
644 GetContentsView()->AddChildView(v3);
646 v3->RequestFocus();
647 GetWidget()->GetFocusManager()->AdvanceFocus(true);
648 EXPECT_TRUE(v1->HasFocus());
651 TEST_F(FocusManagerTest, RotatePaneFocus) {
652 views::AccessiblePaneView* pane1 = new AccessiblePaneView();
653 GetContentsView()->AddChildView(pane1);
655 views::View* v1 = new View;
656 v1->set_focusable(true);
657 pane1->AddChildView(v1);
659 views::View* v2 = new View;
660 v2->set_focusable(true);
661 pane1->AddChildView(v2);
663 views::AccessiblePaneView* pane2 = new AccessiblePaneView();
664 GetContentsView()->AddChildView(pane2);
666 views::View* v3 = new View;
667 v3->set_focusable(true);
668 pane2->AddChildView(v3);
670 views::View* v4 = new View;
671 v4->set_focusable(true);
672 pane2->AddChildView(v4);
674 std::vector<views::View*> panes;
675 panes.push_back(pane1);
676 panes.push_back(pane2);
677 SetAccessiblePanes(panes);
679 FocusManager* focus_manager = GetWidget()->GetFocusManager();
681 // Advance forwards. Focus should stay trapped within each pane.
682 EXPECT_TRUE(focus_manager->RotatePaneFocus(
683 FocusManager::kForward, FocusManager::kWrap));
684 EXPECT_EQ(v1, focus_manager->GetFocusedView());
685 focus_manager->AdvanceFocus(false);
686 EXPECT_EQ(v2, focus_manager->GetFocusedView());
687 focus_manager->AdvanceFocus(false);
688 EXPECT_EQ(v1, focus_manager->GetFocusedView());
690 EXPECT_TRUE(focus_manager->RotatePaneFocus(
691 FocusManager::kForward, FocusManager::kWrap));
692 EXPECT_EQ(v3, focus_manager->GetFocusedView());
693 focus_manager->AdvanceFocus(false);
694 EXPECT_EQ(v4, focus_manager->GetFocusedView());
695 focus_manager->AdvanceFocus(false);
696 EXPECT_EQ(v3, focus_manager->GetFocusedView());
698 EXPECT_TRUE(focus_manager->RotatePaneFocus(
699 FocusManager::kForward, FocusManager::kWrap));
700 EXPECT_EQ(v1, focus_manager->GetFocusedView());
702 // Advance backwards.
703 EXPECT_TRUE(focus_manager->RotatePaneFocus(
704 FocusManager::kBackward, FocusManager::kWrap));
705 EXPECT_EQ(v3, focus_manager->GetFocusedView());
707 EXPECT_TRUE(focus_manager->RotatePaneFocus(
708 FocusManager::kBackward, FocusManager::kWrap));
709 EXPECT_EQ(v1, focus_manager->GetFocusedView());
711 // Advance without wrap. When it gets to the end of the list of
712 // panes, RotatePaneFocus should return false but the current
713 // focused view shouldn't change.
714 EXPECT_TRUE(focus_manager->RotatePaneFocus(
715 FocusManager::kForward, FocusManager::kNoWrap));
716 EXPECT_EQ(v3, focus_manager->GetFocusedView());
718 EXPECT_FALSE(focus_manager->RotatePaneFocus(
719 FocusManager::kForward, FocusManager::kNoWrap));
720 EXPECT_EQ(v3, focus_manager->GetFocusedView());
723 // Verifies the stored focus view tracks the focused view.
724 TEST_F(FocusManagerTest, ImplicitlyStoresFocus) {
725 views::View* v1 = new View;
726 v1->set_focusable(true);
727 GetContentsView()->AddChildView(v1);
729 views::View* v2 = new View;
730 v2->set_focusable(true);
731 GetContentsView()->AddChildView(v2);
733 // Verify a focus request on |v1| implicitly updates the stored focus view.
734 v1->RequestFocus();
735 EXPECT_TRUE(v1->HasFocus());
736 EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView());
738 // Verify a focus request on |v2| implicitly updates the stored focus view.
739 v2->RequestFocus();
740 EXPECT_TRUE(v2->HasFocus());
741 EXPECT_EQ(v2, GetWidget()->GetFocusManager()->GetStoredFocusView());
744 namespace {
746 class FocusManagerArrowKeyTraversalTest : public FocusManagerTest {
747 public:
748 FocusManagerArrowKeyTraversalTest()
749 : previous_arrow_key_traversal_enabled_(false) {
751 virtual ~FocusManagerArrowKeyTraversalTest() {}
753 // FocusManagerTest overrides:
754 virtual void SetUp() OVERRIDE {
755 FocusManagerTest::SetUp();
757 previous_arrow_key_traversal_enabled_ =
758 FocusManager::arrow_key_traversal_enabled();
760 virtual void TearDown() OVERRIDE {
761 FocusManager::set_arrow_key_traversal_enabled(
762 previous_arrow_key_traversal_enabled_);
763 FocusManagerTest::TearDown();
766 private:
767 bool previous_arrow_key_traversal_enabled_;
769 DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest);
772 } // namespace
774 TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
775 FocusManager* focus_manager = GetFocusManager();
776 const ui::KeyEvent left_key(
777 ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE, false);
778 const ui::KeyEvent right_key(
779 ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE, false);
780 const ui::KeyEvent up_key(
781 ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE, false);
782 const ui::KeyEvent down_key(
783 ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE, false);
785 std::vector<views::View*> v;
786 for (size_t i = 0; i < 2; ++i) {
787 views::View* view = new View;
788 view->set_focusable(true);
789 GetContentsView()->AddChildView(view);
790 v.push_back(view);
793 // Arrow key traversal is off and arrow key does not change focus.
794 FocusManager::set_arrow_key_traversal_enabled(false);
795 v[0]->RequestFocus();
796 focus_manager->OnKeyEvent(right_key);
797 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
798 focus_manager->OnKeyEvent(left_key);
799 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
800 focus_manager->OnKeyEvent(down_key);
801 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
802 focus_manager->OnKeyEvent(up_key);
803 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
805 // Turn on arrow key traversal.
806 FocusManager::set_arrow_key_traversal_enabled(true);
807 v[0]->RequestFocus();
808 focus_manager->OnKeyEvent(right_key);
809 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
810 focus_manager->OnKeyEvent(left_key);
811 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
812 focus_manager->OnKeyEvent(down_key);
813 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
814 focus_manager->OnKeyEvent(up_key);
815 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
818 TEST_F(FocusManagerTest, StoreFocusedView) {
819 View view;
820 GetFocusManager()->SetFocusedView(&view);
821 GetFocusManager()->StoreFocusedView(false);
822 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
823 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
825 // Repeat with |true|.
826 GetFocusManager()->SetFocusedView(&view);
827 GetFocusManager()->StoreFocusedView(true);
828 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
829 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
832 namespace {
834 // Trivial WidgetDelegate implementation that allows setting return value of
835 // ShouldAdvanceFocusToTopLevelWidget().
836 class AdvanceFocusWidgetDelegate : public WidgetDelegate {
837 public:
838 explicit AdvanceFocusWidgetDelegate(Widget* widget)
839 : widget_(widget),
840 should_advance_focus_to_parent_(false) {}
841 virtual ~AdvanceFocusWidgetDelegate() {}
843 void set_should_advance_focus_to_parent(bool value) {
844 should_advance_focus_to_parent_ = value;
847 // WidgetDelegate overrides:
848 virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE {
849 return should_advance_focus_to_parent_;
851 virtual Widget* GetWidget() OVERRIDE { return widget_; }
852 virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
854 private:
855 Widget* widget_;
856 bool should_advance_focus_to_parent_;
858 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate);
861 } // namespace
863 // Verifies focus wrapping happens in the same widget.
864 TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
865 // Add |widget_view| as a child of the Widget.
866 View* widget_view = new View;
867 widget_view->set_focusable(true);
868 widget_view->SetBounds(20, 0, 20, 20);
869 GetContentsView()->AddChildView(widget_view);
871 // Create a widget with two views, focus the second.
872 scoped_ptr<AdvanceFocusWidgetDelegate> delegate;
873 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
874 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
875 params.child = true;
876 params.bounds = gfx::Rect(10, 10, 100, 100);
877 params.parent = GetWidget()->GetNativeView();
878 Widget child_widget;
879 delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget));
880 params.delegate = delegate.get();
881 child_widget.Init(params);
882 View* view1 = new View;
883 view1->set_focusable(true);
884 view1->SetBounds(0, 0, 20, 20);
885 View* view2 = new View;
886 view2->set_focusable(true);
887 view2->SetBounds(20, 0, 20, 20);
888 child_widget.client_view()->AddChildView(view1);
889 child_widget.client_view()->AddChildView(view2);
890 child_widget.Show();
891 view2->RequestFocus();
892 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
894 // Advance focus backwards, which should focus the first.
895 GetFocusManager()->AdvanceFocus(false);
896 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
898 // Focus forward to |view2|.
899 GetFocusManager()->AdvanceFocus(true);
900 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
902 // And forward again, wrapping back to |view1|.
903 GetFocusManager()->AdvanceFocus(true);
904 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
906 // Allow focus to go to the parent, and focus backwards which should now move
907 // up |widget_view| (in the parent).
908 delegate->set_should_advance_focus_to_parent(true);
909 GetFocusManager()->AdvanceFocus(true);
910 EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView());
913 } // namespace views