GoogleURLTrackerInfoBarDelegate: Initialize uninitialized member in constructor.
[chromium-blink-merge.git] / ui / views / focus / focus_manager_unittest.cc
blob9bd988d4e0896d8adaa1886891094e59406e144f
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/aura/client/focus_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/base/accelerators/accelerator.h"
12 #include "ui/events/keycodes/keyboard_codes.h"
13 #include "ui/views/accessible_pane_view.h"
14 #include "ui/views/controls/button/label_button.h"
15 #include "ui/views/controls/textfield/textfield.h"
16 #include "ui/views/focus/focus_manager_factory.h"
17 #include "ui/views/focus/focus_manager_test.h"
18 #include "ui/views/focus/widget_focus_manager.h"
19 #include "ui/views/widget/widget.h"
21 namespace views {
23 enum FocusTestEventType {
24 ON_FOCUS = 0,
25 ON_BLUR
28 struct FocusTestEvent {
29 FocusTestEvent(FocusTestEventType type, int view_id)
30 : type(type),
31 view_id(view_id) {
34 FocusTestEventType type;
35 int view_id;
38 class SimpleTestView : public View {
39 public:
40 SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id)
41 : event_list_(event_list) {
42 SetFocusable(true);
43 set_id(view_id);
46 virtual void OnFocus() OVERRIDE {
47 event_list_->push_back(FocusTestEvent(ON_FOCUS, id()));
50 virtual void OnBlur() OVERRIDE {
51 event_list_->push_back(FocusTestEvent(ON_BLUR, id()));
54 private:
55 std::vector<FocusTestEvent>* event_list_;
58 // Tests that the appropriate Focus related methods are called when a View
59 // gets/loses focus.
60 TEST_F(FocusManagerTest, ViewFocusCallbacks) {
61 std::vector<FocusTestEvent> event_list;
62 const int kView1ID = 1;
63 const int kView2ID = 2;
65 SimpleTestView* view1 = new SimpleTestView(&event_list, kView1ID);
66 SimpleTestView* view2 = new SimpleTestView(&event_list, kView2ID);
67 GetContentsView()->AddChildView(view1);
68 GetContentsView()->AddChildView(view2);
70 view1->RequestFocus();
71 ASSERT_EQ(1, static_cast<int>(event_list.size()));
72 EXPECT_EQ(ON_FOCUS, event_list[0].type);
73 EXPECT_EQ(kView1ID, event_list[0].view_id);
75 event_list.clear();
76 view2->RequestFocus();
77 ASSERT_EQ(2, static_cast<int>(event_list.size()));
78 EXPECT_EQ(ON_BLUR, event_list[0].type);
79 EXPECT_EQ(kView1ID, event_list[0].view_id);
80 EXPECT_EQ(ON_FOCUS, event_list[1].type);
81 EXPECT_EQ(kView2ID, event_list[1].view_id);
83 event_list.clear();
84 GetFocusManager()->ClearFocus();
85 ASSERT_EQ(1, static_cast<int>(event_list.size()));
86 EXPECT_EQ(ON_BLUR, event_list[0].type);
87 EXPECT_EQ(kView2ID, event_list[0].view_id);
90 TEST_F(FocusManagerTest, FocusChangeListener) {
91 View* view1 = new View();
92 view1->SetFocusable(true);
93 View* view2 = new View();
94 view2->SetFocusable(true);
95 GetContentsView()->AddChildView(view1);
96 GetContentsView()->AddChildView(view2);
98 TestFocusChangeListener listener;
99 AddFocusChangeListener(&listener);
101 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
102 views::View* null_view = NULL;
104 view1->RequestFocus();
105 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
106 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view1));
107 listener.ClearFocusChanges();
109 view2->RequestFocus();
110 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
111 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2));
112 listener.ClearFocusChanges();
114 GetFocusManager()->ClearFocus();
115 ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
116 EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, null_view));
119 TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
120 TestWidgetFocusChangeListener widget_listener;
121 AddWidgetFocusChangeListener(&widget_listener);
123 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
124 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
125 params.bounds = gfx::Rect(10, 10, 100, 100);
126 params.parent = GetWidget()->GetNativeView();
128 scoped_ptr<Widget> widget1(new Widget);
129 widget1->Init(params);
130 widget1->Show();
132 scoped_ptr<Widget> widget2(new Widget);
133 widget2->Init(params);
134 widget2->Show();
136 widget_listener.ClearFocusChanges();
137 gfx::NativeView native_view1 = widget1->GetNativeView();
138 aura::client::GetFocusClient(native_view1)->FocusWindow(native_view1);
139 ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
140 EXPECT_EQ(native_view1, widget_listener.focus_changes()[0].second);
141 EXPECT_EQ(native_view1, widget_listener.focus_changes()[1].second);
143 widget_listener.ClearFocusChanges();
144 gfx::NativeView native_view2 = widget2->GetNativeView();
145 aura::client::GetFocusClient(native_view2)->FocusWindow(native_view2);
146 ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
147 EXPECT_EQ(NativeViewPair(native_view1, native_view2),
148 widget_listener.focus_changes()[0]);
149 EXPECT_EQ(NativeViewPair(native_view1, native_view2),
150 widget_listener.focus_changes()[1]);
153 // Counts accelerator calls.
154 class TestAcceleratorTarget : public ui::AcceleratorTarget {
155 public:
156 explicit TestAcceleratorTarget(bool process_accelerator)
157 : accelerator_count_(0),
158 process_accelerator_(process_accelerator),
159 can_handle_accelerators_(true) {}
161 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
162 ++accelerator_count_;
163 return process_accelerator_;
166 virtual bool CanHandleAccelerators() const OVERRIDE {
167 return can_handle_accelerators_;
170 int accelerator_count() const { return accelerator_count_; }
172 void set_can_handle_accelerators(bool can_handle_accelerators) {
173 can_handle_accelerators_ = can_handle_accelerators;
176 private:
177 int accelerator_count_; // number of times that the accelerator is activated
178 bool process_accelerator_; // return value of AcceleratorPressed
179 bool can_handle_accelerators_; // return value of CanHandleAccelerators
181 DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget);
184 TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
185 FocusManager* focus_manager = GetFocusManager();
186 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
187 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
189 TestAcceleratorTarget return_target(true);
190 TestAcceleratorTarget escape_target(true);
191 EXPECT_EQ(return_target.accelerator_count(), 0);
192 EXPECT_EQ(escape_target.accelerator_count(), 0);
193 EXPECT_EQ(NULL,
194 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
195 EXPECT_EQ(NULL,
196 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
198 // Register targets.
199 focus_manager->RegisterAccelerator(return_accelerator,
200 ui::AcceleratorManager::kNormalPriority,
201 &return_target);
202 focus_manager->RegisterAccelerator(escape_accelerator,
203 ui::AcceleratorManager::kNormalPriority,
204 &escape_target);
206 // Checks if the correct target is registered.
207 EXPECT_EQ(&return_target,
208 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
209 EXPECT_EQ(&escape_target,
210 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
212 // Hitting the return key.
213 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
214 EXPECT_EQ(return_target.accelerator_count(), 1);
215 EXPECT_EQ(escape_target.accelerator_count(), 0);
217 // Hitting the escape key.
218 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
219 EXPECT_EQ(return_target.accelerator_count(), 1);
220 EXPECT_EQ(escape_target.accelerator_count(), 1);
222 // Register another target for the return key.
223 TestAcceleratorTarget return_target2(true);
224 EXPECT_EQ(return_target2.accelerator_count(), 0);
225 focus_manager->RegisterAccelerator(return_accelerator,
226 ui::AcceleratorManager::kNormalPriority,
227 &return_target2);
228 EXPECT_EQ(&return_target2,
229 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
231 // Hitting the return key; return_target2 has the priority.
232 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
233 EXPECT_EQ(return_target.accelerator_count(), 1);
234 EXPECT_EQ(return_target2.accelerator_count(), 1);
236 // Register a target that does not process the accelerator event.
237 TestAcceleratorTarget return_target3(false);
238 EXPECT_EQ(return_target3.accelerator_count(), 0);
239 focus_manager->RegisterAccelerator(return_accelerator,
240 ui::AcceleratorManager::kNormalPriority,
241 &return_target3);
242 EXPECT_EQ(&return_target3,
243 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
245 // Hitting the return key.
246 // Since the event handler of return_target3 returns false, return_target2
247 // should be called too.
248 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
249 EXPECT_EQ(return_target.accelerator_count(), 1);
250 EXPECT_EQ(return_target2.accelerator_count(), 2);
251 EXPECT_EQ(return_target3.accelerator_count(), 1);
253 // Unregister return_target2.
254 focus_manager->UnregisterAccelerator(return_accelerator, &return_target2);
255 EXPECT_EQ(&return_target3,
256 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
258 // Hitting the return key. return_target3 and return_target should be called.
259 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
260 EXPECT_EQ(return_target.accelerator_count(), 2);
261 EXPECT_EQ(return_target2.accelerator_count(), 2);
262 EXPECT_EQ(return_target3.accelerator_count(), 2);
264 // Unregister targets.
265 focus_manager->UnregisterAccelerator(return_accelerator, &return_target);
266 focus_manager->UnregisterAccelerator(return_accelerator, &return_target3);
267 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target);
269 // Now there is no target registered.
270 EXPECT_EQ(NULL,
271 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
272 EXPECT_EQ(NULL,
273 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
275 // Hitting the return key and the escape key. Nothing should happen.
276 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
277 EXPECT_EQ(return_target.accelerator_count(), 2);
278 EXPECT_EQ(return_target2.accelerator_count(), 2);
279 EXPECT_EQ(return_target3.accelerator_count(), 2);
280 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
281 EXPECT_EQ(escape_target.accelerator_count(), 1);
284 TEST_F(FocusManagerTest, HighPriorityHandlers) {
285 FocusManager* focus_manager = GetFocusManager();
286 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
288 TestAcceleratorTarget escape_target_high(true);
289 TestAcceleratorTarget escape_target_normal(true);
290 EXPECT_EQ(escape_target_high.accelerator_count(), 0);
291 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
292 EXPECT_EQ(NULL,
293 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
294 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
296 // Register high priority target.
297 focus_manager->RegisterAccelerator(escape_accelerator,
298 ui::AcceleratorManager::kHighPriority,
299 &escape_target_high);
300 EXPECT_EQ(&escape_target_high,
301 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
302 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
304 // Hit the escape key.
305 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
306 EXPECT_EQ(escape_target_high.accelerator_count(), 1);
307 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
309 // Add a normal priority target and make sure it doesn't see the key.
310 focus_manager->RegisterAccelerator(escape_accelerator,
311 ui::AcceleratorManager::kNormalPriority,
312 &escape_target_normal);
314 // Checks if the correct target is registered (same as before, the high
315 // priority one).
316 EXPECT_EQ(&escape_target_high,
317 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
318 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
320 // Hit the escape key.
321 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
322 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
323 EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
325 // Unregister the high priority accelerator.
326 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
327 EXPECT_EQ(&escape_target_normal,
328 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
329 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
331 // Hit the escape key.
332 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
333 EXPECT_EQ(escape_target_high.accelerator_count(), 2);
334 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
336 // Add the high priority target back and make sure it starts seeing the key.
337 focus_manager->RegisterAccelerator(escape_accelerator,
338 ui::AcceleratorManager::kHighPriority,
339 &escape_target_high);
340 EXPECT_EQ(&escape_target_high,
341 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
342 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
344 // Hit the escape key.
345 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
346 EXPECT_EQ(escape_target_high.accelerator_count(), 3);
347 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
349 // Unregister the normal priority accelerator.
350 focus_manager->UnregisterAccelerator(
351 escape_accelerator, &escape_target_normal);
352 EXPECT_EQ(&escape_target_high,
353 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
354 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
356 // Hit the escape key.
357 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
358 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
359 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
361 // Unregister the high priority accelerator.
362 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
363 EXPECT_EQ(NULL,
364 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
365 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
367 // Hit the escape key (no change, no targets registered).
368 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
369 EXPECT_EQ(escape_target_high.accelerator_count(), 4);
370 EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
373 TEST_F(FocusManagerTest, CallsEnabledAcceleratorTargetsOnly) {
374 FocusManager* focus_manager = GetFocusManager();
375 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
377 TestAcceleratorTarget return_target1(true);
378 TestAcceleratorTarget return_target2(true);
380 focus_manager->RegisterAccelerator(return_accelerator,
381 ui::AcceleratorManager::kNormalPriority,
382 &return_target1);
383 focus_manager->RegisterAccelerator(return_accelerator,
384 ui::AcceleratorManager::kNormalPriority,
385 &return_target2);
386 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
387 EXPECT_EQ(0, return_target1.accelerator_count());
388 EXPECT_EQ(1, return_target2.accelerator_count());
390 // If CanHandleAccelerators() return false, FocusManager shouldn't call
391 // AcceleratorPressed().
392 return_target2.set_can_handle_accelerators(false);
393 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
394 EXPECT_EQ(1, return_target1.accelerator_count());
395 EXPECT_EQ(1, return_target2.accelerator_count());
397 // If no accelerator targets are enabled, ProcessAccelerator() should fail.
398 return_target1.set_can_handle_accelerators(false);
399 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
400 EXPECT_EQ(1, return_target1.accelerator_count());
401 EXPECT_EQ(1, return_target2.accelerator_count());
403 // Enabling the target again causes the accelerators to be processed again.
404 return_target1.set_can_handle_accelerators(true);
405 return_target2.set_can_handle_accelerators(true);
406 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
407 EXPECT_EQ(1, return_target1.accelerator_count());
408 EXPECT_EQ(2, return_target2.accelerator_count());
411 // Unregisters itself when its accelerator is invoked.
412 class SelfUnregisteringAcceleratorTarget : public ui::AcceleratorTarget {
413 public:
414 SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator,
415 FocusManager* focus_manager)
416 : accelerator_(accelerator),
417 focus_manager_(focus_manager),
418 accelerator_count_(0) {
421 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
422 ++accelerator_count_;
423 focus_manager_->UnregisterAccelerator(accelerator, this);
424 return true;
427 virtual bool CanHandleAccelerators() const OVERRIDE {
428 return true;
431 int accelerator_count() const { return accelerator_count_; }
433 private:
434 ui::Accelerator accelerator_;
435 FocusManager* focus_manager_;
436 int accelerator_count_;
438 DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget);
441 TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) {
442 FocusManager* focus_manager = GetFocusManager();
443 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
444 SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager);
445 EXPECT_EQ(target.accelerator_count(), 0);
446 EXPECT_EQ(NULL,
447 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
449 // Register the target.
450 focus_manager->RegisterAccelerator(return_accelerator,
451 ui::AcceleratorManager::kNormalPriority,
452 &target);
453 EXPECT_EQ(&target,
454 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
456 // Hitting the return key. The target will be unregistered.
457 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
458 EXPECT_EQ(target.accelerator_count(), 1);
459 EXPECT_EQ(NULL,
460 focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
462 // Hitting the return key again; nothing should happen.
463 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
464 EXPECT_EQ(target.accelerator_count(), 1);
467 class FocusManagerDtorTest : public FocusManagerTest {
468 protected:
469 typedef std::vector<std::string> DtorTrackVector;
471 class FocusManagerDtorTracked : public FocusManager {
472 public:
473 FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker)
474 : FocusManager(widget, NULL /* delegate */),
475 dtor_tracker_(dtor_tracker) {
478 virtual ~FocusManagerDtorTracked() {
479 dtor_tracker_->push_back("FocusManagerDtorTracked");
482 DtorTrackVector* dtor_tracker_;
484 private:
485 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked);
488 class TestFocusManagerFactory : public FocusManagerFactory {
489 public:
490 explicit TestFocusManagerFactory(DtorTrackVector* dtor_tracker)
491 : dtor_tracker_(dtor_tracker) {
494 virtual FocusManager* CreateFocusManager(Widget* widget,
495 bool desktop_widget) OVERRIDE {
496 return new FocusManagerDtorTracked(widget, dtor_tracker_);
499 private:
500 DtorTrackVector* dtor_tracker_;
501 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory);
504 class LabelButtonDtorTracked : public LabelButton {
505 public:
506 LabelButtonDtorTracked(const base::string16& text,
507 DtorTrackVector* dtor_tracker)
508 : LabelButton(NULL, text),
509 dtor_tracker_(dtor_tracker) {
510 SetStyle(STYLE_BUTTON);
512 virtual ~LabelButtonDtorTracked() {
513 dtor_tracker_->push_back("LabelButtonDtorTracked");
516 DtorTrackVector* dtor_tracker_;
519 class WindowDtorTracked : public Widget {
520 public:
521 explicit WindowDtorTracked(DtorTrackVector* dtor_tracker)
522 : dtor_tracker_(dtor_tracker) {
525 virtual ~WindowDtorTracked() {
526 dtor_tracker_->push_back("WindowDtorTracked");
529 DtorTrackVector* dtor_tracker_;
532 virtual void SetUp() {
533 ViewsTestBase::SetUp();
534 FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_));
535 // Create WindowDtorTracked that uses FocusManagerDtorTracked.
536 Widget* widget = new WindowDtorTracked(&dtor_tracker_);
537 Widget::InitParams params;
538 params.delegate = this;
539 params.bounds = gfx::Rect(0, 0, 100, 100);
540 widget->Init(params);
542 tracked_focus_manager_ =
543 static_cast<FocusManagerDtorTracked*>(GetFocusManager());
544 widget->Show();
547 virtual void TearDown() {
548 FocusManagerFactory::Install(NULL);
549 ViewsTestBase::TearDown();
552 FocusManager* tracked_focus_manager_;
553 DtorTrackVector dtor_tracker_;
556 namespace {
558 class FocusInAboutToRequestFocusFromTabTraversalView : public View {
559 public:
560 FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL) {}
562 void set_view_to_focus(View* view) { view_to_focus_ = view; }
564 virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE {
565 view_to_focus_->RequestFocus();
568 private:
569 views::View* view_to_focus_;
571 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView);
573 } // namespace
575 // Verifies a focus change done during a call to
576 // AboutToRequestFocusFromTabTraversal() is honored.
577 TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) {
578 // Create 3 views focuses the 3 and advances to the second. The 2nd views
579 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
580 views::View* v1 = new View;
581 v1->SetFocusable(true);
582 GetContentsView()->AddChildView(v1);
584 FocusInAboutToRequestFocusFromTabTraversalView* v2 =
585 new FocusInAboutToRequestFocusFromTabTraversalView;
586 v2->SetFocusable(true);
587 v2->set_view_to_focus(v1);
588 GetContentsView()->AddChildView(v2);
590 views::View* v3 = new View;
591 v3->SetFocusable(true);
592 GetContentsView()->AddChildView(v3);
594 v3->RequestFocus();
595 GetWidget()->GetFocusManager()->AdvanceFocus(true);
596 EXPECT_TRUE(v1->HasFocus());
599 TEST_F(FocusManagerTest, RotatePaneFocus) {
600 views::AccessiblePaneView* pane1 = new AccessiblePaneView();
601 GetContentsView()->AddChildView(pane1);
603 views::View* v1 = new View;
604 v1->SetFocusable(true);
605 pane1->AddChildView(v1);
607 views::View* v2 = new View;
608 v2->SetFocusable(true);
609 pane1->AddChildView(v2);
611 views::AccessiblePaneView* pane2 = new AccessiblePaneView();
612 GetContentsView()->AddChildView(pane2);
614 views::View* v3 = new View;
615 v3->SetFocusable(true);
616 pane2->AddChildView(v3);
618 views::View* v4 = new View;
619 v4->SetFocusable(true);
620 pane2->AddChildView(v4);
622 std::vector<views::View*> panes;
623 panes.push_back(pane1);
624 panes.push_back(pane2);
625 SetAccessiblePanes(panes);
627 FocusManager* focus_manager = GetWidget()->GetFocusManager();
629 // Advance forwards. Focus should stay trapped within each pane.
630 EXPECT_TRUE(focus_manager->RotatePaneFocus(
631 FocusManager::kForward, FocusManager::kWrap));
632 EXPECT_EQ(v1, focus_manager->GetFocusedView());
633 focus_manager->AdvanceFocus(false);
634 EXPECT_EQ(v2, focus_manager->GetFocusedView());
635 focus_manager->AdvanceFocus(false);
636 EXPECT_EQ(v1, focus_manager->GetFocusedView());
638 EXPECT_TRUE(focus_manager->RotatePaneFocus(
639 FocusManager::kForward, FocusManager::kWrap));
640 EXPECT_EQ(v3, focus_manager->GetFocusedView());
641 focus_manager->AdvanceFocus(false);
642 EXPECT_EQ(v4, focus_manager->GetFocusedView());
643 focus_manager->AdvanceFocus(false);
644 EXPECT_EQ(v3, focus_manager->GetFocusedView());
646 EXPECT_TRUE(focus_manager->RotatePaneFocus(
647 FocusManager::kForward, FocusManager::kWrap));
648 EXPECT_EQ(v1, focus_manager->GetFocusedView());
650 // Advance backwards.
651 EXPECT_TRUE(focus_manager->RotatePaneFocus(
652 FocusManager::kBackward, FocusManager::kWrap));
653 EXPECT_EQ(v3, focus_manager->GetFocusedView());
655 EXPECT_TRUE(focus_manager->RotatePaneFocus(
656 FocusManager::kBackward, FocusManager::kWrap));
657 EXPECT_EQ(v1, focus_manager->GetFocusedView());
659 // Advance without wrap. When it gets to the end of the list of
660 // panes, RotatePaneFocus should return false but the current
661 // focused view shouldn't change.
662 EXPECT_TRUE(focus_manager->RotatePaneFocus(
663 FocusManager::kForward, FocusManager::kNoWrap));
664 EXPECT_EQ(v3, focus_manager->GetFocusedView());
666 EXPECT_FALSE(focus_manager->RotatePaneFocus(
667 FocusManager::kForward, FocusManager::kNoWrap));
668 EXPECT_EQ(v3, focus_manager->GetFocusedView());
671 // Verifies the stored focus view tracks the focused view.
672 TEST_F(FocusManagerTest, ImplicitlyStoresFocus) {
673 views::View* v1 = new View;
674 v1->SetFocusable(true);
675 GetContentsView()->AddChildView(v1);
677 views::View* v2 = new View;
678 v2->SetFocusable(true);
679 GetContentsView()->AddChildView(v2);
681 // Verify a focus request on |v1| implicitly updates the stored focus view.
682 v1->RequestFocus();
683 EXPECT_TRUE(v1->HasFocus());
684 EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView());
686 // Verify a focus request on |v2| implicitly updates the stored focus view.
687 v2->RequestFocus();
688 EXPECT_TRUE(v2->HasFocus());
689 EXPECT_EQ(v2, GetWidget()->GetFocusManager()->GetStoredFocusView());
692 namespace {
694 class FocusManagerArrowKeyTraversalTest : public FocusManagerTest {
695 public:
696 FocusManagerArrowKeyTraversalTest()
697 : previous_arrow_key_traversal_enabled_(false) {
699 virtual ~FocusManagerArrowKeyTraversalTest() {}
701 // FocusManagerTest overrides:
702 virtual void SetUp() OVERRIDE {
703 FocusManagerTest::SetUp();
705 previous_arrow_key_traversal_enabled_ =
706 FocusManager::arrow_key_traversal_enabled();
708 virtual void TearDown() OVERRIDE {
709 FocusManager::set_arrow_key_traversal_enabled(
710 previous_arrow_key_traversal_enabled_);
711 FocusManagerTest::TearDown();
714 private:
715 bool previous_arrow_key_traversal_enabled_;
717 DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest);
720 } // namespace
722 TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
723 FocusManager* focus_manager = GetFocusManager();
724 const ui::KeyEvent left_key(
725 ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE, false);
726 const ui::KeyEvent right_key(
727 ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE, false);
728 const ui::KeyEvent up_key(
729 ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE, false);
730 const ui::KeyEvent down_key(
731 ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE, false);
733 std::vector<views::View*> v;
734 for (size_t i = 0; i < 2; ++i) {
735 views::View* view = new View;
736 view->SetFocusable(true);
737 GetContentsView()->AddChildView(view);
738 v.push_back(view);
741 // Arrow key traversal is off and arrow key does not change focus.
742 FocusManager::set_arrow_key_traversal_enabled(false);
743 v[0]->RequestFocus();
744 focus_manager->OnKeyEvent(right_key);
745 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
746 focus_manager->OnKeyEvent(left_key);
747 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
748 focus_manager->OnKeyEvent(down_key);
749 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
750 focus_manager->OnKeyEvent(up_key);
751 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
753 // Turn on arrow key traversal.
754 FocusManager::set_arrow_key_traversal_enabled(true);
755 v[0]->RequestFocus();
756 focus_manager->OnKeyEvent(right_key);
757 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
758 focus_manager->OnKeyEvent(left_key);
759 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
760 focus_manager->OnKeyEvent(down_key);
761 EXPECT_EQ(v[1], focus_manager->GetFocusedView());
762 focus_manager->OnKeyEvent(up_key);
763 EXPECT_EQ(v[0], focus_manager->GetFocusedView());
766 TEST_F(FocusManagerTest, StoreFocusedView) {
767 View view;
768 GetFocusManager()->SetFocusedView(&view);
769 GetFocusManager()->StoreFocusedView(false);
770 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
771 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
773 // Repeat with |true|.
774 GetFocusManager()->SetFocusedView(&view);
775 GetFocusManager()->StoreFocusedView(true);
776 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
777 EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
780 namespace {
782 // Trivial WidgetDelegate implementation that allows setting return value of
783 // ShouldAdvanceFocusToTopLevelWidget().
784 class AdvanceFocusWidgetDelegate : public WidgetDelegate {
785 public:
786 explicit AdvanceFocusWidgetDelegate(Widget* widget)
787 : widget_(widget),
788 should_advance_focus_to_parent_(false) {}
789 virtual ~AdvanceFocusWidgetDelegate() {}
791 void set_should_advance_focus_to_parent(bool value) {
792 should_advance_focus_to_parent_ = value;
795 // WidgetDelegate overrides:
796 virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE {
797 return should_advance_focus_to_parent_;
799 virtual Widget* GetWidget() OVERRIDE { return widget_; }
800 virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
802 private:
803 Widget* widget_;
804 bool should_advance_focus_to_parent_;
806 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate);
809 } // namespace
811 // Verifies focus wrapping happens in the same widget.
812 TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
813 // Add |widget_view| as a child of the Widget.
814 View* widget_view = new View;
815 widget_view->SetFocusable(true);
816 widget_view->SetBounds(20, 0, 20, 20);
817 GetContentsView()->AddChildView(widget_view);
819 // Create a widget with two views, focus the second.
820 scoped_ptr<AdvanceFocusWidgetDelegate> delegate;
821 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
822 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
823 params.child = true;
824 params.bounds = gfx::Rect(10, 10, 100, 100);
825 params.parent = GetWidget()->GetNativeView();
826 Widget child_widget;
827 delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget));
828 params.delegate = delegate.get();
829 child_widget.Init(params);
830 View* view1 = new View;
831 view1->SetFocusable(true);
832 view1->SetBounds(0, 0, 20, 20);
833 View* view2 = new View;
834 view2->SetFocusable(true);
835 view2->SetBounds(20, 0, 20, 20);
836 child_widget.client_view()->AddChildView(view1);
837 child_widget.client_view()->AddChildView(view2);
838 child_widget.Show();
839 view2->RequestFocus();
840 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
842 // Advance focus backwards, which should focus the first.
843 GetFocusManager()->AdvanceFocus(false);
844 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
846 // Focus forward to |view2|.
847 GetFocusManager()->AdvanceFocus(true);
848 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
850 // And forward again, wrapping back to |view1|.
851 GetFocusManager()->AdvanceFocus(true);
852 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
854 // Allow focus to go to the parent, and focus backwards which should now move
855 // up |widget_view| (in the parent).
856 delegate->set_should_advance_focus_to_parent(true);
857 GetFocusManager()->AdvanceFocus(true);
858 EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView());
861 } // namespace views