focus_manager_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/utf_string_conversions.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/keycodes/keyboard_codes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/text_button.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/textfield/textfield.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/focus/accelerator_handler.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/focus/focus_manager_factory.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/focus/focus_manager_test.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/focus/widget_focus_manager.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace views { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FocusNativeView(gfx::NativeView view) { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::client::GetFocusClient(view)->FocusWindow(view); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetFocus(view); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#error 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum FocusTestEventType { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ON_FOCUS = 0, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ON_BLUR 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct FocusTestEvent { 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FocusTestEvent(FocusTestEventType type, int view_id) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : type(type), 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view_id(view_id) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FocusTestEventType type; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int view_id; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SimpleTestView : public View { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : event_list_(event_list) { 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) set_focusable(true); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) set_id(view_id); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnFocus() OVERRIDE { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_list_->push_back(FocusTestEvent(ON_FOCUS, id())); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnBlur() OVERRIDE { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_list_->push_back(FocusTestEvent(ON_BLUR, id())); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<FocusTestEvent>* event_list_; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that the appropriate Focus related methods are called when a View 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// gets/loses focus. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FocusManagerTest, ViewFocusCallbacks) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<FocusTestEvent> event_list; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kView1ID = 1; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kView2ID = 2; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SimpleTestView* view1 = new SimpleTestView(&event_list, kView1ID); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SimpleTestView* view2 = new SimpleTestView(&event_list, kView2ID); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetContentsView()->AddChildView(view1); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetContentsView()->AddChildView(view2); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view1->RequestFocus(); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(1, static_cast<int>(event_list.size())); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ON_FOCUS, event_list[0].type); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kView1ID, event_list[0].view_id); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_list.clear(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view2->RequestFocus(); 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(2, static_cast<int>(event_list.size())); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ON_BLUR, event_list[0].type); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kView1ID, event_list[0].view_id); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ON_FOCUS, event_list[1].type); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kView2ID, event_list[1].view_id); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_list.clear(); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFocusManager()->ClearFocus(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(1, static_cast<int>(event_list.size())); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(ON_BLUR, event_list[0].type); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(kView2ID, event_list[0].view_id); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FocusManagerTest, FocusChangeListener) { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) View* view1 = new View(); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view1->set_focusable(true); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) View* view2 = new View(); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view2->set_focusable(true); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetContentsView()->AddChildView(view1); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetContentsView()->AddChildView(view2); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestFocusChangeListener listener; 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AddFocusChangeListener(&listener); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::View* null_view = NULL; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) view1->RequestFocus(); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size())); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view1)); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener.ClearFocusChanges(); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) view2->RequestFocus(); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size())); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2)); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) listener.ClearFocusChanges(); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFocusManager()->ClearFocus(); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size())); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, null_view)); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FocusManagerTest, WidgetFocusChangeListener) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestWidgetFocusChangeListener widget_listener; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddWidgetFocusChangeListener(&widget_listener); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(10, 10, 100, 100); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.parent = GetWidget()->GetNativeView(); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Widget> widget1(new Widget); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget1->Init(params); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget1->Show(); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<Widget> widget2(new Widget); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) widget2->Init(params); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) widget2->Show(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget_listener.ClearFocusChanges(); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::NativeView native_view1 = widget1->GetNativeView(); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FocusNativeView(native_view1); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size())); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(native_view1, widget_listener.focus_changes()[0].second); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(native_view1, widget_listener.focus_changes()[1].second); 155 156 widget_listener.ClearFocusChanges(); 157 gfx::NativeView native_view2 = widget2->GetNativeView(); 158 FocusNativeView(native_view2); 159 ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size())); 160 EXPECT_EQ(NativeViewPair(native_view1, native_view2), 161 widget_listener.focus_changes()[0]); 162 EXPECT_EQ(NativeViewPair(native_view1, native_view2), 163 widget_listener.focus_changes()[1]); 164} 165 166#if !defined(USE_AURA) 167class TestTextfield : public Textfield { 168 public: 169 TestTextfield() {} 170 virtual gfx::NativeView TestGetNativeControlView() { 171 return native_wrapper_->GetTestingHandle(); 172 } 173}; 174 175// Tests that NativeControls do set the focused View appropriately on the 176// FocusManager. 177TEST_F(FocusManagerTest, DISABLED_FocusNativeControls) { 178 TestTextfield* textfield = new TestTextfield(); 179 GetContentsView()->AddChildView(textfield); 180 // Simulate the native view getting the native focus (such as by user click). 181 FocusNativeView(textfield->TestGetNativeControlView()); 182 EXPECT_EQ(textfield, GetFocusManager()->GetFocusedView()); 183} 184#endif 185 186// Counts accelerator calls. 187class TestAcceleratorTarget : public ui::AcceleratorTarget { 188 public: 189 explicit TestAcceleratorTarget(bool process_accelerator) 190 : accelerator_count_(0), 191 process_accelerator_(process_accelerator), 192 can_handle_accelerators_(true) {} 193 194 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE { 195 ++accelerator_count_; 196 return process_accelerator_; 197 } 198 199 virtual bool CanHandleAccelerators() const OVERRIDE { 200 return can_handle_accelerators_; 201 } 202 203 int accelerator_count() const { return accelerator_count_; } 204 205 void set_can_handle_accelerators(bool can_handle_accelerators) { 206 can_handle_accelerators_ = can_handle_accelerators; 207 } 208 209 private: 210 int accelerator_count_; // number of times that the accelerator is activated 211 bool process_accelerator_; // return value of AcceleratorPressed 212 bool can_handle_accelerators_; // return value of CanHandleAccelerators 213 214 DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget); 215}; 216 217TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) { 218 FocusManager* focus_manager = GetFocusManager(); 219 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); 220 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE); 221 222 TestAcceleratorTarget return_target(true); 223 TestAcceleratorTarget escape_target(true); 224 EXPECT_EQ(return_target.accelerator_count(), 0); 225 EXPECT_EQ(escape_target.accelerator_count(), 0); 226 EXPECT_EQ(NULL, 227 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 228 EXPECT_EQ(NULL, 229 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 230 231 // Register targets. 232 focus_manager->RegisterAccelerator(return_accelerator, 233 ui::AcceleratorManager::kNormalPriority, 234 &return_target); 235 focus_manager->RegisterAccelerator(escape_accelerator, 236 ui::AcceleratorManager::kNormalPriority, 237 &escape_target); 238 239 // Checks if the correct target is registered. 240 EXPECT_EQ(&return_target, 241 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 242 EXPECT_EQ(&escape_target, 243 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 244 245 // Hitting the return key. 246 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 247 EXPECT_EQ(return_target.accelerator_count(), 1); 248 EXPECT_EQ(escape_target.accelerator_count(), 0); 249 250 // Hitting the escape key. 251 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 252 EXPECT_EQ(return_target.accelerator_count(), 1); 253 EXPECT_EQ(escape_target.accelerator_count(), 1); 254 255 // Register another target for the return key. 256 TestAcceleratorTarget return_target2(true); 257 EXPECT_EQ(return_target2.accelerator_count(), 0); 258 focus_manager->RegisterAccelerator(return_accelerator, 259 ui::AcceleratorManager::kNormalPriority, 260 &return_target2); 261 EXPECT_EQ(&return_target2, 262 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 263 264 // Hitting the return key; return_target2 has the priority. 265 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 266 EXPECT_EQ(return_target.accelerator_count(), 1); 267 EXPECT_EQ(return_target2.accelerator_count(), 1); 268 269 // Register a target that does not process the accelerator event. 270 TestAcceleratorTarget return_target3(false); 271 EXPECT_EQ(return_target3.accelerator_count(), 0); 272 focus_manager->RegisterAccelerator(return_accelerator, 273 ui::AcceleratorManager::kNormalPriority, 274 &return_target3); 275 EXPECT_EQ(&return_target3, 276 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 277 278 // Hitting the return key. 279 // Since the event handler of return_target3 returns false, return_target2 280 // should be called too. 281 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 282 EXPECT_EQ(return_target.accelerator_count(), 1); 283 EXPECT_EQ(return_target2.accelerator_count(), 2); 284 EXPECT_EQ(return_target3.accelerator_count(), 1); 285 286 // Unregister return_target2. 287 focus_manager->UnregisterAccelerator(return_accelerator, &return_target2); 288 EXPECT_EQ(&return_target3, 289 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 290 291 // Hitting the return key. return_target3 and return_target should be called. 292 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 293 EXPECT_EQ(return_target.accelerator_count(), 2); 294 EXPECT_EQ(return_target2.accelerator_count(), 2); 295 EXPECT_EQ(return_target3.accelerator_count(), 2); 296 297 // Unregister targets. 298 focus_manager->UnregisterAccelerator(return_accelerator, &return_target); 299 focus_manager->UnregisterAccelerator(return_accelerator, &return_target3); 300 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target); 301 302 // Now there is no target registered. 303 EXPECT_EQ(NULL, 304 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 305 EXPECT_EQ(NULL, 306 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 307 308 // Hitting the return key and the escape key. Nothing should happen. 309 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); 310 EXPECT_EQ(return_target.accelerator_count(), 2); 311 EXPECT_EQ(return_target2.accelerator_count(), 2); 312 EXPECT_EQ(return_target3.accelerator_count(), 2); 313 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator)); 314 EXPECT_EQ(escape_target.accelerator_count(), 1); 315} 316 317TEST_F(FocusManagerTest, HighPriorityHandlers) { 318 FocusManager* focus_manager = GetFocusManager(); 319 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE); 320 321 TestAcceleratorTarget escape_target_high(true); 322 TestAcceleratorTarget escape_target_normal(true); 323 EXPECT_EQ(escape_target_high.accelerator_count(), 0); 324 EXPECT_EQ(escape_target_normal.accelerator_count(), 0); 325 EXPECT_EQ(NULL, 326 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 327 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator)); 328 329 // Register high priority target. 330 focus_manager->RegisterAccelerator(escape_accelerator, 331 ui::AcceleratorManager::kHighPriority, 332 &escape_target_high); 333 EXPECT_EQ(&escape_target_high, 334 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 335 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator)); 336 337 // Hit the escape key. 338 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 339 EXPECT_EQ(escape_target_high.accelerator_count(), 1); 340 EXPECT_EQ(escape_target_normal.accelerator_count(), 0); 341 342 // Add a normal priority target and make sure it doesn't see the key. 343 focus_manager->RegisterAccelerator(escape_accelerator, 344 ui::AcceleratorManager::kNormalPriority, 345 &escape_target_normal); 346 347 // Checks if the correct target is registered (same as before, the high 348 // priority one). 349 EXPECT_EQ(&escape_target_high, 350 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 351 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator)); 352 353 // Hit the escape key. 354 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 355 EXPECT_EQ(escape_target_high.accelerator_count(), 2); 356 EXPECT_EQ(escape_target_normal.accelerator_count(), 0); 357 358 // Unregister the high priority accelerator. 359 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high); 360 EXPECT_EQ(&escape_target_normal, 361 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 362 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator)); 363 364 // Hit the escape key. 365 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 366 EXPECT_EQ(escape_target_high.accelerator_count(), 2); 367 EXPECT_EQ(escape_target_normal.accelerator_count(), 1); 368 369 // Add the high priority target back and make sure it starts seeing the key. 370 focus_manager->RegisterAccelerator(escape_accelerator, 371 ui::AcceleratorManager::kHighPriority, 372 &escape_target_high); 373 EXPECT_EQ(&escape_target_high, 374 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 375 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator)); 376 377 // Hit the escape key. 378 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 379 EXPECT_EQ(escape_target_high.accelerator_count(), 3); 380 EXPECT_EQ(escape_target_normal.accelerator_count(), 1); 381 382 // Unregister the normal priority accelerator. 383 focus_manager->UnregisterAccelerator( 384 escape_accelerator, &escape_target_normal); 385 EXPECT_EQ(&escape_target_high, 386 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 387 EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator)); 388 389 // Hit the escape key. 390 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); 391 EXPECT_EQ(escape_target_high.accelerator_count(), 4); 392 EXPECT_EQ(escape_target_normal.accelerator_count(), 1); 393 394 // Unregister the high priority accelerator. 395 focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high); 396 EXPECT_EQ(NULL, 397 focus_manager->GetCurrentTargetForAccelerator(escape_accelerator)); 398 EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator)); 399 400 // Hit the escape key (no change, no targets registered). 401 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator)); 402 EXPECT_EQ(escape_target_high.accelerator_count(), 4); 403 EXPECT_EQ(escape_target_normal.accelerator_count(), 1); 404} 405 406TEST_F(FocusManagerTest, CallsEnabledAcceleratorTargetsOnly) { 407 FocusManager* focus_manager = GetFocusManager(); 408 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); 409 410 TestAcceleratorTarget return_target1(true); 411 TestAcceleratorTarget return_target2(true); 412 413 focus_manager->RegisterAccelerator(return_accelerator, 414 ui::AcceleratorManager::kNormalPriority, 415 &return_target1); 416 focus_manager->RegisterAccelerator(return_accelerator, 417 ui::AcceleratorManager::kNormalPriority, 418 &return_target2); 419 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 420 EXPECT_EQ(0, return_target1.accelerator_count()); 421 EXPECT_EQ(1, return_target2.accelerator_count()); 422 423 // If CanHandleAccelerators() return false, FocusManager shouldn't call 424 // AcceleratorPressed(). 425 return_target2.set_can_handle_accelerators(false); 426 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 427 EXPECT_EQ(1, return_target1.accelerator_count()); 428 EXPECT_EQ(1, return_target2.accelerator_count()); 429 430 // If no accelerator targets are enabled, ProcessAccelerator() should fail. 431 return_target1.set_can_handle_accelerators(false); 432 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); 433 EXPECT_EQ(1, return_target1.accelerator_count()); 434 EXPECT_EQ(1, return_target2.accelerator_count()); 435 436 // Enabling the target again causes the accelerators to be processed again. 437 return_target1.set_can_handle_accelerators(true); 438 return_target2.set_can_handle_accelerators(true); 439 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 440 EXPECT_EQ(1, return_target1.accelerator_count()); 441 EXPECT_EQ(2, return_target2.accelerator_count()); 442} 443 444// Unregisters itself when its accelerator is invoked. 445class SelfUnregisteringAcceleratorTarget : public ui::AcceleratorTarget { 446 public: 447 SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator, 448 FocusManager* focus_manager) 449 : accelerator_(accelerator), 450 focus_manager_(focus_manager), 451 accelerator_count_(0) { 452 } 453 454 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE { 455 ++accelerator_count_; 456 focus_manager_->UnregisterAccelerator(accelerator, this); 457 return true; 458 } 459 460 virtual bool CanHandleAccelerators() const OVERRIDE { 461 return true; 462 } 463 464 int accelerator_count() const { return accelerator_count_; } 465 466 private: 467 ui::Accelerator accelerator_; 468 FocusManager* focus_manager_; 469 int accelerator_count_; 470 471 DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget); 472}; 473 474TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) { 475 FocusManager* focus_manager = GetFocusManager(); 476 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); 477 SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager); 478 EXPECT_EQ(target.accelerator_count(), 0); 479 EXPECT_EQ(NULL, 480 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 481 482 // Register the target. 483 focus_manager->RegisterAccelerator(return_accelerator, 484 ui::AcceleratorManager::kNormalPriority, 485 &target); 486 EXPECT_EQ(&target, 487 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 488 489 // Hitting the return key. The target will be unregistered. 490 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); 491 EXPECT_EQ(target.accelerator_count(), 1); 492 EXPECT_EQ(NULL, 493 focus_manager->GetCurrentTargetForAccelerator(return_accelerator)); 494 495 // Hitting the return key again; nothing should happen. 496 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); 497 EXPECT_EQ(target.accelerator_count(), 1); 498} 499 500class FocusManagerDtorTest : public FocusManagerTest { 501 protected: 502 typedef std::vector<std::string> DtorTrackVector; 503 504 class FocusManagerDtorTracked : public FocusManager { 505 public: 506 FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker) 507 : FocusManager(widget, NULL /* delegate */), 508 dtor_tracker_(dtor_tracker) { 509 } 510 511 virtual ~FocusManagerDtorTracked() { 512 dtor_tracker_->push_back("FocusManagerDtorTracked"); 513 } 514 515 DtorTrackVector* dtor_tracker_; 516 517 private: 518 DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked); 519 }; 520 521 class TestFocusManagerFactory : public FocusManagerFactory { 522 public: 523 explicit TestFocusManagerFactory(DtorTrackVector* dtor_tracker) 524 : dtor_tracker_(dtor_tracker) { 525 } 526 527 virtual FocusManager* CreateFocusManager(Widget* widget) OVERRIDE { 528 return new FocusManagerDtorTracked(widget, dtor_tracker_); 529 } 530 531 private: 532 DtorTrackVector* dtor_tracker_; 533 DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory); 534 }; 535 536 class NativeButtonDtorTracked : public NativeTextButton { 537 public: 538 NativeButtonDtorTracked(const string16& text, 539 DtorTrackVector* dtor_tracker) 540 : NativeTextButton(NULL, text), 541 dtor_tracker_(dtor_tracker) { 542 }; 543 virtual ~NativeButtonDtorTracked() { 544 dtor_tracker_->push_back("NativeButtonDtorTracked"); 545 } 546 547 DtorTrackVector* dtor_tracker_; 548 }; 549 550 class WindowDtorTracked : public Widget { 551 public: 552 explicit WindowDtorTracked(DtorTrackVector* dtor_tracker) 553 : dtor_tracker_(dtor_tracker) { 554 } 555 556 virtual ~WindowDtorTracked() { 557 dtor_tracker_->push_back("WindowDtorTracked"); 558 } 559 560 DtorTrackVector* dtor_tracker_; 561 }; 562 563 virtual void SetUp() { 564 ViewsTestBase::SetUp(); 565 FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_)); 566 // Create WindowDtorTracked that uses FocusManagerDtorTracked. 567 Widget* widget = new WindowDtorTracked(&dtor_tracker_); 568 Widget::InitParams params; 569 params.delegate = this; 570 params.bounds = gfx::Rect(0, 0, 100, 100); 571 widget->Init(params); 572 573 tracked_focus_manager_ = 574 static_cast<FocusManagerDtorTracked*>(GetFocusManager()); 575 widget->Show(); 576 } 577 578 virtual void TearDown() { 579 FocusManagerFactory::Install(NULL); 580 ViewsTestBase::TearDown(); 581 } 582 583 FocusManager* tracked_focus_manager_; 584 DtorTrackVector dtor_tracker_; 585}; 586 587#if !defined(USE_AURA) 588TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) { 589 // Setup views hierarchy. 590 GetContentsView()->AddChildView(new TestTextfield()); 591 GetContentsView()->AddChildView(new NativeButtonDtorTracked( 592 ASCIIToUTF16("button"), &dtor_tracker_)); 593 594 // Close the window. 595 GetWidget()->Close(); 596 RunPendingMessages(); 597 598 // Test window, button and focus manager should all be destructed. 599 ASSERT_EQ(3, static_cast<int>(dtor_tracker_.size())); 600 601 // Focus manager should be the last one to destruct. 602 ASSERT_STREQ("FocusManagerDtorTracked", dtor_tracker_[2].c_str()); 603} 604#endif 605 606namespace { 607 608class FocusInAboutToRequestFocusFromTabTraversalView : public View { 609 public: 610 FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL) {} 611 612 void set_view_to_focus(View* view) { view_to_focus_ = view; } 613 614 virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE { 615 view_to_focus_->RequestFocus(); 616 } 617 618 private: 619 views::View* view_to_focus_; 620 621 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView); 622}; 623} // namespace 624 625// Verifies a focus change done during a call to 626// AboutToRequestFocusFromTabTraversal() is honored. 627TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) { 628 // Create 3 views focuses the 3 and advances to the second. The 2nd views 629 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first. 630 views::View* v1 = new View; 631 v1->set_focusable(true); 632 GetContentsView()->AddChildView(v1); 633 634 FocusInAboutToRequestFocusFromTabTraversalView* v2 = 635 new FocusInAboutToRequestFocusFromTabTraversalView; 636 v2->set_focusable(true); 637 v2->set_view_to_focus(v1); 638 GetContentsView()->AddChildView(v2); 639 640 views::View* v3 = new View; 641 v3->set_focusable(true); 642 GetContentsView()->AddChildView(v3); 643 644 v3->RequestFocus(); 645 GetWidget()->GetFocusManager()->AdvanceFocus(true); 646 EXPECT_TRUE(v1->HasFocus()); 647} 648 649} // namespace views 650