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"
10 #include "base/command_line.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "ui/aura/client/focus_client.h"
13 #include "ui/aura/window.h"
14 #include "ui/base/accelerators/accelerator.h"
15 #include "ui/base/ime/dummy_text_input_client.h"
16 #include "ui/base/ime/text_input_focus_manager.h"
17 #include "ui/base/ui_base_switches.h"
18 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/views/accessible_pane_view.h"
20 #include "ui/views/controls/button/label_button.h"
21 #include "ui/views/focus/focus_manager_factory.h"
22 #include "ui/views/focus/widget_focus_manager.h"
23 #include "ui/views/test/focus_manager_test.h"
24 #include "ui/views/widget/widget.h"
28 enum FocusTestEventType
{
33 struct FocusTestEvent
{
34 FocusTestEvent(FocusTestEventType type
, int view_id
)
39 FocusTestEventType type
;
43 class SimpleTestView
: public View
{
45 SimpleTestView(std::vector
<FocusTestEvent
>* event_list
, int view_id
)
46 : event_list_(event_list
) {
51 virtual void OnFocus() OVERRIDE
{
52 event_list_
->push_back(FocusTestEvent(ON_FOCUS
, id()));
55 virtual void OnBlur() OVERRIDE
{
56 event_list_
->push_back(FocusTestEvent(ON_BLUR
, id()));
60 std::vector
<FocusTestEvent
>* event_list_
;
62 DISALLOW_COPY_AND_ASSIGN(SimpleTestView
);
65 // Tests that the appropriate Focus related methods are called when a View
67 TEST_F(FocusManagerTest
, ViewFocusCallbacks
) {
68 std::vector
<FocusTestEvent
> event_list
;
69 const int kView1ID
= 1;
70 const int kView2ID
= 2;
72 SimpleTestView
* view1
= new SimpleTestView(&event_list
, kView1ID
);
73 SimpleTestView
* view2
= new SimpleTestView(&event_list
, kView2ID
);
74 GetContentsView()->AddChildView(view1
);
75 GetContentsView()->AddChildView(view2
);
77 view1
->RequestFocus();
78 ASSERT_EQ(1, static_cast<int>(event_list
.size()));
79 EXPECT_EQ(ON_FOCUS
, event_list
[0].type
);
80 EXPECT_EQ(kView1ID
, event_list
[0].view_id
);
83 view2
->RequestFocus();
84 ASSERT_EQ(2, static_cast<int>(event_list
.size()));
85 EXPECT_EQ(ON_BLUR
, event_list
[0].type
);
86 EXPECT_EQ(kView1ID
, event_list
[0].view_id
);
87 EXPECT_EQ(ON_FOCUS
, event_list
[1].type
);
88 EXPECT_EQ(kView2ID
, event_list
[1].view_id
);
91 GetFocusManager()->ClearFocus();
92 ASSERT_EQ(1, static_cast<int>(event_list
.size()));
93 EXPECT_EQ(ON_BLUR
, event_list
[0].type
);
94 EXPECT_EQ(kView2ID
, event_list
[0].view_id
);
97 TEST_F(FocusManagerTest
, FocusChangeListener
) {
98 View
* view1
= new View();
99 view1
->SetFocusable(true);
100 View
* view2
= new View();
101 view2
->SetFocusable(true);
102 GetContentsView()->AddChildView(view1
);
103 GetContentsView()->AddChildView(view2
);
105 TestFocusChangeListener listener
;
106 AddFocusChangeListener(&listener
);
108 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
109 views::View
* null_view
= NULL
;
111 view1
->RequestFocus();
112 ASSERT_EQ(1, static_cast<int>(listener
.focus_changes().size()));
113 EXPECT_TRUE(listener
.focus_changes()[0] == ViewPair(null_view
, view1
));
114 listener
.ClearFocusChanges();
116 view2
->RequestFocus();
117 ASSERT_EQ(1, static_cast<int>(listener
.focus_changes().size()));
118 EXPECT_TRUE(listener
.focus_changes()[0] == ViewPair(view1
, view2
));
119 listener
.ClearFocusChanges();
121 GetFocusManager()->ClearFocus();
122 ASSERT_EQ(1, static_cast<int>(listener
.focus_changes().size()));
123 EXPECT_TRUE(listener
.focus_changes()[0] == ViewPair(view2
, null_view
));
126 TEST_F(FocusManagerTest
, WidgetFocusChangeListener
) {
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
);
139 scoped_ptr
<Widget
> widget2(new Widget
);
140 widget2
->Init(params
);
143 widget_listener
.ClearFocusChanges();
144 gfx::NativeView native_view1
= widget1
->GetNativeView();
145 aura::client::GetFocusClient(native_view1
)->FocusWindow(native_view1
);
146 ASSERT_EQ(2, static_cast<int>(widget_listener
.focus_changes().size()));
147 EXPECT_EQ(native_view1
, widget_listener
.focus_changes()[0].second
);
148 EXPECT_EQ(native_view1
, widget_listener
.focus_changes()[1].second
);
150 widget_listener
.ClearFocusChanges();
151 gfx::NativeView native_view2
= widget2
->GetNativeView();
152 aura::client::GetFocusClient(native_view2
)->FocusWindow(native_view2
);
153 ASSERT_EQ(2, static_cast<int>(widget_listener
.focus_changes().size()));
154 EXPECT_EQ(NativeViewPair(native_view1
, native_view2
),
155 widget_listener
.focus_changes()[0]);
156 EXPECT_EQ(NativeViewPair(native_view1
, native_view2
),
157 widget_listener
.focus_changes()[1]);
160 // Counts accelerator calls.
161 class TestAcceleratorTarget
: public ui::AcceleratorTarget
{
163 explicit TestAcceleratorTarget(bool process_accelerator
)
164 : accelerator_count_(0),
165 process_accelerator_(process_accelerator
),
166 can_handle_accelerators_(true) {}
168 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
{
169 ++accelerator_count_
;
170 return process_accelerator_
;
173 virtual bool CanHandleAccelerators() const OVERRIDE
{
174 return can_handle_accelerators_
;
177 int accelerator_count() const { return accelerator_count_
; }
179 void set_can_handle_accelerators(bool can_handle_accelerators
) {
180 can_handle_accelerators_
= can_handle_accelerators
;
184 int accelerator_count_
; // number of times that the accelerator is activated
185 bool process_accelerator_
; // return value of AcceleratorPressed
186 bool can_handle_accelerators_
; // return value of CanHandleAccelerators
188 DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget
);
191 TEST_F(FocusManagerTest
, CallsNormalAcceleratorTarget
) {
192 FocusManager
* focus_manager
= GetFocusManager();
193 ui::Accelerator
return_accelerator(ui::VKEY_RETURN
, ui::EF_NONE
);
194 ui::Accelerator
escape_accelerator(ui::VKEY_ESCAPE
, ui::EF_NONE
);
196 TestAcceleratorTarget
return_target(true);
197 TestAcceleratorTarget
escape_target(true);
198 EXPECT_EQ(return_target
.accelerator_count(), 0);
199 EXPECT_EQ(escape_target
.accelerator_count(), 0);
201 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
203 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
206 focus_manager
->RegisterAccelerator(return_accelerator
,
207 ui::AcceleratorManager::kNormalPriority
,
209 focus_manager
->RegisterAccelerator(escape_accelerator
,
210 ui::AcceleratorManager::kNormalPriority
,
213 // Checks if the correct target is registered.
214 EXPECT_EQ(&return_target
,
215 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
216 EXPECT_EQ(&escape_target
,
217 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
219 // Hitting the return key.
220 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
221 EXPECT_EQ(return_target
.accelerator_count(), 1);
222 EXPECT_EQ(escape_target
.accelerator_count(), 0);
224 // Hitting the escape key.
225 EXPECT_TRUE(focus_manager
->ProcessAccelerator(escape_accelerator
));
226 EXPECT_EQ(return_target
.accelerator_count(), 1);
227 EXPECT_EQ(escape_target
.accelerator_count(), 1);
229 // Register another target for the return key.
230 TestAcceleratorTarget
return_target2(true);
231 EXPECT_EQ(return_target2
.accelerator_count(), 0);
232 focus_manager
->RegisterAccelerator(return_accelerator
,
233 ui::AcceleratorManager::kNormalPriority
,
235 EXPECT_EQ(&return_target2
,
236 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
238 // Hitting the return key; return_target2 has the priority.
239 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
240 EXPECT_EQ(return_target
.accelerator_count(), 1);
241 EXPECT_EQ(return_target2
.accelerator_count(), 1);
243 // Register a target that does not process the accelerator event.
244 TestAcceleratorTarget
return_target3(false);
245 EXPECT_EQ(return_target3
.accelerator_count(), 0);
246 focus_manager
->RegisterAccelerator(return_accelerator
,
247 ui::AcceleratorManager::kNormalPriority
,
249 EXPECT_EQ(&return_target3
,
250 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
252 // Hitting the return key.
253 // Since the event handler of return_target3 returns false, return_target2
254 // should be called too.
255 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
256 EXPECT_EQ(return_target
.accelerator_count(), 1);
257 EXPECT_EQ(return_target2
.accelerator_count(), 2);
258 EXPECT_EQ(return_target3
.accelerator_count(), 1);
260 // Unregister return_target2.
261 focus_manager
->UnregisterAccelerator(return_accelerator
, &return_target2
);
262 EXPECT_EQ(&return_target3
,
263 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
265 // Hitting the return key. return_target3 and return_target should be called.
266 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
267 EXPECT_EQ(return_target
.accelerator_count(), 2);
268 EXPECT_EQ(return_target2
.accelerator_count(), 2);
269 EXPECT_EQ(return_target3
.accelerator_count(), 2);
271 // Unregister targets.
272 focus_manager
->UnregisterAccelerator(return_accelerator
, &return_target
);
273 focus_manager
->UnregisterAccelerator(return_accelerator
, &return_target3
);
274 focus_manager
->UnregisterAccelerator(escape_accelerator
, &escape_target
);
276 // Now there is no target registered.
278 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
280 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
282 // Hitting the return key and the escape key. Nothing should happen.
283 EXPECT_FALSE(focus_manager
->ProcessAccelerator(return_accelerator
));
284 EXPECT_EQ(return_target
.accelerator_count(), 2);
285 EXPECT_EQ(return_target2
.accelerator_count(), 2);
286 EXPECT_EQ(return_target3
.accelerator_count(), 2);
287 EXPECT_FALSE(focus_manager
->ProcessAccelerator(escape_accelerator
));
288 EXPECT_EQ(escape_target
.accelerator_count(), 1);
291 TEST_F(FocusManagerTest
, HighPriorityHandlers
) {
292 FocusManager
* focus_manager
= GetFocusManager();
293 ui::Accelerator
escape_accelerator(ui::VKEY_ESCAPE
, ui::EF_NONE
);
295 TestAcceleratorTarget
escape_target_high(true);
296 TestAcceleratorTarget
escape_target_normal(true);
297 EXPECT_EQ(escape_target_high
.accelerator_count(), 0);
298 EXPECT_EQ(escape_target_normal
.accelerator_count(), 0);
300 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
301 EXPECT_FALSE(focus_manager
->HasPriorityHandler(escape_accelerator
));
303 // Register high priority target.
304 focus_manager
->RegisterAccelerator(escape_accelerator
,
305 ui::AcceleratorManager::kHighPriority
,
306 &escape_target_high
);
307 EXPECT_EQ(&escape_target_high
,
308 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
309 EXPECT_TRUE(focus_manager
->HasPriorityHandler(escape_accelerator
));
311 // Hit the escape key.
312 EXPECT_TRUE(focus_manager
->ProcessAccelerator(escape_accelerator
));
313 EXPECT_EQ(escape_target_high
.accelerator_count(), 1);
314 EXPECT_EQ(escape_target_normal
.accelerator_count(), 0);
316 // Add a normal priority target and make sure it doesn't see the key.
317 focus_manager
->RegisterAccelerator(escape_accelerator
,
318 ui::AcceleratorManager::kNormalPriority
,
319 &escape_target_normal
);
321 // Checks if the correct target is registered (same as before, the high
323 EXPECT_EQ(&escape_target_high
,
324 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
325 EXPECT_TRUE(focus_manager
->HasPriorityHandler(escape_accelerator
));
327 // Hit the escape key.
328 EXPECT_TRUE(focus_manager
->ProcessAccelerator(escape_accelerator
));
329 EXPECT_EQ(escape_target_high
.accelerator_count(), 2);
330 EXPECT_EQ(escape_target_normal
.accelerator_count(), 0);
332 // Unregister the high priority accelerator.
333 focus_manager
->UnregisterAccelerator(escape_accelerator
, &escape_target_high
);
334 EXPECT_EQ(&escape_target_normal
,
335 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
336 EXPECT_FALSE(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(), 2);
341 EXPECT_EQ(escape_target_normal
.accelerator_count(), 1);
343 // Add the high priority target back and make sure it starts seeing the key.
344 focus_manager
->RegisterAccelerator(escape_accelerator
,
345 ui::AcceleratorManager::kHighPriority
,
346 &escape_target_high
);
347 EXPECT_EQ(&escape_target_high
,
348 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
349 EXPECT_TRUE(focus_manager
->HasPriorityHandler(escape_accelerator
));
351 // Hit the escape key.
352 EXPECT_TRUE(focus_manager
->ProcessAccelerator(escape_accelerator
));
353 EXPECT_EQ(escape_target_high
.accelerator_count(), 3);
354 EXPECT_EQ(escape_target_normal
.accelerator_count(), 1);
356 // Unregister the normal priority accelerator.
357 focus_manager
->UnregisterAccelerator(
358 escape_accelerator
, &escape_target_normal
);
359 EXPECT_EQ(&escape_target_high
,
360 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
361 EXPECT_TRUE(focus_manager
->HasPriorityHandler(escape_accelerator
));
363 // Hit the escape key.
364 EXPECT_TRUE(focus_manager
->ProcessAccelerator(escape_accelerator
));
365 EXPECT_EQ(escape_target_high
.accelerator_count(), 4);
366 EXPECT_EQ(escape_target_normal
.accelerator_count(), 1);
368 // Unregister the high priority accelerator.
369 focus_manager
->UnregisterAccelerator(escape_accelerator
, &escape_target_high
);
371 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
372 EXPECT_FALSE(focus_manager
->HasPriorityHandler(escape_accelerator
));
374 // Hit the escape key (no change, no targets registered).
375 EXPECT_FALSE(focus_manager
->ProcessAccelerator(escape_accelerator
));
376 EXPECT_EQ(escape_target_high
.accelerator_count(), 4);
377 EXPECT_EQ(escape_target_normal
.accelerator_count(), 1);
380 TEST_F(FocusManagerTest
, CallsEnabledAcceleratorTargetsOnly
) {
381 FocusManager
* focus_manager
= GetFocusManager();
382 ui::Accelerator
return_accelerator(ui::VKEY_RETURN
, ui::EF_NONE
);
384 TestAcceleratorTarget
return_target1(true);
385 TestAcceleratorTarget
return_target2(true);
387 focus_manager
->RegisterAccelerator(return_accelerator
,
388 ui::AcceleratorManager::kNormalPriority
,
390 focus_manager
->RegisterAccelerator(return_accelerator
,
391 ui::AcceleratorManager::kNormalPriority
,
393 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
394 EXPECT_EQ(0, return_target1
.accelerator_count());
395 EXPECT_EQ(1, return_target2
.accelerator_count());
397 // If CanHandleAccelerators() return false, FocusManager shouldn't call
398 // AcceleratorPressed().
399 return_target2
.set_can_handle_accelerators(false);
400 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
401 EXPECT_EQ(1, return_target1
.accelerator_count());
402 EXPECT_EQ(1, return_target2
.accelerator_count());
404 // If no accelerator targets are enabled, ProcessAccelerator() should fail.
405 return_target1
.set_can_handle_accelerators(false);
406 EXPECT_FALSE(focus_manager
->ProcessAccelerator(return_accelerator
));
407 EXPECT_EQ(1, return_target1
.accelerator_count());
408 EXPECT_EQ(1, return_target2
.accelerator_count());
410 // Enabling the target again causes the accelerators to be processed again.
411 return_target1
.set_can_handle_accelerators(true);
412 return_target2
.set_can_handle_accelerators(true);
413 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
414 EXPECT_EQ(1, return_target1
.accelerator_count());
415 EXPECT_EQ(2, return_target2
.accelerator_count());
418 // Unregisters itself when its accelerator is invoked.
419 class SelfUnregisteringAcceleratorTarget
: public ui::AcceleratorTarget
{
421 SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator
,
422 FocusManager
* focus_manager
)
423 : accelerator_(accelerator
),
424 focus_manager_(focus_manager
),
425 accelerator_count_(0) {
428 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
{
429 ++accelerator_count_
;
430 focus_manager_
->UnregisterAccelerator(accelerator
, this);
434 virtual bool CanHandleAccelerators() const OVERRIDE
{
438 int accelerator_count() const { return accelerator_count_
; }
441 ui::Accelerator accelerator_
;
442 FocusManager
* focus_manager_
;
443 int accelerator_count_
;
445 DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget
);
448 TEST_F(FocusManagerTest
, CallsSelfDeletingAcceleratorTarget
) {
449 FocusManager
* focus_manager
= GetFocusManager();
450 ui::Accelerator
return_accelerator(ui::VKEY_RETURN
, ui::EF_NONE
);
451 SelfUnregisteringAcceleratorTarget
target(return_accelerator
, focus_manager
);
452 EXPECT_EQ(target
.accelerator_count(), 0);
454 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
456 // Register the target.
457 focus_manager
->RegisterAccelerator(return_accelerator
,
458 ui::AcceleratorManager::kNormalPriority
,
461 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
463 // Hitting the return key. The target will be unregistered.
464 EXPECT_TRUE(focus_manager
->ProcessAccelerator(return_accelerator
));
465 EXPECT_EQ(target
.accelerator_count(), 1);
467 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
469 // Hitting the return key again; nothing should happen.
470 EXPECT_FALSE(focus_manager
->ProcessAccelerator(return_accelerator
));
471 EXPECT_EQ(target
.accelerator_count(), 1);
474 class FocusManagerDtorTest
: public FocusManagerTest
{
476 typedef std::vector
<std::string
> DtorTrackVector
;
478 class FocusManagerDtorTracked
: public FocusManager
{
480 FocusManagerDtorTracked(Widget
* widget
, DtorTrackVector
* dtor_tracker
)
481 : FocusManager(widget
, NULL
/* delegate */),
482 dtor_tracker_(dtor_tracker
) {
485 virtual ~FocusManagerDtorTracked() {
486 dtor_tracker_
->push_back("FocusManagerDtorTracked");
489 DtorTrackVector
* dtor_tracker_
;
492 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked
);
495 class TestFocusManagerFactory
: public FocusManagerFactory
{
497 explicit TestFocusManagerFactory(DtorTrackVector
* dtor_tracker
)
498 : dtor_tracker_(dtor_tracker
) {
501 virtual FocusManager
* CreateFocusManager(Widget
* widget
,
502 bool desktop_widget
) OVERRIDE
{
503 return new FocusManagerDtorTracked(widget
, dtor_tracker_
);
507 DtorTrackVector
* dtor_tracker_
;
508 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory
);
511 class LabelButtonDtorTracked
: public LabelButton
{
513 LabelButtonDtorTracked(const base::string16
& text
,
514 DtorTrackVector
* dtor_tracker
)
515 : LabelButton(NULL
, text
),
516 dtor_tracker_(dtor_tracker
) {
517 SetStyle(STYLE_BUTTON
);
519 virtual ~LabelButtonDtorTracked() {
520 dtor_tracker_
->push_back("LabelButtonDtorTracked");
523 DtorTrackVector
* dtor_tracker_
;
526 class WindowDtorTracked
: public Widget
{
528 explicit WindowDtorTracked(DtorTrackVector
* dtor_tracker
)
529 : dtor_tracker_(dtor_tracker
) {
532 virtual ~WindowDtorTracked() {
533 dtor_tracker_
->push_back("WindowDtorTracked");
536 DtorTrackVector
* dtor_tracker_
;
539 virtual void SetUp() {
540 ViewsTestBase::SetUp();
541 FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_
));
542 // Create WindowDtorTracked that uses FocusManagerDtorTracked.
543 Widget
* widget
= new WindowDtorTracked(&dtor_tracker_
);
544 Widget::InitParams params
;
545 params
.delegate
= this;
546 params
.bounds
= gfx::Rect(0, 0, 100, 100);
547 widget
->Init(params
);
549 tracked_focus_manager_
=
550 static_cast<FocusManagerDtorTracked
*>(GetFocusManager());
554 virtual void TearDown() {
555 FocusManagerFactory::Install(NULL
);
556 ViewsTestBase::TearDown();
559 FocusManager
* tracked_focus_manager_
;
560 DtorTrackVector dtor_tracker_
;
565 class FocusInAboutToRequestFocusFromTabTraversalView
: public View
{
567 FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL
) {}
569 void set_view_to_focus(View
* view
) { view_to_focus_
= view
; }
571 virtual void AboutToRequestFocusFromTabTraversal(bool reverse
) OVERRIDE
{
572 view_to_focus_
->RequestFocus();
576 views::View
* view_to_focus_
;
578 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView
);
582 // Verifies a focus change done during a call to
583 // AboutToRequestFocusFromTabTraversal() is honored.
584 TEST_F(FocusManagerTest
, FocusInAboutToRequestFocusFromTabTraversal
) {
585 // Create 3 views focuses the 3 and advances to the second. The 2nd views
586 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
587 views::View
* v1
= new View
;
588 v1
->SetFocusable(true);
589 GetContentsView()->AddChildView(v1
);
591 FocusInAboutToRequestFocusFromTabTraversalView
* v2
=
592 new FocusInAboutToRequestFocusFromTabTraversalView
;
593 v2
->SetFocusable(true);
594 v2
->set_view_to_focus(v1
);
595 GetContentsView()->AddChildView(v2
);
597 views::View
* v3
= new View
;
598 v3
->SetFocusable(true);
599 GetContentsView()->AddChildView(v3
);
602 GetWidget()->GetFocusManager()->AdvanceFocus(true);
603 EXPECT_TRUE(v1
->HasFocus());
606 TEST_F(FocusManagerTest
, RotatePaneFocus
) {
607 views::AccessiblePaneView
* pane1
= new AccessiblePaneView();
608 GetContentsView()->AddChildView(pane1
);
610 views::View
* v1
= new View
;
611 v1
->SetFocusable(true);
612 pane1
->AddChildView(v1
);
614 views::View
* v2
= new View
;
615 v2
->SetFocusable(true);
616 pane1
->AddChildView(v2
);
618 views::AccessiblePaneView
* pane2
= new AccessiblePaneView();
619 GetContentsView()->AddChildView(pane2
);
621 views::View
* v3
= new View
;
622 v3
->SetFocusable(true);
623 pane2
->AddChildView(v3
);
625 views::View
* v4
= new View
;
626 v4
->SetFocusable(true);
627 pane2
->AddChildView(v4
);
629 std::vector
<views::View
*> panes
;
630 panes
.push_back(pane1
);
631 panes
.push_back(pane2
);
632 SetAccessiblePanes(panes
);
634 FocusManager
* focus_manager
= GetWidget()->GetFocusManager();
636 // Advance forwards. Focus should stay trapped within each pane.
637 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
638 FocusManager::kForward
, FocusManager::kWrap
));
639 EXPECT_EQ(v1
, focus_manager
->GetFocusedView());
640 focus_manager
->AdvanceFocus(false);
641 EXPECT_EQ(v2
, focus_manager
->GetFocusedView());
642 focus_manager
->AdvanceFocus(false);
643 EXPECT_EQ(v1
, focus_manager
->GetFocusedView());
645 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
646 FocusManager::kForward
, FocusManager::kWrap
));
647 EXPECT_EQ(v3
, focus_manager
->GetFocusedView());
648 focus_manager
->AdvanceFocus(false);
649 EXPECT_EQ(v4
, focus_manager
->GetFocusedView());
650 focus_manager
->AdvanceFocus(false);
651 EXPECT_EQ(v3
, focus_manager
->GetFocusedView());
653 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
654 FocusManager::kForward
, FocusManager::kWrap
));
655 EXPECT_EQ(v1
, focus_manager
->GetFocusedView());
657 // Advance backwards.
658 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
659 FocusManager::kBackward
, FocusManager::kWrap
));
660 EXPECT_EQ(v3
, focus_manager
->GetFocusedView());
662 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
663 FocusManager::kBackward
, FocusManager::kWrap
));
664 EXPECT_EQ(v1
, focus_manager
->GetFocusedView());
666 // Advance without wrap. When it gets to the end of the list of
667 // panes, RotatePaneFocus should return false but the current
668 // focused view shouldn't change.
669 EXPECT_TRUE(focus_manager
->RotatePaneFocus(
670 FocusManager::kForward
, FocusManager::kNoWrap
));
671 EXPECT_EQ(v3
, focus_manager
->GetFocusedView());
673 EXPECT_FALSE(focus_manager
->RotatePaneFocus(
674 FocusManager::kForward
, FocusManager::kNoWrap
));
675 EXPECT_EQ(v3
, focus_manager
->GetFocusedView());
678 // Verifies the stored focus view tracks the focused view.
679 TEST_F(FocusManagerTest
, ImplicitlyStoresFocus
) {
680 views::View
* v1
= new View
;
681 v1
->SetFocusable(true);
682 GetContentsView()->AddChildView(v1
);
684 views::View
* v2
= new View
;
685 v2
->SetFocusable(true);
686 GetContentsView()->AddChildView(v2
);
688 // Verify a focus request on |v1| implicitly updates the stored focus view.
690 EXPECT_TRUE(v1
->HasFocus());
691 EXPECT_EQ(v1
, GetWidget()->GetFocusManager()->GetStoredFocusView());
693 // Verify a focus request on |v2| implicitly updates the stored focus view.
695 EXPECT_TRUE(v2
->HasFocus());
696 EXPECT_EQ(v2
, GetWidget()->GetFocusManager()->GetStoredFocusView());
701 class FocusManagerArrowKeyTraversalTest
: public FocusManagerTest
{
703 FocusManagerArrowKeyTraversalTest()
704 : previous_arrow_key_traversal_enabled_(false) {
706 virtual ~FocusManagerArrowKeyTraversalTest() {}
708 // FocusManagerTest overrides:
709 virtual void SetUp() OVERRIDE
{
710 FocusManagerTest::SetUp();
712 previous_arrow_key_traversal_enabled_
=
713 FocusManager::arrow_key_traversal_enabled();
715 virtual void TearDown() OVERRIDE
{
716 FocusManager::set_arrow_key_traversal_enabled(
717 previous_arrow_key_traversal_enabled_
);
718 FocusManagerTest::TearDown();
722 bool previous_arrow_key_traversal_enabled_
;
724 DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest
);
729 TEST_F(FocusManagerArrowKeyTraversalTest
, ArrowKeyTraversal
) {
730 FocusManager
* focus_manager
= GetFocusManager();
731 const ui::KeyEvent
left_key(ui::ET_KEY_PRESSED
, ui::VKEY_LEFT
, ui::EF_NONE
);
732 const ui::KeyEvent
right_key(ui::ET_KEY_PRESSED
, ui::VKEY_RIGHT
, ui::EF_NONE
);
733 const ui::KeyEvent
up_key(ui::ET_KEY_PRESSED
, ui::VKEY_UP
, ui::EF_NONE
);
734 const ui::KeyEvent
down_key(ui::ET_KEY_PRESSED
, ui::VKEY_DOWN
, ui::EF_NONE
);
736 std::vector
<views::View
*> v
;
737 for (size_t i
= 0; i
< 2; ++i
) {
738 views::View
* view
= new View
;
739 view
->SetFocusable(true);
740 GetContentsView()->AddChildView(view
);
744 // Arrow key traversal is off and arrow key does not change focus.
745 FocusManager::set_arrow_key_traversal_enabled(false);
746 v
[0]->RequestFocus();
747 focus_manager
->OnKeyEvent(right_key
);
748 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
749 focus_manager
->OnKeyEvent(left_key
);
750 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
751 focus_manager
->OnKeyEvent(down_key
);
752 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
753 focus_manager
->OnKeyEvent(up_key
);
754 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
756 // Turn on arrow key traversal.
757 FocusManager::set_arrow_key_traversal_enabled(true);
758 v
[0]->RequestFocus();
759 focus_manager
->OnKeyEvent(right_key
);
760 EXPECT_EQ(v
[1], focus_manager
->GetFocusedView());
761 focus_manager
->OnKeyEvent(left_key
);
762 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
763 focus_manager
->OnKeyEvent(down_key
);
764 EXPECT_EQ(v
[1], focus_manager
->GetFocusedView());
765 focus_manager
->OnKeyEvent(up_key
);
766 EXPECT_EQ(v
[0], focus_manager
->GetFocusedView());
769 TEST_F(FocusManagerTest
, StoreFocusedView
) {
771 GetFocusManager()->SetFocusedView(&view
);
772 GetFocusManager()->StoreFocusedView(false);
773 EXPECT_EQ(NULL
, GetFocusManager()->GetFocusedView());
774 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
775 EXPECT_EQ(&view
, GetFocusManager()->GetStoredFocusView());
777 // Repeat with |true|.
778 GetFocusManager()->SetFocusedView(&view
);
779 GetFocusManager()->StoreFocusedView(true);
780 EXPECT_EQ(NULL
, GetFocusManager()->GetFocusedView());
781 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
782 EXPECT_EQ(&view
, GetFocusManager()->GetStoredFocusView());
785 class TextInputTestView
: public View
{
787 TextInputTestView() {}
789 virtual ui::TextInputClient
* GetTextInputClient() OVERRIDE
{
790 return &text_input_client_
;
794 ui::DummyTextInputClient text_input_client_
;
796 DISALLOW_COPY_AND_ASSIGN(TextInputTestView
);
799 TEST_F(FocusManagerTest
, TextInputClient
) {
800 base::CommandLine
* cmd_line
= base::CommandLine::ForCurrentProcess();
801 cmd_line
->AppendSwitch(switches::kEnableTextInputFocusManager
);
803 View
* view
= new TextInputTestView
;
804 ui::TextInputClient
* text_input_client
= view
->GetTextInputClient();
805 view
->SetFocusable(true);
806 GetContentsView()->AddChildView(view
);
807 ui::TextInputFocusManager
* text_input_focus_manager
=
808 ui::TextInputFocusManager::GetInstance();
810 GetFocusManager()->SetFocusedView(view
);
811 EXPECT_EQ(view
, GetFocusManager()->GetFocusedView());
812 EXPECT_EQ(text_input_client
,
813 text_input_focus_manager
->GetFocusedTextInputClient());
814 GetFocusManager()->StoreFocusedView(false);
815 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
816 EXPECT_EQ(text_input_client
,
817 text_input_focus_manager
->GetFocusedTextInputClient());
819 // Repeat with |true|.
820 GetFocusManager()->SetFocusedView(view
);
821 EXPECT_EQ(view
, GetFocusManager()->GetFocusedView());
822 EXPECT_EQ(text_input_client
,
823 text_input_focus_manager
->GetFocusedTextInputClient());
824 GetFocusManager()->StoreFocusedView(true);
825 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
826 EXPECT_EQ(text_input_client
,
827 text_input_focus_manager
->GetFocusedTextInputClient());
829 // Focus the view twice in a row.
830 GetFocusManager()->SetFocusedView(view
);
831 EXPECT_EQ(text_input_client
,
832 text_input_focus_manager
->GetFocusedTextInputClient());
833 ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL
);
834 GetFocusManager()->SetFocusedView(view
);
835 EXPECT_EQ(text_input_client
,
836 text_input_focus_manager
->GetFocusedTextInputClient());
841 // Trivial WidgetDelegate implementation that allows setting return value of
842 // ShouldAdvanceFocusToTopLevelWidget().
843 class AdvanceFocusWidgetDelegate
: public WidgetDelegate
{
845 explicit AdvanceFocusWidgetDelegate(Widget
* widget
)
847 should_advance_focus_to_parent_(false) {}
848 virtual ~AdvanceFocusWidgetDelegate() {}
850 void set_should_advance_focus_to_parent(bool value
) {
851 should_advance_focus_to_parent_
= value
;
854 // WidgetDelegate overrides:
855 virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE
{
856 return should_advance_focus_to_parent_
;
858 virtual Widget
* GetWidget() OVERRIDE
{ return widget_
; }
859 virtual const Widget
* GetWidget() const OVERRIDE
{ return widget_
; }
863 bool should_advance_focus_to_parent_
;
865 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate
);
870 // Verifies focus wrapping happens in the same widget.
871 TEST_F(FocusManagerTest
, AdvanceFocusStaysInWidget
) {
872 // Add |widget_view| as a child of the Widget.
873 View
* widget_view
= new View
;
874 widget_view
->SetFocusable(true);
875 widget_view
->SetBounds(20, 0, 20, 20);
876 GetContentsView()->AddChildView(widget_view
);
878 // Create a widget with two views, focus the second.
879 scoped_ptr
<AdvanceFocusWidgetDelegate
> delegate
;
880 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_WINDOW
);
881 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
883 params
.bounds
= gfx::Rect(10, 10, 100, 100);
884 params
.parent
= GetWidget()->GetNativeView();
886 delegate
.reset(new AdvanceFocusWidgetDelegate(&child_widget
));
887 params
.delegate
= delegate
.get();
888 child_widget
.Init(params
);
889 View
* view1
= new View
;
890 view1
->SetFocusable(true);
891 view1
->SetBounds(0, 0, 20, 20);
892 View
* view2
= new View
;
893 view2
->SetFocusable(true);
894 view2
->SetBounds(20, 0, 20, 20);
895 child_widget
.client_view()->AddChildView(view1
);
896 child_widget
.client_view()->AddChildView(view2
);
898 view2
->RequestFocus();
899 EXPECT_EQ(view2
, GetFocusManager()->GetFocusedView());
901 // Advance focus backwards, which should focus the first.
902 GetFocusManager()->AdvanceFocus(false);
903 EXPECT_EQ(view1
, GetFocusManager()->GetFocusedView());
905 // Focus forward to |view2|.
906 GetFocusManager()->AdvanceFocus(true);
907 EXPECT_EQ(view2
, GetFocusManager()->GetFocusedView());
909 // And forward again, wrapping back to |view1|.
910 GetFocusManager()->AdvanceFocus(true);
911 EXPECT_EQ(view1
, GetFocusManager()->GetFocusedView());
913 // Allow focus to go to the parent, and focus backwards which should now move
914 // up |widget_view| (in the parent).
915 delegate
->set_should_advance_focus_to_parent(true);
916 GetFocusManager()->AdvanceFocus(true);
917 EXPECT_EQ(widget_view
, GetFocusManager()->GetFocusedView());