| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ | 5 #ifndef UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ |
| 6 #define UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ | 6 #define UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ |
| 7 | 7 |
| 8 #include <list> | 8 #include <list> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/observer_list.h" | 13 #include "base/observer_list.h" |
| 14 #include "ui/base/accelerators/accelerator.h" | 14 #include "ui/base/accelerators/accelerator.h" |
| 15 #include "ui/base/accelerators/accelerator_manager.h" | 15 #include "ui/base/accelerators/accelerator_manager.h" |
| 16 #include "ui/base/accelerators/accelerator_processor.h" |
| 16 #include "ui/gfx/native_widget_types.h" | 17 #include "ui/gfx/native_widget_types.h" |
| 17 #include "ui/views/views_export.h" | 18 #include "ui/views/views_export.h" |
| 18 | 19 |
| 19 // The FocusManager class is used to handle focus traversal, store/restore | 20 // The FocusManager class is used to handle focus traversal, store/restore |
| 20 // focused views and handle keyboard accelerators. | 21 // focused views and handle keyboard accelerators. |
| 21 // | 22 // |
| 22 // There are 2 types of focus: | 23 // There are 2 types of focus: |
| 23 // - the native focus, which is the focus that an gfx::NativeView has. | 24 // - 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 // - the view focus, which is the focus that a views::View has. |
| 25 // | 26 // |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 // No change to focus state has occurred yet when this function is called. | 114 // No change to focus state has occurred yet when this function is called. |
| 114 virtual void OnWillChangeFocus(View* focused_before, View* focused_now) = 0; | 115 virtual void OnWillChangeFocus(View* focused_before, View* focused_now) = 0; |
| 115 | 116 |
| 116 // Called after focus state has changed. | 117 // Called after focus state has changed. |
| 117 virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0; | 118 virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0; |
| 118 | 119 |
| 119 protected: | 120 protected: |
| 120 virtual ~FocusChangeListener() {} | 121 virtual ~FocusChangeListener() {} |
| 121 }; | 122 }; |
| 122 | 123 |
| 123 class VIEWS_EXPORT FocusManager { | 124 class VIEWS_EXPORT FocusManager : public ui::AcceleratorProcessor { |
| 124 public: | 125 public: |
| 125 // The reason why the focus changed. | 126 // The reason why the focus changed. |
| 126 enum FocusChangeReason { | 127 enum FocusChangeReason { |
| 127 // The focus changed because the user traversed focusable views using | 128 // The focus changed because the user traversed focusable views using |
| 128 // keys like Tab or Shift+Tab. | 129 // keys like Tab or Shift+Tab. |
| 129 kReasonFocusTraversal, | 130 kReasonFocusTraversal, |
| 130 | 131 |
| 131 // The focus changed due to restoring the focus. | 132 // The focus changed due to restoring the focus. |
| 132 kReasonFocusRestore, | 133 kReasonFocusRestore, |
| 133 | 134 |
| 134 // The focus changed due to a click or a shortcut to jump directly to | 135 // The focus changed due to a click or a shortcut to jump directly to |
| 135 // a particular view. | 136 // a particular view. |
| 136 kReasonDirectFocusChange | 137 kReasonDirectFocusChange |
| 137 }; | 138 }; |
| 138 | 139 |
| 139 // TODO: use Direction in place of bool reverse throughout. | 140 // TODO: use Direction in place of bool reverse throughout. |
| 140 enum Direction { | 141 enum Direction { |
| 141 kForward, | 142 kForward, |
| 142 kBackward | 143 kBackward |
| 143 }; | 144 }; |
| 144 | 145 |
| 145 enum FocusCycleWrappingBehavior { | 146 enum FocusCycleWrappingBehavior { |
| 146 kWrap, | 147 kWrap, |
| 147 kNoWrap | 148 kNoWrap |
| 148 }; | 149 }; |
| 149 | 150 |
| 150 FocusManager(Widget* widget, FocusManagerDelegate* delegate); | 151 explicit FocusManager(Widget* widget); |
| 151 virtual ~FocusManager(); | 152 ~FocusManager() override; |
| 152 | 153 |
| 153 // Processes the passed key event for accelerators and keyboard traversal. | 154 // Processes the passed key event for accelerators and keyboard traversal. |
| 154 // Returns false if the event has been consumed and should not be processed | 155 // Returns false if the event has been consumed and should not be processed |
| 155 // further. | 156 // further. |
| 156 bool OnKeyEvent(const ui::KeyEvent& event); | 157 bool OnKeyEvent(const ui::KeyEvent& event); |
| 157 | 158 |
| 158 // Returns true is the specified is part of the hierarchy of the window | 159 // Returns true is the specified is part of the hierarchy of the window |
| 159 // associated with this FocusManager. | 160 // associated with this FocusManager. |
| 160 bool ContainsView(View* view); | 161 bool ContainsView(View* view); |
| 161 | 162 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 | 219 |
| 219 // Changes the text input focus to |view->GetTextInputClient()| iff |view| | 220 // Changes the text input focus to |view->GetTextInputClient()| iff |view| |
| 220 // is focused. Views must call this method when their internal | 221 // is focused. Views must call this method when their internal |
| 221 // TextInputClient instance changes. | 222 // TextInputClient instance changes. |
| 222 void OnTextInputClientChanged(View* view); | 223 void OnTextInputClientChanged(View* view); |
| 223 | 224 |
| 224 // Moves the text input focus into/out from |view|. | 225 // Moves the text input focus into/out from |view|. |
| 225 void FocusTextInputClient(View* view); | 226 void FocusTextInputClient(View* view); |
| 226 void BlurTextInputClient(View* view); | 227 void BlurTextInputClient(View* view); |
| 227 | 228 |
| 228 // Disable shortcut handling. | |
| 229 static void set_shortcut_handling_suspended(bool suspended) { | |
| 230 shortcut_handling_suspended_ = suspended; | |
| 231 } | |
| 232 // Returns whether shortcut handling is currently suspended. | |
| 233 bool shortcut_handling_suspended() { return shortcut_handling_suspended_; } | |
| 234 | |
| 235 // Register a keyboard accelerator for the specified target. If multiple | 229 // Register a keyboard accelerator for the specified target. If multiple |
| 236 // targets are registered for an accelerator, a target registered later has | 230 // targets are registered for an accelerator, a target registered later has |
| 237 // higher priority. | 231 // higher priority. |
| 238 // |accelerator| is the accelerator to register. | 232 // |accelerator| is the accelerator to register. |
| 239 // |priority| denotes the priority of the handler. | 233 // |priority| denotes the priority of the handler. |
| 240 // NOTE: In almost all cases, you should specify kNormalPriority for this | 234 // NOTE: In almost all cases, you should specify kNormalPriority for this |
| 241 // parameter. Setting it to kHighPriority prevents Chrome from sending the | 235 // parameter. Setting it to kHighPriority prevents Chrome from sending the |
| 242 // shortcut to the webpage if the renderer has focus, which is not desirable | 236 // shortcut to the webpage if the renderer has focus, which is not desirable |
| 243 // except for very isolated cases. | 237 // except for very isolated cases. |
| 244 // |target| is the AcceleratorTarget that handles the event once the | 238 // |target| is the AcceleratorTarget that handles the event once the |
| 245 // accelerator is pressed. | 239 // accelerator is pressed. |
| 246 // Note that we are currently limited to accelerators that are either: | 240 // Note that we are currently limited to accelerators that are either: |
| 247 // - a key combination including Ctrl or Alt | 241 // - a key combination including Ctrl or Alt |
| 248 // - the escape key | 242 // - the escape key |
| 249 // - the enter key | 243 // - the enter key |
| 250 // - any F key (F1, F2, F3 ...) | 244 // - any F key (F1, F2, F3 ...) |
| 251 // - any browser specific keys (as available on special keyboards) | 245 // - any browser specific keys (as available on special keyboards) |
| 252 void RegisterAccelerator(const ui::Accelerator& accelerator, | 246 void RegisterAccelerator(const ui::Accelerator& accelerator, |
| 253 ui::AcceleratorManager::HandlerPriority priority, | 247 ui::AcceleratorManager::HandlerPriority priority, |
| 254 ui::AcceleratorTarget* target); | 248 ui::AcceleratorTarget* target); |
| 255 | 249 |
| 256 // Unregister the specified keyboard accelerator for the specified target. | 250 // Unregister the specified keyboard accelerator for the specified target. |
| 257 void UnregisterAccelerator(const ui::Accelerator& accelerator, | 251 void UnregisterAccelerator(const ui::Accelerator& accelerator, |
| 258 ui::AcceleratorTarget* target); | 252 ui::AcceleratorTarget* target); |
| 259 | 253 |
| 260 // Unregister all keyboard accelerator for the specified target. | 254 // Unregister all keyboard accelerator for the specified target. |
| 261 void UnregisterAccelerators(ui::AcceleratorTarget* target); | 255 void UnregisterAccelerators(ui::AcceleratorTarget* target); |
| 262 | 256 |
| 263 // Activate the target associated with the specified accelerator. | |
| 264 // First, AcceleratorPressed handler of the most recently registered target | |
| 265 // is called, and if that handler processes the event (i.e. returns true), | |
| 266 // this method immediately returns. If not, we do the same thing on the next | |
| 267 // target, and so on. | |
| 268 // Returns true if an accelerator was activated. | |
| 269 bool ProcessAccelerator(const ui::Accelerator& accelerator); | |
| 270 | |
| 271 // Resets menu key state if |event| is not menu key release. | 257 // Resets menu key state if |event| is not menu key release. |
| 272 // This is effective only on x11. | 258 // This is effective only on x11. |
| 273 void MaybeResetMenuKeyState(const ui::KeyEvent& key); | 259 void MaybeResetMenuKeyState(const ui::KeyEvent& key); |
| 274 | 260 |
| 275 // Called by a RootView when a view within its hierarchy is removed | 261 // Called by a RootView when a view within its hierarchy is removed |
| 276 // from its parent. This will only be called by a RootView in a | 262 // from its parent. This will only be called by a RootView in a |
| 277 // hierarchy of Widgets that this FocusManager is attached to the | 263 // hierarchy of Widgets that this FocusManager is attached to the |
| 278 // parent Widget of. | 264 // parent Widget of. |
| 279 void ViewRemoved(View* removed); | 265 void ViewRemoved(View* removed); |
| 280 | 266 |
| 281 // Adds/removes a listener. The FocusChangeListener is notified every time | 267 // Adds/removes a listener. The FocusChangeListener is notified every time |
| 282 // the focused view is about to change. | 268 // the focused view is about to change. |
| 283 void AddFocusChangeListener(FocusChangeListener* listener); | 269 void AddFocusChangeListener(FocusChangeListener* listener); |
| 284 void RemoveFocusChangeListener(FocusChangeListener* listener); | 270 void RemoveFocusChangeListener(FocusChangeListener* listener); |
| 285 | 271 |
| 286 // Returns the AcceleratorTarget that should be activated for the specified | 272 // Adds/removes an accelerator processor. |
| 287 // keyboard accelerator, or NULL if no view is registered for that keyboard | 273 // PreProcessors are given a chance to process an accelerator before normal |
| 288 // accelerator. | 274 // processing. |
| 289 ui::AcceleratorTarget* GetCurrentTargetForAccelerator( | 275 // PostProcessors are given a chance to process unhandled accelerators. |
| 290 const ui::Accelerator& accelerator) const; | 276 void AddAcceleratorPreProcessor(ui::AcceleratorProcessor* processor); |
| 277 void AddAcceleratorPostProcessor(ui::AcceleratorProcessor* processor); |
| 278 void RemoveAcceleratorProcessor(ui::AcceleratorProcessor* processor); |
| 291 | 279 |
| 292 // Whether the given |accelerator| has a priority handler associated with it. | 280 // Whether the given |accelerator| has a priority handler associated with it. |
| 293 bool HasPriorityHandler(const ui::Accelerator& accelerator) const; | 281 bool HasPriorityHandler(const ui::Accelerator& accelerator) const; |
| 294 | 282 |
| 295 // Clears the native view having the focus. | 283 // Clears the native view having the focus. |
| 296 virtual void ClearNativeFocus(); | 284 virtual void ClearNativeFocus(); |
| 297 | 285 |
| 298 // Focuses the next keyboard-accessible pane, taken from the list of | 286 // Focuses the next keyboard-accessible pane, taken from the list of |
| 299 // views returned by WidgetDelegate::GetAccessiblePanes(). If there are | 287 // views returned by WidgetDelegate::GetAccessiblePanes(). If there are |
| 300 // no panes, the widget's root view is treated as a single pane. | 288 // no panes, the widget's root view is treated as a single pane. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 324 // |starting_view| is NULL |starting_widget| is consuled to determine which | 312 // |starting_view| is NULL |starting_widget| is consuled to determine which |
| 325 // Widget to start from. See | 313 // Widget to start from. See |
| 326 // WidgetDelegate::ShouldAdvanceFocusToTopLevelWidget() for details. If both | 314 // WidgetDelegate::ShouldAdvanceFocusToTopLevelWidget() for details. If both |
| 327 // |starting_view| and |starting_widget| are NULL, traversal starts at | 315 // |starting_view| and |starting_widget| are NULL, traversal starts at |
| 328 // |widget_|. | 316 // |widget_|. |
| 329 View* GetNextFocusableView(View* starting_view, | 317 View* GetNextFocusableView(View* starting_view, |
| 330 Widget* starting_widget, | 318 Widget* starting_widget, |
| 331 bool reverse, | 319 bool reverse, |
| 332 bool dont_loop); | 320 bool dont_loop); |
| 333 | 321 |
| 322 // Overridden from ui::AcceleratorProcessor: |
| 323 bool ProcessAccelerator(const ui::Accelerator& accelerator) override; |
| 324 ui::AcceleratorTarget* GetTargetForAccelerator( |
| 325 const ui::Accelerator& accelerator) const override; |
| 326 |
| 334 private: | 327 private: |
| 335 // Returns the focusable view found in the FocusTraversable specified starting | 328 // Returns the focusable view found in the FocusTraversable specified starting |
| 336 // at the specified view. This traverses down along the FocusTraversable | 329 // at the specified view. This traverses down along the FocusTraversable |
| 337 // hierarchy. | 330 // hierarchy. |
| 338 // Returns NULL if no focusable view were found. | 331 // Returns NULL if no focusable view were found. |
| 339 View* FindFocusableView(FocusTraversable* focus_traversable, | 332 View* FindFocusableView(FocusTraversable* focus_traversable, |
| 340 View* starting_view, | 333 View* starting_view, |
| 341 bool reverse); | 334 bool reverse); |
| 342 | 335 |
| 343 // Process arrow key traversal. Returns true if the event has been consumed | 336 // Process arrow key traversal. Returns true if the event has been consumed |
| 344 // and should not be processed further. | 337 // and should not be processed further. |
| 345 bool ProcessArrowKeyTraversal(const ui::KeyEvent& event); | 338 bool ProcessArrowKeyTraversal(const ui::KeyEvent& event); |
| 346 | 339 |
| 347 // Keeps track of whether shortcut handling is currently suspended. | |
| 348 static bool shortcut_handling_suspended_; | |
| 349 | |
| 350 // Whether arrow key traversal is enabled. | 340 // Whether arrow key traversal is enabled. |
| 351 static bool arrow_key_traversal_enabled_; | 341 static bool arrow_key_traversal_enabled_; |
| 352 | 342 |
| 353 // The top-level Widget this FocusManager is associated with. | 343 // The top-level Widget this FocusManager is associated with. |
| 354 Widget* widget_; | 344 Widget* widget_; |
| 355 | 345 |
| 356 // The object which handles an accelerator when |accelerator_manager_| doesn't | |
| 357 // handle it. | |
| 358 scoped_ptr<FocusManagerDelegate> delegate_; | |
| 359 | |
| 360 // The view that currently is focused. | 346 // The view that currently is focused. |
| 361 View* focused_view_; | 347 View* focused_view_; |
| 362 | 348 |
| 363 // The AcceleratorManager this FocusManager is associated with. | 349 // The AcceleratorManager this FocusManager is associated with. |
| 364 scoped_ptr<ui::AcceleratorManager> accelerator_manager_; | 350 scoped_ptr<ui::AcceleratorManager> accelerator_manager_; |
| 365 | 351 |
| 352 std::list<ui::AcceleratorProcessor*> accelerator_processors_; |
| 353 |
| 366 // The storage id used in the ViewStorage to store/restore the view that last | 354 // The storage id used in the ViewStorage to store/restore the view that last |
| 367 // had focus. | 355 // had focus. |
| 368 int stored_focused_view_storage_id_; | 356 int stored_focused_view_storage_id_; |
| 369 | 357 |
| 370 // The reason why the focus most recently changed. | 358 // The reason why the focus most recently changed. |
| 371 FocusChangeReason focus_change_reason_; | 359 FocusChangeReason focus_change_reason_; |
| 372 | 360 |
| 373 // The list of registered FocusChange listeners. | 361 // The list of registered FocusChange listeners. |
| 374 ObserverList<FocusChangeListener, true> focus_change_listeners_; | 362 ObserverList<FocusChangeListener, true> focus_change_listeners_; |
| 375 | 363 |
| 376 // See description above getter. | 364 // See description above getter. |
| 377 bool is_changing_focus_; | 365 bool is_changing_focus_; |
| 378 | 366 |
| 379 DISALLOW_COPY_AND_ASSIGN(FocusManager); | 367 DISALLOW_COPY_AND_ASSIGN(FocusManager); |
| 380 }; | 368 }; |
| 381 | 369 |
| 382 } // namespace views | 370 } // namespace views |
| 383 | 371 |
| 384 #endif // UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ | 372 #endif // UI_VIEWS_FOCUS_FOCUS_MANAGER_H_ |
| OLD | NEW |