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 #include "ui/views/focus/focus_manager.h" | 5 #include "ui/views/focus/focus_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "ui/base/accelerators/accelerator.h" | 12 #include "ui/base/accelerators/accelerator.h" |
13 #include "ui/base/accelerators/accelerator_manager.h" | |
14 #include "ui/base/keycodes/keyboard_codes.h" | 13 #include "ui/base/keycodes/keyboard_codes.h" |
15 #include "ui/views/focus/focus_search.h" | 14 #include "ui/views/focus/focus_search.h" |
16 #include "ui/views/focus/view_storage.h" | 15 #include "ui/views/focus/view_storage.h" |
17 #include "ui/views/focus/widget_focus_manager.h" | 16 #include "ui/views/focus/widget_focus_manager.h" |
18 #include "ui/views/view.h" | 17 #include "ui/views/view.h" |
19 #include "ui/views/widget/root_view.h" | 18 #include "ui/views/widget/root_view.h" |
20 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
21 | 20 |
22 namespace views { | 21 namespace views { |
23 | 22 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false); | 66 ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false); |
68 return ProcessAccelerator(accelerator); | 67 return ProcessAccelerator(accelerator); |
69 } else { | 68 } else { |
70 return false; | 69 return false; |
71 } | 70 } |
72 #else | 71 #else |
73 if (event.type() != ui::ET_KEY_PRESSED) | 72 if (event.type() != ui::ET_KEY_PRESSED) |
74 return false; | 73 return false; |
75 #endif | 74 #endif |
76 | 75 |
| 76 ui::Accelerator accelerator(event.key_code(), |
| 77 event.IsShiftDown(), |
| 78 event.IsControlDown(), |
| 79 event.IsAltDown()); |
| 80 |
77 #if defined(OS_WIN) | 81 #if defined(OS_WIN) |
78 // If the focused view wants to process the key event as is, let it be. | 82 // If the focused view wants to process the key event as is, let it be. |
79 // On Linux we always dispatch key events to the focused view first, so | 83 // On Linux we always dispatch key events to the focused view first, so |
80 // we should not do this check here. See also NativeWidgetGtk::OnKeyEvent(). | 84 // we should not do this check here. See also NativeWidgetGtk::OnKeyEvent(). |
81 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event)) | 85 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event) && |
| 86 !accelerator_manager_->HasPriorityHandler(accelerator)) |
82 return true; | 87 return true; |
83 #endif | 88 #endif |
84 | 89 |
85 // Intercept Tab related messages for focus traversal. | 90 // Intercept Tab related messages for focus traversal. |
86 // Note that we don't do focus traversal if the root window is not part of the | 91 // Note that we don't do focus traversal if the root window is not part of the |
87 // active window hierarchy as this would mean we have no focused view and | 92 // active window hierarchy as this would mean we have no focused view and |
88 // would focus the first focusable view. | 93 // would focus the first focusable view. |
89 #if defined(OS_WIN) && !defined(USE_AURA) | 94 #if defined(OS_WIN) && !defined(USE_AURA) |
90 HWND top_window = widget_->GetNativeView(); | 95 HWND top_window = widget_->GetNativeView(); |
91 HWND active_window = ::GetActiveWindow(); | 96 HWND active_window = ::GetActiveWindow(); |
(...skipping 26 matching lines...) Expand all Loading... |
118 } else if (index >= static_cast<int>(views.size())) { | 123 } else if (index >= static_cast<int>(views.size())) { |
119 index = 0; | 124 index = 0; |
120 } | 125 } |
121 SetFocusedViewWithReason(views[index], kReasonFocusTraversal); | 126 SetFocusedViewWithReason(views[index], kReasonFocusTraversal); |
122 return false; | 127 return false; |
123 } | 128 } |
124 | 129 |
125 // Process keyboard accelerators. | 130 // Process keyboard accelerators. |
126 // If the key combination matches an accelerator, the accelerator is | 131 // If the key combination matches an accelerator, the accelerator is |
127 // triggered, otherwise the key event is processed as usual. | 132 // triggered, otherwise the key event is processed as usual. |
128 ui::Accelerator accelerator(event.key_code(), | |
129 event.IsShiftDown(), | |
130 event.IsControlDown(), | |
131 event.IsAltDown()); | |
132 if (ProcessAccelerator(accelerator)) { | 133 if (ProcessAccelerator(accelerator)) { |
133 // If a shortcut was activated for this keydown message, do not propagate | 134 // If a shortcut was activated for this keydown message, do not propagate |
134 // the event further. | 135 // the event further. |
135 return false; | 136 return false; |
136 } | 137 } |
137 return true; | 138 return true; |
138 } | 139 } |
139 | 140 |
140 void FocusManager::ValidateFocusedView() { | 141 void FocusManager::ValidateFocusedView() { |
141 if (focused_view_) { | 142 if (focused_view_) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // Forget menu key state when the window lost focus. | 296 // Forget menu key state when the window lost focus. |
296 should_handle_menu_key_release_ = false; | 297 should_handle_menu_key_release_ = false; |
297 #endif | 298 #endif |
298 ViewStorage* view_storage = ViewStorage::GetInstance(); | 299 ViewStorage* view_storage = ViewStorage::GetInstance(); |
299 if (!view_storage) { | 300 if (!view_storage) { |
300 // This should never happen but bug 981648 seems to indicate it could. | 301 // This should never happen but bug 981648 seems to indicate it could. |
301 NOTREACHED(); | 302 NOTREACHED(); |
302 return; | 303 return; |
303 } | 304 } |
304 | 305 |
305 // TODO (jcampan): when a TabContents containing a popup is closed, the focus | 306 // TODO(jcivelli): when a TabContents containing a popup is closed, the focus |
306 // is stored twice causing an assert. We should find a better alternative than | 307 // is stored twice causing an assert. We should find a better alternative than |
307 // removing the view from the storage explicitly. | 308 // removing the view from the storage explicitly. |
308 view_storage->RemoveView(stored_focused_view_storage_id_); | 309 view_storage->RemoveView(stored_focused_view_storage_id_); |
309 | 310 |
310 if (!focused_view_) | 311 if (!focused_view_) |
311 return; | 312 return; |
312 | 313 |
313 view_storage->StoreView(stored_focused_view_storage_id_, focused_view_); | 314 view_storage->StoreView(stored_focused_view_storage_id_, focused_view_); |
314 | 315 |
315 View* v = focused_view_; | 316 View* v = focused_view_; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 FocusSearch::DOWN, | 399 FocusSearch::DOWN, |
399 false, | 400 false, |
400 &new_focus_traversable, | 401 &new_focus_traversable, |
401 &new_starting_view); | 402 &new_starting_view); |
402 } | 403 } |
403 return v; | 404 return v; |
404 } | 405 } |
405 | 406 |
406 void FocusManager::RegisterAccelerator( | 407 void FocusManager::RegisterAccelerator( |
407 const ui::Accelerator& accelerator, | 408 const ui::Accelerator& accelerator, |
| 409 ui::AcceleratorManager::HandlerPriority priority, |
408 ui::AcceleratorTarget* target) { | 410 ui::AcceleratorTarget* target) { |
409 accelerator_manager_->Register(accelerator, target); | 411 accelerator_manager_->Register(accelerator, priority, target); |
410 } | 412 } |
411 | 413 |
412 void FocusManager::UnregisterAccelerator(const ui::Accelerator& accelerator, | 414 void FocusManager::UnregisterAccelerator(const ui::Accelerator& accelerator, |
413 ui::AcceleratorTarget* target) { | 415 ui::AcceleratorTarget* target) { |
414 accelerator_manager_->Unregister(accelerator, target); | 416 accelerator_manager_->Unregister(accelerator, target); |
415 } | 417 } |
416 | 418 |
417 void FocusManager::UnregisterAccelerators(ui::AcceleratorTarget* target) { | 419 void FocusManager::UnregisterAccelerators(ui::AcceleratorTarget* target) { |
418 accelerator_manager_->UnregisterAll(target); | 420 accelerator_manager_->UnregisterAll(target); |
419 } | 421 } |
(...skipping 17 matching lines...) Expand all Loading... |
437 void FocusManager::ResetMenuKeyState() { | 439 void FocusManager::ResetMenuKeyState() { |
438 should_handle_menu_key_release_ = false; | 440 should_handle_menu_key_release_ = false; |
439 } | 441 } |
440 #endif | 442 #endif |
441 | 443 |
442 ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( | 444 ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( |
443 const ui::Accelerator& accelerator) const { | 445 const ui::Accelerator& accelerator) const { |
444 return accelerator_manager_->GetCurrentTarget(accelerator); | 446 return accelerator_manager_->GetCurrentTarget(accelerator); |
445 } | 447 } |
446 | 448 |
| 449 bool FocusManager::HasPriorityHandler( |
| 450 const ui::Accelerator& accelerator) const { |
| 451 return accelerator_manager_->HasPriorityHandler(accelerator); |
| 452 } |
| 453 |
447 // static | 454 // static |
448 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { | 455 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { |
449 return key_event.key_code() == ui::VKEY_TAB && !key_event.IsControlDown(); | 456 return key_event.key_code() == ui::VKEY_TAB && !key_event.IsControlDown(); |
450 } | 457 } |
451 | 458 |
452 void FocusManager::ViewRemoved(View* removed) { | 459 void FocusManager::ViewRemoved(View* removed) { |
453 // If the view being removed contains (or is) the focused view, | 460 // If the view being removed contains (or is) the focused view, |
454 // clear the focus. However, it's not safe to call ClearFocus() | 461 // clear the focus. However, it's not safe to call ClearFocus() |
455 // (and in turn ClearNativeFocus()) here because ViewRemoved() can | 462 // (and in turn ClearNativeFocus()) here because ViewRemoved() can |
456 // be called while the top level widget is being destroyed. | 463 // be called while the top level widget is being destroyed. |
457 if (focused_view_ && removed && removed->Contains(focused_view_)) | 464 if (focused_view_ && removed && removed->Contains(focused_view_)) |
458 SetFocusedView(NULL); | 465 SetFocusedView(NULL); |
459 } | 466 } |
460 | 467 |
461 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) { | 468 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) { |
462 focus_change_listeners_.AddObserver(listener); | 469 focus_change_listeners_.AddObserver(listener); |
463 } | 470 } |
464 | 471 |
465 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) { | 472 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) { |
466 focus_change_listeners_.RemoveObserver(listener); | 473 focus_change_listeners_.RemoveObserver(listener); |
467 } | 474 } |
468 | 475 |
469 } // namespace views | 476 } // namespace views |
OLD | NEW |