Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / views / focus / focus_manager_unittest.cc
blobc9032644ba37c08c9f8e9196aaab83007aaff16a
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 "ui/views/focus/focus_manager.h"
7 #include <utility>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "ui/base/accelerators/accelerator.h"
13 #include "ui/events/keycodes/keyboard_codes.h"
14 #include "ui/views/accessible_pane_view.h"
15 #include "ui/views/controls/button/label_button.h"
16 #include "ui/views/focus/focus_manager_factory.h"
17 #include "ui/views/focus/widget_focus_manager.h"
18 #include "ui/views/test/focus_manager_test.h"
19 #include "ui/views/test/widget_test.h"
20 #include "ui/views/widget/widget.h"
22 namespace views {
24 enum FocusTestEventType {
25 ON_FOCUS = 0,
26 ON_BLUR
29 struct FocusTestEvent {
30 FocusTestEvent(FocusTestEventType type, int view_id)
31 : type(type),
32 view_id(view_id) {
35 FocusTestEventType type;
36 int view_id;
39 class SimpleTestView : public View {
40 public:
41 SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id)
42 : event_list_(event_list) {
43 SetFocusable(true);
44 set_id(view_id);
47 void OnFocus() override {
48 event_list_->push_back(FocusTestEvent(ON_FOCUS, id()));
51 void OnBlur() override {
52 event_list_->push_back(FocusTestEvent(ON_BLUR, id()));
55 private:
56 std::vector<FocusTestEvent>* event_list_;
58 DISALLOW_COPY_AND_ASSIGN(SimpleTestView);
61 // Tests that the appropriate Focus related methods are called when a View
62 // gets/loses focus.
63 TEST_F(FocusManagerTest, ViewFocusCallbacks) {
64 std::vector<FocusTestEvent> event_list;
65 const int kView1ID = 1;
66 const int kView2ID = 2;
68 SimpleTestView* view1 = new SimpleTestView(&event_list, kView1ID);
69 SimpleTestView* view2 = new SimpleTestView(&event_list, kView2ID);
70 GetContentsView()->AddChildView(view1);
71 GetContentsView()->AddChildView(view2);
73 view1->RequestFocus();
74 ASSERT_EQ(1, static_cast<int>(event_list.size()));
75 EXPECT_EQ(ON_FOCUS, event_list[0].type);
76 EXPECT_EQ(kView1ID, event_list[0].view_id);
78 event_list.clear();
79 view2->RequestFocus();
80 ASSERT_EQ(2, static_cast<int>(event_list.size()));
81 EXPECT_EQ(ON_BLUR, event_list[0].type);
82 EXPECT_EQ(kView1ID, event_list[0].view_id);
83 EXPECT_EQ(ON_FOCUS, event_list[1].type);
84 EXPECT_EQ(kView2ID, event_list[1].view_id);
86 event_list.clear();
87 GetFocusManager()->ClearFocus();
88 ASSERT_EQ(1, static_cast<int>(event_list.size()));
89 EXPECT_EQ(ON_BLUR, event_list[0].type);
90 EXPECT_EQ(kView2ID, event_list[0].view_id);
93 TEST_F(FocusManagerTest, FocusChangeListener) {
94 View* view1 = new View();
95 view1->SetFocusable(true);
96 View* view2 = new View();
97 view2->SetFocusable(true);
98 GetContentsView()->AddChildView(view1);
99 GetContentsView()->AddChildView(view2);
101 TestFocusChangeListener listener;
102 AddFocusChangeListener(&listener);
104 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
105 views::View* null_view = NULL;
107 view1->RequestFocus();
108 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
109 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view1));
110 listener.ClearFocusChanges();
112 view2->RequestFocus();
113 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
114 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2));
115 listener.ClearFocusChanges();
117 GetFocusManager()->ClearFocus();
118 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
119 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, null_view));
122 TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
123 // First, ensure the simulator is aware of the Widget created in SetUp() being
124 // currently active.
125 test::WidgetTest::SimulateNativeActivate(GetWidget());
127 TestWidgetFocusChangeListener widget_listener;
128 AddWidgetFocusChangeListener(&widget_listener);
130 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
131 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
132 params.bounds = gfx::Rect(10, 10, 100, 100);
133 params.parent = GetWidget()->GetNativeView();
135 scoped_ptr<Widget> widget1(new Widget);
136 widget1->Init(params);
137 widget1->Show();
139 scoped_ptr<Widget> widget2(new Widget);
140 widget2->Init(params);
141 widget2->Show();
143 widget_listener.ClearFocusChanges();
144 gfx::NativeView native_view1 = widget1->GetNativeView();
145 test::WidgetTest::SimulateNativeActivate(widget1.get());
146 ASSERT_EQ(2u, widget_listener.focus_changes().size());
147 EXPECT_EQ(nullptr, widget_listener.focus_changes()[0]);
148 EXPECT_EQ(native_view1, widget_listener.focus_changes()[1]);
150 widget_listener.ClearFocusChanges();
151 gfx::NativeView native_view2 = widget2->GetNativeView();
152 test::WidgetTest::SimulateNativeActivate(widget2.get());
153 ASSERT_EQ(2u, widget_listener.focus_changes().size());
154 EXPECT_EQ(nullptr, widget_listener.focus_changes()[0]);
155 EXPECT_EQ(native_view2, widget_listener.focus_changes()[1]);
158 // Counts accelerator calls.
159 class TestAcceleratorTarget : public ui::AcceleratorTarget {
160 public:
161 explicit TestAcceleratorTarget(bool process_accelerator)
162 : accelerator_count_(0),
163 process_accelerator_(process_accelerator),
164 can_handle_accelerators_(true) {}
166 bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
167 ++accelerator_count_;
168 return process_accelerator_;
171 bool CanHandleAccelerators() const override {
172 return can_handle_accelerators_;
175 int accelerator_count() const { return accelerator_count_; }
177 void set_can_handle_accelerators(bool can_handle_accelerators) {
178 can_handle_accelerators_ = can_handle_accelerators;
181 private:
182 int accelerator_count_; // number of times that the accelerator is activated
183 bool process_accelerator_; // return value of AcceleratorPressed
184 bool can_handle_accelerators_; // return value of CanHandleAccelerators
186 DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget);
189 TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
190 FocusManager* focus_manager = GetFocusManager();
191 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
192 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
194 TestAcceleratorTarget return_target(true);
195 TestAcceleratorTarget escape_target(true);
196 EXPECT_EQ(return_target.accelerator_count(), 0);
197 EXPECT_EQ(escape_target.accelerator_count(), 0);
198 EXPECT_EQ(NULL,
199 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
200 EXPECT_EQ(NULL,
201 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
203 // Register targets.
204 focus_manager->RegisterAccelerator(return_accelerator,
205 ui::AcceleratorManager::kNormalPriority,
206 &return_target);
207 focus_manager->RegisterAccelerator(escape_accelerator,
208 ui::AcceleratorManager::kNormalPriority,
209 &escape_target);
211 // Checks if the correct target is registered.
212 EXPECT_EQ(&return_target,
213 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
214 EXPECT_EQ(&escape_target,
215 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
217 // Hitting the return key.
218 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
219 EXPECT_EQ(return_target.accelerator_count(), 1);
220 EXPECT_EQ(escape_target.accelerator_count(), 0);
222 // Hitting the escape key.
223 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
224 EXPECT_EQ(return_target.accelerator_count(), 1);
225 EXPECT_EQ(escape_target.accelerator_count(), 1);
227 // Register another target for the return key.
228 TestAcceleratorTarget return_target2(true);
229 EXPECT_EQ(return_target2.accelerator_count(), 0);
230 focus_manager->RegisterAccelerator(return_accelerator,
231 ui::AcceleratorManager::kNormalPriority,
232 &return_target2);
233 EXPECT_EQ(&return_target2,
234 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
236 // Hitting the return key; return_target2 has the priority.
237 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
238 EXPECT_EQ(return_target.accelerator_count(), 1);
239 EXPECT_EQ(return_target2.accelerator_count(), 1);
241 // Register a target that does not process the accelerator event.
242 TestAcceleratorTarget return_target3(false);
243 EXPECT_EQ(return_target3.accelerator_count(), 0);
244 focus_manager->RegisterAccelerator(return_accelerator,
245 ui::AcceleratorManager::kNormalPriority,
246 &return_target3);
247 EXPECT_EQ(&return_target3,
248 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
250 // Hitting the return key.
251 // Since the event handler of return_target3 returns false, return_target2
252 // should be called too.
253 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
254 EXPECT_EQ(return_target.accelerator_count(), 1);
255 EXPECT_EQ(return_target2.accelerator_count(), 2);
256 EXPECT_EQ(return_target3.accelerator_count(), 1);
258 // Unregister return_target2.
259 focus_manager->UnregisterAccelerator(return_accelerator, &return_target2);
260 EXPECT_EQ(&return_target3,
261 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
263 // Hitting the return key. return_target3 and return_target should be called.
264 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
265 EXPECT_EQ(return_target.accelerator_count(), 2);
266 EXPECT_EQ(return_target2.accelerator_count(), 2);
267 EXPECT_EQ(return_target3.accelerator_count(), 2);
269 // Unregister targets.
270 focus_manager->UnregisterAccelerator(return_accelerator, &return_target);
271 focus_manager->UnregisterAccelerator(return_accelerator, &return_target3);
272 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target);
274 // Now there is no target registered.
275 EXPECT_EQ(NULL,
276 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
277 EXPECT_EQ(NULL,
278 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
280 // Hitting the return key and the escape key. Nothing should happen.
281 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
282 EXPECT_EQ(return_target.accelerator_count(), 2);
283 EXPECT_EQ(return_target2.accelerator_count(), 2);
284 EXPECT_EQ(return_target3.accelerator_count(), 2);
285 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
286 EXPECT_EQ(escape_target.accelerator_count(), 1);
289 TEST_F(FocusManagerTest, HighPriorityHandlers) {
290 FocusManager* focus_manager = GetFocusManager();
291 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
293 TestAcceleratorTarget escape_target_high(true);
294 TestAcceleratorTarget escape_target_normal(true);
295 EXPECT_EQ(escape_target_high.accelerator_count(), 0);
296 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
297 EXPECT_EQ(NULL,
298 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
299 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
301 // Register high priority target.
302 focus_manager->RegisterAccelerator(escape_accelerator,
303 ui::AcceleratorManager::kHighPriority,
304 &escape_target_high);
305 EXPECT_EQ(&escape_target_high,
306 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
307 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
309 // Hit the escape key.
310 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
311 EXPECT_EQ(escape_target_high.accelerator_count(), 1);
312 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
314 // Add a normal priority target and make sure it doesn't see the key.
315 focus_manager->RegisterAccelerator(escape_accelerator,
316 ui::AcceleratorManager::kNormalPriority,
317 &escape_target_normal);
319 // Checks if the correct target is registered (same as before, the high
320 // priority one).
321 EXPECT_EQ(&escape_target_high,
322 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
323 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
325 // Hit the escape key.
326 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
327 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
328 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
330 // Unregister the high priority accelerator.
331 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
332 EXPECT_EQ(&escape_target_normal,
333 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
334 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
336 // Hit the escape key.
337 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
338 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
339 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
341 // Add the high priority target back and make sure it starts seeing the key.
342 focus_manager->RegisterAccelerator(escape_accelerator,
343 ui::AcceleratorManager::kHighPriority,
344 &escape_target_high);
345 EXPECT_EQ(&escape_target_high,
346 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
347 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
349 // Hit the escape key.
350 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
351 EXPECT_EQ(escape_target_high.accelerator_count(), 3);
352 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
354 // Unregister the normal priority accelerator.
355 focus_manager->UnregisterAccelerator(
356 escape_accelerator, &escape_target_normal);
357 EXPECT_EQ(&escape_target_high,
358 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
359 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
361 // Hit the escape key.
362 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
363 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
364 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
366 // Unregister the high priority accelerator.
367 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
368 EXPECT_EQ(NULL,
369 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
370 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
372 // Hit the escape key (no change, no targets registered).
373 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
374 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
375 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
378 TEST_F(FocusManagerTest, CallsEnabledAcceleratorTargetsOnly) {
379 FocusManager* focus_manager = GetFocusManager();
380 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
382 TestAcceleratorTarget return_target1(true);
383 TestAcceleratorTarget return_target2(true);
385 focus_manager->RegisterAccelerator(return_accelerator,
386 ui::AcceleratorManager::kNormalPriority,
387 &return_target1);
388 focus_manager->RegisterAccelerator(return_accelerator,
389 ui::AcceleratorManager::kNormalPriority,
390 &return_target2);
391 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
392 EXPECT_EQ(0, return_target1.accelerator_count());
393 EXPECT_EQ(1, return_target2.accelerator_count());
395 // If CanHandleAccelerators() return false, FocusManager shouldn't call
396 // AcceleratorPressed().
397 return_target2.set_can_handle_accelerators(false);
398 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
399 EXPECT_EQ(1, return_target1.accelerator_count());
400 EXPECT_EQ(1, return_target2.accelerator_count());
402 // If no accelerator targets are enabled, ProcessAccelerator() should fail.
403 return_target1.set_can_handle_accelerators(false);
404 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
405 EXPECT_EQ(1, return_target1.accelerator_count());
406 EXPECT_EQ(1, return_target2.accelerator_count());
408 // Enabling the target again causes the accelerators to be processed again.
409 return_target1.set_can_handle_accelerators(true);
410 return_target2.set_can_handle_accelerators(true);
411 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
412 EXPECT_EQ(1, return_target1.accelerator_count());
413 EXPECT_EQ(2, return_target2.accelerator_count());
416 // Unregisters itself when its accelerator is invoked.
417 class SelfUnregisteringAcceleratorTarget : public ui::AcceleratorTarget {
418 public:
419 SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator,
420 FocusManager* focus_manager)
421 : accelerator_(accelerator),
422 focus_manager_(focus_manager),
423 accelerator_count_(0) {
426 bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
427 ++accelerator_count_;
428 focus_manager_->UnregisterAccelerator(accelerator, this);
429 return true;
432 bool CanHandleAccelerators() const override { return true; }
434 int accelerator_count() const { return accelerator_count_; }
436 private:
437 ui::Accelerator accelerator_;
438 FocusManager* focus_manager_;
439 int accelerator_count_;
441 DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget);
444 TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) {
445 FocusManager* focus_manager = GetFocusManager();
446 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
447 SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager);
448 EXPECT_EQ(target.accelerator_count(), 0);
449 EXPECT_EQ(NULL,
450 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
452 // Register the target.
453 focus_manager->RegisterAccelerator(return_accelerator,
454 ui::AcceleratorManager::kNormalPriority,
455 &target);
456 EXPECT_EQ(&target,
457 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
459 // Hitting the return key. The target will be unregistered.
460 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
461 EXPECT_EQ(target.accelerator_count(), 1);
462 EXPECT_EQ(NULL,
463 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
465 // Hitting the return key again; nothing should happen.
466 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
467 EXPECT_EQ(target.accelerator_count(), 1);
470 TEST_F(FocusManagerTest, SuspendAccelerators) {
471 const ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
472 ui::Accelerator accelerator(event.key_code(), event.flags());
473 TestAcceleratorTarget target(true);
474 FocusManager* focus_manager = GetFocusManager();
475 focus_manager->RegisterAccelerator(accelerator,
476 ui::AcceleratorManager::kNormalPriority,
477 &target);
479 focus_manager->set_shortcut_handling_suspended(true);
480 EXPECT_TRUE(focus_manager->OnKeyEvent(event));
481 EXPECT_EQ(0, target.accelerator_count());
483 focus_manager->set_shortcut_handling_suspended(false);
484 EXPECT_FALSE(focus_manager->OnKeyEvent(event));
485 EXPECT_EQ(1, target.accelerator_count());
488 class FocusManagerDtorTest : public FocusManagerTest {
489 protected:
490 typedef std::vector<std::string> DtorTrackVector;
492 class FocusManagerDtorTracked : public FocusManager {
493 public:
494 FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker)
495 : FocusManager(widget, NULL /* delegate */),
496 dtor_tracker_(dtor_tracker) {
499 ~FocusManagerDtorTracked() override {
500 dtor_tracker_->push_back("FocusManagerDtorTracked");
503 DtorTrackVector* dtor_tracker_;
505 private:
506 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked);
509 class TestFocusManagerFactory : public FocusManagerFactory {
510 public:
511 explicit TestFocusManagerFactory(DtorTrackVector* dtor_tracker)
512 : dtor_tracker_(dtor_tracker) {
515 FocusManager* CreateFocusManager(Widget* widget,
516 bool desktop_widget) override {
517 return new FocusManagerDtorTracked(widget, dtor_tracker_);
520 private:
521 DtorTrackVector* dtor_tracker_;
522 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory);
525 class LabelButtonDtorTracked : public LabelButton {
526 public:
527 LabelButtonDtorTracked(const base::string16& text,
528 DtorTrackVector* dtor_tracker)
529 : LabelButton(NULL, text),
530 dtor_tracker_(dtor_tracker) {
531 SetStyle(STYLE_BUTTON);
533 ~LabelButtonDtorTracked() override {
534 dtor_tracker_->push_back("LabelButtonDtorTracked");
537 DtorTrackVector* dtor_tracker_;
540 class WindowDtorTracked : public Widget {
541 public:
542 explicit WindowDtorTracked(DtorTrackVector* dtor_tracker)
543 : dtor_tracker_(dtor_tracker) {
546 ~WindowDtorTracked() override {
547 dtor_tracker_->push_back("WindowDtorTracked");
550 DtorTrackVector* dtor_tracker_;
553 void SetUp() override {
554 ViewsTestBase::SetUp();
555 FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_));
556 // Create WindowDtorTracked that uses FocusManagerDtorTracked.
557 Widget* widget = new WindowDtorTracked(&dtor_tracker_);
558 Widget::InitParams params;
559 params.delegate = this;
560 params.bounds = gfx::Rect(0, 0, 100, 100);
561 widget->Init(params);
563 tracked_focus_manager_ =
564 static_cast<FocusManagerDtorTracked*>(GetFocusManager());
565 widget->Show();
568 void TearDown() override {
569 FocusManagerFactory::Install(NULL);
570 ViewsTestBase::TearDown();
573 FocusManager* tracked_focus_manager_;
574 DtorTrackVector dtor_tracker_;
577 namespace {
579 class FocusInAboutToRequestFocusFromTabTraversalView : public View {
580 public:
581 FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL) {}
583 void set_view_to_focus(View* view) { view_to_focus_ = view; }
585 void AboutToRequestFocusFromTabTraversal(bool reverse) override {
586 view_to_focus_->RequestFocus();
589 private:
590 views::View* view_to_focus_;
592 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView);
594 } // namespace
596 // Verifies a focus change done during a call to
597 // AboutToRequestFocusFromTabTraversal() is honored.
598 TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) {
599 // Create 3 views focuses the 3 and advances to the second. The 2nd views
600 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
601 views::View* v1 = new View;
602 v1->SetFocusable(true);
603 GetContentsView()->AddChildView(v1);
605 FocusInAboutToRequestFocusFromTabTraversalView* v2 =
606 new FocusInAboutToRequestFocusFromTabTraversalView;
607 v2->SetFocusable(true);
608 v2->set_view_to_focus(v1);
609 GetContentsView()->AddChildView(v2);
611 views::View* v3 = new View;
612 v3->SetFocusable(true);
613 GetContentsView()->AddChildView(v3);
615 v3->RequestFocus();
616 GetWidget()->GetFocusManager()->AdvanceFocus(true);
617 EXPECT_TRUE(v1->HasFocus());
620 TEST_F(FocusManagerTest, RotatePaneFocus) {
621 views::AccessiblePaneView* pane1 = new AccessiblePaneView();
622 GetContentsView()->AddChildView(pane1);
624 views::View* v1 = new View;
625 v1->SetFocusable(true);
626 pane1->AddChildView(v1);
628 views::View* v2 = new View;
629 v2->SetFocusable(true);
630 pane1->AddChildView(v2);
632 views::AccessiblePaneView* pane2 = new AccessiblePaneView();
633 GetContentsView()->AddChildView(pane2);
635 views::View* v3 = new View;
636 v3->SetFocusable(true);
637 pane2->AddChildView(v3);
639 views::View* v4 = new View;
640 v4->SetFocusable(true);
641 pane2->AddChildView(v4);
643 std::vector<views::View*> panes;
644 panes.push_back(pane1);
645 panes.push_back(pane2);
646 SetAccessiblePanes(panes);
648 FocusManager* focus_manager = GetWidget()->GetFocusManager();
650 // Advance forwards. Focus should stay trapped within each pane.
651 EXPECT_TRUE(focus_manager->RotatePaneFocus(
652 FocusManager::kForward, FocusManager::kWrap));
653 EXPECT_EQ(v1, focus_manager->GetFocusedView());
654 focus_manager->AdvanceFocus(false);
655 EXPECT_EQ(v2, focus_manager->GetFocusedView());
656 focus_manager->AdvanceFocus(false);
657 EXPECT_EQ(v1, focus_manager->GetFocusedView());
659 EXPECT_TRUE(focus_manager->RotatePaneFocus(
660 FocusManager::kForward, FocusManager::kWrap));
661 EXPECT_EQ(v3, focus_manager->GetFocusedView());
662 focus_manager->AdvanceFocus(false);
663 EXPECT_EQ(v4, focus_manager->GetFocusedView());
664 focus_manager->AdvanceFocus(false);
665 EXPECT_EQ(v3, focus_manager->GetFocusedView());
667 EXPECT_TRUE(focus_manager->RotatePaneFocus(
668 FocusManager::kForward, FocusManager::kWrap));
669 EXPECT_EQ(v1, focus_manager->GetFocusedView());
671 // Advance backwards.
672 EXPECT_TRUE(focus_manager->RotatePaneFocus(
673 FocusManager::kBackward, FocusManager::kWrap));
674 EXPECT_EQ(v3, focus_manager->GetFocusedView());
676 EXPECT_TRUE(focus_manager->RotatePaneFocus(
677 FocusManager::kBackward, FocusManager::kWrap));
678 EXPECT_EQ(v1, focus_manager->GetFocusedView());
680 // Advance without wrap. When it gets to the end of the list of
681 // panes, RotatePaneFocus should return false but the current
682 // focused view shouldn't change.
683 EXPECT_TRUE(focus_manager->RotatePaneFocus(
684 FocusManager::kForward, FocusManager::kNoWrap));
685 EXPECT_EQ(v3, focus_manager->GetFocusedView());
687 EXPECT_FALSE(focus_manager->RotatePaneFocus(
688 FocusManager::kForward, FocusManager::kNoWrap));
689 EXPECT_EQ(v3, focus_manager->GetFocusedView());
692 // Verifies the stored focus view tracks the focused view.
693 TEST_F(FocusManagerTest, ImplicitlyStoresFocus) {
694 views::View* v1 = new View;
695 v1->SetFocusable(true);
696 GetContentsView()->AddChildView(v1);
698 views::View* v2 = new View;
699 v2->SetFocusable(true);
700 GetContentsView()->AddChildView(v2);
702 // Verify a focus request on |v1| implicitly updates the stored focus view.
703 v1->RequestFocus();
704 EXPECT_TRUE(v1->HasFocus());
705 EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView());
707 // Verify a focus request on |v2| implicitly updates the stored focus view.
708 v2->RequestFocus();
709 EXPECT_TRUE(v2->HasFocus());
710 EXPECT_EQ(v2, GetWidget()->GetFocusManager()->GetStoredFocusView());
713 namespace {
715 class FocusManagerArrowKeyTraversalTest : public FocusManagerTest {
716 public:
717 FocusManagerArrowKeyTraversalTest()
718 : previous_arrow_key_traversal_enabled_(false) {
720 ~FocusManagerArrowKeyTraversalTest() override {}
722 // FocusManagerTest overrides:
723 void SetUp() override {
724 FocusManagerTest::SetUp();
726 previous_arrow_key_traversal_enabled_ =
727 FocusManager::arrow_key_traversal_enabled();
729 void TearDown() override {
730 FocusManager::set_arrow_key_traversal_enabled(
731 previous_arrow_key_traversal_enabled_);
732 FocusManagerTest::TearDown();
735 private:
736 bool previous_arrow_key_traversal_enabled_;
738 DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest);
741 } // namespace
743 TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
744 FocusManager* focus_manager = GetFocusManager();
745 const ui::KeyEvent left_key(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE);
746 const ui::KeyEvent right_key(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE);
747 const ui::KeyEvent up_key(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE);
748 const ui::KeyEvent down_key(ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE);
750 std::vector<views::View*> v;
751 for (size_t i = 0; i < 2; ++i) {
752 views::View* view = new View;
753 view->SetFocusable(true);
754 GetContentsView()->AddChildView(view);
755 v.push_back(view);
758 // Arrow key traversal is off and arrow key does not change focus.
759 FocusManager::set_arrow_key_traversal_enabled(false);
760 v[0]->RequestFocus();
761 focus_manager->OnKeyEvent(right_key);
762 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
763 focus_manager->OnKeyEvent(left_key);
764 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
765 focus_manager->OnKeyEvent(down_key);
766 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
767 focus_manager->OnKeyEvent(up_key);
768 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
770 // Turn on arrow key traversal.
771 FocusManager::set_arrow_key_traversal_enabled(true);
772 v[0]->RequestFocus();
773 focus_manager->OnKeyEvent(right_key);
774 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
775 focus_manager->OnKeyEvent(left_key);
776 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
777 focus_manager->OnKeyEvent(down_key);
778 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
779 focus_manager->OnKeyEvent(up_key);
780 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
783 TEST_F(FocusManagerTest, StoreFocusedView) {
784 View view;
785 GetFocusManager()->SetFocusedView(&view);
786 GetFocusManager()->StoreFocusedView(false);
787 EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
788 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
789 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
791 // Repeat with |true|.
792 GetFocusManager()->SetFocusedView(&view);
793 GetFocusManager()->StoreFocusedView(true);
794 EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
795 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
796 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
799 namespace {
801 // Trivial WidgetDelegate implementation that allows setting return value of
802 // ShouldAdvanceFocusToTopLevelWidget().
803 class AdvanceFocusWidgetDelegate : public WidgetDelegate {
804 public:
805 explicit AdvanceFocusWidgetDelegate(Widget* widget)
806 : widget_(widget),
807 should_advance_focus_to_parent_(false) {}
808 ~AdvanceFocusWidgetDelegate() override {}
810 void set_should_advance_focus_to_parent(bool value) {
811 should_advance_focus_to_parent_ = value;
814 // WidgetDelegate overrides:
815 bool ShouldAdvanceFocusToTopLevelWidget() const override {
816 return should_advance_focus_to_parent_;
818 Widget* GetWidget() override { return widget_; }
819 const Widget* GetWidget() const override { return widget_; }
821 private:
822 Widget* widget_;
823 bool should_advance_focus_to_parent_;
825 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate);
828 } // namespace
830 // Verifies focus wrapping happens in the same widget.
831 TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
832 // Add |widget_view| as a child of the Widget.
833 View* widget_view = new View;
834 widget_view->SetFocusable(true);
835 widget_view->SetBounds(20, 0, 20, 20);
836 GetContentsView()->AddChildView(widget_view);
838 // Create a widget with two views, focus the second.
839 scoped_ptr<AdvanceFocusWidgetDelegate> delegate;
840 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
841 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
842 params.child = true;
843 params.bounds = gfx::Rect(10, 10, 100, 100);
844 params.parent = GetWidget()->GetNativeView();
845 Widget child_widget;
846 delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget));
847 params.delegate = delegate.get();
848 child_widget.Init(params);
849 View* view1 = new View;
850 view1->SetFocusable(true);
851 view1->SetBounds(0, 0, 20, 20);
852 View* view2 = new View;
853 view2->SetFocusable(true);
854 view2->SetBounds(20, 0, 20, 20);
855 child_widget.client_view()->AddChildView(view1);
856 child_widget.client_view()->AddChildView(view2);
857 child_widget.Show();
858 view2->RequestFocus();
859 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
861 // Advance focus backwards, which should focus the first.
862 GetFocusManager()->AdvanceFocus(false);
863 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
865 // Focus forward to |view2|.
866 GetFocusManager()->AdvanceFocus(true);
867 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
869 // And forward again, wrapping back to |view1|.
870 GetFocusManager()->AdvanceFocus(true);
871 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
873 // Allow focus to go to the parent, and focus backwards which should now move
874 // up |widget_view| (in the parent).
875 delegate->set_should_advance_focus_to_parent(true);
876 GetFocusManager()->AdvanceFocus(true);
877 EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView());
880 } // namespace views