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