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 void OnFocus() override
{
52 event_list_
->push_back(FocusTestEvent(ON_FOCUS
, id()));
55 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(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 aura::client::GetFocusClient(native_view2
)->FocusWindow(native_view2
);
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
{
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
;
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);
199 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
201 focus_manager
->GetCurrentTargetForAccelerator(escape_accelerator
));
204 focus_manager
->RegisterAccelerator(return_accelerator
,
205 ui::AcceleratorManager::kNormalPriority
,
207 focus_manager
->RegisterAccelerator(escape_accelerator
,
208 ui::AcceleratorManager::kNormalPriority
,
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
,
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
,
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.
276 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
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);
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
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
);
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
,
388 focus_manager
->RegisterAccelerator(return_accelerator
,
389 ui::AcceleratorManager::kNormalPriority
,
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
{
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);
432 bool CanHandleAccelerators() const override
{ return true; }
434 int accelerator_count() const { return accelerator_count_
; }
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);
450 focus_manager
->GetCurrentTargetForAccelerator(return_accelerator
));
452 // Register the target.
453 focus_manager
->RegisterAccelerator(return_accelerator
,
454 ui::AcceleratorManager::kNormalPriority
,
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);
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
,
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
{
490 typedef std::vector
<std::string
> DtorTrackVector
;
492 class FocusManagerDtorTracked
: public FocusManager
{
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_
;
506 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked
);
509 class TestFocusManagerFactory
: public FocusManagerFactory
{
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_
);
521 DtorTrackVector
* dtor_tracker_
;
522 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory
);
525 class LabelButtonDtorTracked
: public LabelButton
{
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
{
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());
568 void TearDown() override
{
569 FocusManagerFactory::Install(NULL
);
570 ViewsTestBase::TearDown();
573 FocusManager
* tracked_focus_manager_
;
574 DtorTrackVector dtor_tracker_
;
579 class FocusInAboutToRequestFocusFromTabTraversalView
: public View
{
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();
590 views::View
* view_to_focus_
;
592 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView
);
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
);
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.
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.
709 EXPECT_TRUE(v2
->HasFocus());
710 EXPECT_EQ(v2
, GetWidget()->GetFocusManager()->GetStoredFocusView());
715 class FocusManagerArrowKeyTraversalTest
: public FocusManagerTest
{
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();
736 bool previous_arrow_key_traversal_enabled_
;
738 DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest
);
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
);
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
) {
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 class TextInputTestView
: public View
{
801 TextInputTestView() {}
803 ui::TextInputClient
* GetTextInputClient() override
{
804 return &text_input_client_
;
808 ui::DummyTextInputClient text_input_client_
;
810 DISALLOW_COPY_AND_ASSIGN(TextInputTestView
);
813 TEST_F(FocusManagerTest
, TextInputClient
) {
814 base::CommandLine
* cmd_line
= base::CommandLine::ForCurrentProcess();
815 cmd_line
->AppendSwitch(switches::kEnableTextInputFocusManager
);
817 View
* view
= new TextInputTestView
;
818 ui::TextInputClient
* text_input_client
= view
->GetTextInputClient();
819 view
->SetFocusable(true);
820 GetContentsView()->AddChildView(view
);
821 ui::TextInputFocusManager
* text_input_focus_manager
=
822 ui::TextInputFocusManager::GetInstance();
824 GetFocusManager()->SetFocusedView(view
);
825 EXPECT_EQ(view
, GetFocusManager()->GetFocusedView());
826 EXPECT_EQ(text_input_client
,
827 text_input_focus_manager
->GetFocusedTextInputClient());
828 GetFocusManager()->StoreFocusedView(false);
829 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
830 EXPECT_EQ(text_input_client
,
831 text_input_focus_manager
->GetFocusedTextInputClient());
833 // Repeat with |true|.
834 GetFocusManager()->SetFocusedView(view
);
835 EXPECT_EQ(view
, GetFocusManager()->GetFocusedView());
836 EXPECT_EQ(text_input_client
,
837 text_input_focus_manager
->GetFocusedTextInputClient());
838 GetFocusManager()->StoreFocusedView(true);
839 EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
840 EXPECT_EQ(text_input_client
,
841 text_input_focus_manager
->GetFocusedTextInputClient());
843 // Focus the view twice in a row.
844 GetFocusManager()->SetFocusedView(view
);
845 EXPECT_EQ(text_input_client
,
846 text_input_focus_manager
->GetFocusedTextInputClient());
847 ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL
);
848 GetFocusManager()->SetFocusedView(view
);
849 EXPECT_EQ(text_input_client
,
850 text_input_focus_manager
->GetFocusedTextInputClient());
855 // Trivial WidgetDelegate implementation that allows setting return value of
856 // ShouldAdvanceFocusToTopLevelWidget().
857 class AdvanceFocusWidgetDelegate
: public WidgetDelegate
{
859 explicit AdvanceFocusWidgetDelegate(Widget
* widget
)
861 should_advance_focus_to_parent_(false) {}
862 ~AdvanceFocusWidgetDelegate() override
{}
864 void set_should_advance_focus_to_parent(bool value
) {
865 should_advance_focus_to_parent_
= value
;
868 // WidgetDelegate overrides:
869 bool ShouldAdvanceFocusToTopLevelWidget() const override
{
870 return should_advance_focus_to_parent_
;
872 Widget
* GetWidget() override
{ return widget_
; }
873 const Widget
* GetWidget() const override
{ return widget_
; }
877 bool should_advance_focus_to_parent_
;
879 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate
);
884 // Verifies focus wrapping happens in the same widget.
885 TEST_F(FocusManagerTest
, AdvanceFocusStaysInWidget
) {
886 // Add |widget_view| as a child of the Widget.
887 View
* widget_view
= new View
;
888 widget_view
->SetFocusable(true);
889 widget_view
->SetBounds(20, 0, 20, 20);
890 GetContentsView()->AddChildView(widget_view
);
892 // Create a widget with two views, focus the second.
893 scoped_ptr
<AdvanceFocusWidgetDelegate
> delegate
;
894 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_WINDOW
);
895 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
897 params
.bounds
= gfx::Rect(10, 10, 100, 100);
898 params
.parent
= GetWidget()->GetNativeView();
900 delegate
.reset(new AdvanceFocusWidgetDelegate(&child_widget
));
901 params
.delegate
= delegate
.get();
902 child_widget
.Init(params
);
903 View
* view1
= new View
;
904 view1
->SetFocusable(true);
905 view1
->SetBounds(0, 0, 20, 20);
906 View
* view2
= new View
;
907 view2
->SetFocusable(true);
908 view2
->SetBounds(20, 0, 20, 20);
909 child_widget
.client_view()->AddChildView(view1
);
910 child_widget
.client_view()->AddChildView(view2
);
912 view2
->RequestFocus();
913 EXPECT_EQ(view2
, GetFocusManager()->GetFocusedView());
915 // Advance focus backwards, which should focus the first.
916 GetFocusManager()->AdvanceFocus(false);
917 EXPECT_EQ(view1
, GetFocusManager()->GetFocusedView());
919 // Focus forward to |view2|.
920 GetFocusManager()->AdvanceFocus(true);
921 EXPECT_EQ(view2
, GetFocusManager()->GetFocusedView());
923 // And forward again, wrapping back to |view1|.
924 GetFocusManager()->AdvanceFocus(true);
925 EXPECT_EQ(view1
, GetFocusManager()->GetFocusedView());
927 // Allow focus to go to the parent, and focus backwards which should now move
928 // up |widget_view| (in the parent).
929 delegate
->set_should_advance_focus_to_parent(true);
930 GetFocusManager()->AdvanceFocus(true);
931 EXPECT_EQ(widget_view
, GetFocusManager()->GetFocusedView());