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. 4 5#ifndef UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ 6#define UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ 7 8#include <list> 9#include <map> 10 11#include "base/basictypes.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/observer_list.h" 14#include "ui/base/accelerators/accelerator.h" 15#include "ui/base/accelerators/accelerator_manager.h" 16#include "ui/gfx/native_widget_types.h" 17#include "ui/views/views_export.h" 18 19// The FocusManager class is used to handle focus traversal, store/restore 20// focused views and handle keyboard accelerators. 21// 22// There are 2 types of focus: 23// - the native focus, which is the focus that an gfx::NativeView has. 24// - the view focus, which is the focus that a views::View has. 25// 26// Each native view must register with their Focus Manager so the focus manager 27// gets notified when they are focused (and keeps track of the native focus) and 28// as well so that the tab key events can be intercepted. 29// They can provide when they register a View that is kept in synch in term of 30// focus. This is used in NativeControl for example, where a View wraps an 31// actual native window. 32// This is already done for you if you subclass the NativeControl class or if 33// you use the NativeViewHost class. 34// 35// When creating a top window (derived from views::Widget) that is not a child 36// window, it creates and owns a FocusManager to manage the focus for itself and 37// all its child windows. 38// 39// The FocusTraversable interface exposes the methods a class should implement 40// in order to be able to be focus traversed when tab key is pressed. 41// RootViews implement FocusTraversable. 42// The FocusManager contains a top FocusTraversable instance, which is the top 43// RootView. 44// 45// If you just use views, then the focus traversal is handled for you by the 46// RootView. The default traversal order is the order in which the views have 47// been added to their container. You can modify this order by using the View 48// method SetNextFocusableView(). 49// 50// If you are embedding a native view containing a nested RootView (for example 51// by adding a NativeControl that contains a NativeWidgetWin as its native 52// component), then you need to: 53// - override the View::GetFocusTraversable() method in your outer component. 54// It should return the RootView of the inner component. This is used when 55// the focus traversal traverse down the focus hierarchy to enter the nested 56// RootView. In the example mentioned above, the NativeControl overrides 57// GetFocusTraversable() and returns hwnd_view_container_->GetRootView(). 58// - call Widget::SetFocusTraversableParent() on the nested RootView and point 59// it to the outer RootView. This is used when the focus goes out of the 60// nested RootView. In the example: 61// hwnd_view_container_->GetWidget()->SetFocusTraversableParent( 62// native_control->GetRootView()); 63// - call RootView::SetFocusTraversableParentView() on the nested RootView with 64// the parent view that directly contains the native window. This is needed 65// when traversing up from the nested RootView to know which view to start 66// with when going to the next/previous view. 67// In our example: 68// hwnd_view_container_->GetWidget()->SetFocusTraversableParent( 69// native_control); 70// 71// Note that FocusTraversable do not have to be RootViews: AccessibleToolbarView 72// is FocusTraversable. 73 74namespace ui { 75class AcceleratorManager; 76class AcceleratorTarget; 77class EventHandler; 78class KeyEvent; 79} 80 81namespace views { 82 83class FocusManagerDelegate; 84class FocusSearch; 85class RootView; 86class View; 87class Widget; 88 89// The FocusTraversable interface is used by components that want to process 90// focus traversal events (due to Tab/Shift-Tab key events). 91class VIEWS_EXPORT FocusTraversable { 92 public: 93 // Return a FocusSearch object that implements the algorithm to find 94 // the next or previous focusable view. 95 virtual FocusSearch* GetFocusSearch() = 0; 96 97 // Should return the parent FocusTraversable. 98 // The top RootView which is the top FocusTraversable returns NULL. 99 virtual FocusTraversable* GetFocusTraversableParent() = 0; 100 101 // This should return the View this FocusTraversable belongs to. 102 // It is used when walking up the view hierarchy tree to find which view 103 // should be used as the starting view for finding the next/previous view. 104 virtual View* GetFocusTraversableParentView() = 0; 105 106 protected: 107 virtual ~FocusTraversable() {} 108}; 109 110// This interface should be implemented by classes that want to be notified when 111// the focus is about to change. See the Add/RemoveFocusChangeListener methods. 112class VIEWS_EXPORT FocusChangeListener { 113 public: 114 // No change to focus state has occurred yet when this function is called. 115 virtual void OnWillChangeFocus(View* focused_before, View* focused_now) = 0; 116 117 // Called after focus state has changed. 118 virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0; 119 120 protected: 121 virtual ~FocusChangeListener() {} 122}; 123 124class VIEWS_EXPORT FocusManager { 125 public: 126 // The reason why the focus changed. 127 enum FocusChangeReason { 128 // The focus changed because the user traversed focusable views using 129 // keys like Tab or Shift+Tab. 130 kReasonFocusTraversal, 131 132 // The focus changed due to restoring the focus. 133 kReasonFocusRestore, 134 135 // The focus changed due to a click or a shortcut to jump directly to 136 // a particular view. 137 kReasonDirectFocusChange 138 }; 139 140 // TODO: use Direction in place of bool reverse throughout. 141 enum Direction { 142 kForward, 143 kBackward 144 }; 145 146 enum FocusCycleWrappingBehavior { 147 kWrap, 148 kNoWrap 149 }; 150 151 FocusManager(Widget* widget, FocusManagerDelegate* delegate); 152 virtual ~FocusManager(); 153 154 // Processes the passed key event for accelerators and keyboard traversal. 155 // Returns false if the event has been consumed and should not be processed 156 // further. 157 bool OnKeyEvent(const ui::KeyEvent& event); 158 159 // Returns true is the specified is part of the hierarchy of the window 160 // associated with this FocusManager. 161 bool ContainsView(View* view); 162 163 // Advances the focus (backward if reverse is true). 164 void AdvanceFocus(bool reverse); 165 166 // The FocusManager keeps track of the focused view within a RootView. 167 View* GetFocusedView() { return focused_view_; } 168 const View* GetFocusedView() const { return focused_view_; } 169 170 // Low-level methods to force the focus to change (and optionally provide 171 // a reason). If the focus change should only happen if the view is 172 // currenty focusable, enabled, and visible, call view->RequestFocus(). 173 void SetFocusedViewWithReason(View* view, FocusChangeReason reason); 174 void SetFocusedView(View* view) { 175 SetFocusedViewWithReason(view, kReasonDirectFocusChange); 176 } 177 178 // Get the reason why the focus most recently changed. 179 FocusChangeReason focus_change_reason() const { 180 return focus_change_reason_; 181 } 182 183 // Clears the focused view. The window associated with the top root view gets 184 // the native focus (so we still get keyboard events). 185 void ClearFocus(); 186 187 // Validates the focused view, clearing it if the window it belongs too is not 188 // attached to the window hierarchy anymore. 189 void ValidateFocusedView(); 190 191 // Stores the focused view. Used when the widget loses activation. 192 // |clear_native_focus| indicates whether this should invoke ClearFocus(). 193 // Typically |true| should be passed in. 194 void StoreFocusedView(bool clear_native_focus); 195 196 // Restore the view saved with a previous call to StoreFocusedView(). Used 197 // when the widget becomes active. Returns true when the previous view was 198 // successfully refocused - otherwise false. 199 bool RestoreFocusedView(); 200 201 // Sets the |view| to be restored when calling RestoreFocusView. This is used 202 // to set where the focus should go on restoring a Window created without 203 // focus being set. 204 void SetStoredFocusView(View* view); 205 206 // Returns the View that either currently has focus, or if no view has focus 207 // the view that last had focus. 208 View* GetStoredFocusView(); 209 210 // Clears the stored focused view. 211 void ClearStoredFocusedView(); 212 213 // Returns true if in the process of changing the focused view. 214 bool is_changing_focus() const { return is_changing_focus_; } 215 216 // Changes the text input focus to |view->GetTextInputClient()| iff |view| 217 // is focused. Views must call this method when their internal 218 // TextInputClient instance changes. 219 void OnTextInputClientChanged(View* view); 220 221 // Moves the text input focus into/out from |view|. 222 void FocusTextInputClient(View* view); 223 void BlurTextInputClient(View* view); 224 225 // Disable shortcut handling. 226 static void set_shortcut_handling_suspended(bool suspended) { 227 shortcut_handling_suspended_ = suspended; 228 } 229 // Returns whether shortcut handling is currently suspended. 230 bool shortcut_handling_suspended() { return shortcut_handling_suspended_; } 231 232 // Register a keyboard accelerator for the specified target. If multiple 233 // targets are registered for an accelerator, a target registered later has 234 // higher priority. 235 // |accelerator| is the accelerator to register. 236 // |priority| denotes the priority of the handler. 237 // NOTE: In almost all cases, you should specify kNormalPriority for this 238 // parameter. Setting it to kHighPriority prevents Chrome from sending the 239 // shortcut to the webpage if the renderer has focus, which is not desirable 240 // except for very isolated cases. 241 // |target| is the AcceleratorTarget that handles the event once the 242 // accelerator is pressed. 243 // Note that we are currently limited to accelerators that are either: 244 // - a key combination including Ctrl or Alt 245 // - the escape key 246 // - the enter key 247 // - any F key (F1, F2, F3 ...) 248 // - any browser specific keys (as available on special keyboards) 249 void RegisterAccelerator(const ui::Accelerator& accelerator, 250 ui::AcceleratorManager::HandlerPriority priority, 251 ui::AcceleratorTarget* target); 252 253 // Unregister the specified keyboard accelerator for the specified target. 254 void UnregisterAccelerator(const ui::Accelerator& accelerator, 255 ui::AcceleratorTarget* target); 256 257 // Unregister all keyboard accelerator for the specified target. 258 void UnregisterAccelerators(ui::AcceleratorTarget* target); 259 260 // Activate the target associated with the specified accelerator. 261 // First, AcceleratorPressed handler of the most recently registered target 262 // is called, and if that handler processes the event (i.e. returns true), 263 // this method immediately returns. If not, we do the same thing on the next 264 // target, and so on. 265 // Returns true if an accelerator was activated. 266 bool ProcessAccelerator(const ui::Accelerator& accelerator); 267 268 // Resets menu key state if |event| is not menu key release. 269 // This is effective only on x11. 270 void MaybeResetMenuKeyState(const ui::KeyEvent& key); 271 272 // Called by a RootView when a view within its hierarchy is removed 273 // from its parent. This will only be called by a RootView in a 274 // hierarchy of Widgets that this FocusManager is attached to the 275 // parent Widget of. 276 void ViewRemoved(View* removed); 277 278 // Adds/removes a listener. The FocusChangeListener is notified every time 279 // the focused view is about to change. 280 void AddFocusChangeListener(FocusChangeListener* listener); 281 void RemoveFocusChangeListener(FocusChangeListener* listener); 282 283 // Returns the AcceleratorTarget that should be activated for the specified 284 // keyboard accelerator, or NULL if no view is registered for that keyboard 285 // accelerator. 286 ui::AcceleratorTarget* GetCurrentTargetForAccelerator( 287 const ui::Accelerator& accelertor) const; 288 289 // Whether the given |accelerator| has a priority handler associated with it. 290 bool HasPriorityHandler(const ui::Accelerator& accelerator) const; 291 292 // Clears the native view having the focus. 293 virtual void ClearNativeFocus(); 294 295 // Focuses the next keyboard-accessible pane, taken from the list of 296 // views returned by WidgetDelegate::GetAccessiblePanes(). If there are 297 // no panes, the widget's root view is treated as a single pane. 298 // A keyboard-accessible pane should subclass from AccessiblePaneView in 299 // order to trap keyboard focus within that pane. If |wrap| is kWrap, 300 // it keeps cycling within this widget, otherwise it returns false after 301 // reaching the last pane so that focus can cycle to another widget. 302 bool RotatePaneFocus(Direction direction, FocusCycleWrappingBehavior wrap); 303 304 // Convenience method that returns true if the passed |key_event| should 305 // trigger tab traversal (if it is a TAB key press with or without SHIFT 306 // pressed). 307 static bool IsTabTraversalKeyEvent(const ui::KeyEvent& key_event); 308 309 // Sets whether arrow key traversal is enabled. When enabled, right/down key 310 // behaves like tab and left/up key behaves like shift-tab. Note when this 311 // is enabled, the arrow key movement within grouped views are disabled. 312 static void set_arrow_key_traversal_enabled(bool enabled) { 313 arrow_key_traversal_enabled_ = enabled; 314 } 315 // Returns whether arrow key traversal is enabled. 316 static bool arrow_key_traversal_enabled() { 317 return arrow_key_traversal_enabled_; 318 } 319 320 // Returns the next focusable view. Traversal starts at |starting_view|. If 321 // |starting_view| is NULL |starting_widget| is consuled to determine which 322 // Widget to start from. See 323 // WidgetDelegate::ShouldAdvanceFocusToTopLevelWidget() for details. If both 324 // |starting_view| and |starting_widget| are NULL, traversal starts at 325 // |widget_|. 326 View* GetNextFocusableView(View* starting_view, 327 Widget* starting_widget, 328 bool reverse, 329 bool dont_loop); 330 331 private: 332 // Returns the focusable view found in the FocusTraversable specified starting 333 // at the specified view. This traverses down along the FocusTraversable 334 // hierarchy. 335 // Returns NULL if no focusable view were found. 336 View* FindFocusableView(FocusTraversable* focus_traversable, 337 View* starting_view, 338 bool reverse); 339 340 // Process arrow key traversal. Returns true if the event has been consumed 341 // and should not be processed further. 342 bool ProcessArrowKeyTraversal(const ui::KeyEvent& event); 343 344 // Keeps track of whether shortcut handling is currently suspended. 345 static bool shortcut_handling_suspended_; 346 347 // Whether arrow key traversal is enabled. 348 static bool arrow_key_traversal_enabled_; 349 350 // The top-level Widget this FocusManager is associated with. 351 Widget* widget_; 352 353 // The object which handles an accelerator when |accelerator_manager_| doesn't 354 // handle it. 355 scoped_ptr<FocusManagerDelegate> delegate_; 356 357 // The view that currently is focused. 358 View* focused_view_; 359 360 // The AcceleratorManager this FocusManager is associated with. 361 scoped_ptr<ui::AcceleratorManager> accelerator_manager_; 362 363 // The storage id used in the ViewStorage to store/restore the view that last 364 // had focus. 365 int stored_focused_view_storage_id_; 366 367 // The reason why the focus most recently changed. 368 FocusChangeReason focus_change_reason_; 369 370 // The list of registered FocusChange listeners. 371 ObserverList<FocusChangeListener, true> focus_change_listeners_; 372 373 // See description above getter. 374 bool is_changing_focus_; 375 376 DISALLOW_COPY_AND_ASSIGN(FocusManager); 377}; 378 379} // namespace views 380 381#endif // UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ 382