Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(901)

Side by Side Diff: ui/views/focus/focus_manager.cc

Issue 10134036: Let Chrome app handle Ash accelerators first if the app is launched as a window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: final rebase Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/focus/focus_manager_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/keycodes/keyboard_codes.h" 13 #include "ui/base/keycodes/keyboard_codes.h"
14 #include "ui/views/focus/focus_manager_delegate.h"
14 #include "ui/views/focus/focus_search.h" 15 #include "ui/views/focus/focus_search.h"
15 #include "ui/views/focus/view_storage.h" 16 #include "ui/views/focus/view_storage.h"
16 #include "ui/views/focus/widget_focus_manager.h" 17 #include "ui/views/focus/widget_focus_manager.h"
17 #include "ui/views/view.h" 18 #include "ui/views/view.h"
18 #include "ui/views/widget/root_view.h" 19 #include "ui/views/widget/root_view.h"
19 #include "ui/views/widget/widget.h" 20 #include "ui/views/widget/widget.h"
20 21
21 namespace views { 22 namespace views {
22 23
23 FocusManager::FocusManager(Widget* widget) 24 FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate)
24 : widget_(widget), 25 : widget_(widget),
26 delegate_(delegate),
25 focused_view_(NULL), 27 focused_view_(NULL),
26 accelerator_manager_(new ui::AcceleratorManager), 28 accelerator_manager_(new ui::AcceleratorManager),
27 focus_change_reason_(kReasonDirectFocusChange), 29 focus_change_reason_(kReasonDirectFocusChange),
28 #if defined(USE_X11) 30 #if defined(USE_X11)
29 should_handle_menu_key_release_(false), 31 should_handle_menu_key_release_(false),
30 #endif 32 #endif
31 is_changing_focus_(false) { 33 is_changing_focus_(false) {
32 DCHECK(widget_); 34 DCHECK(widget_);
33 stored_focused_view_storage_id_ = 35 stored_focused_view_storage_id_ =
34 ViewStorage::GetInstance()->CreateStorageID(); 36 ViewStorage::GetInstance()->CreateStorageID();
(...skipping 12 matching lines...) Expand all
47 // Always reset |should_handle_menu_key_release_| unless we are handling a 49 // Always reset |should_handle_menu_key_release_| unless we are handling a
48 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only 50 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
49 // be activated when handling a VKEY_MENU key release event which is preceded 51 // be activated when handling a VKEY_MENU key release event which is preceded
50 // by an un-handled VKEY_MENU key press event. 52 // by an un-handled VKEY_MENU key press event.
51 if (key_code != ui::VKEY_MENU || event.type() != ui::ET_KEY_RELEASED) 53 if (key_code != ui::VKEY_MENU || event.type() != ui::ET_KEY_RELEASED)
52 should_handle_menu_key_release_ = false; 54 should_handle_menu_key_release_ = false;
53 55
54 if (event.type() == ui::ET_KEY_PRESSED) { 56 if (event.type() == ui::ET_KEY_PRESSED) {
55 // VKEY_MENU is triggered by key release event. 57 // VKEY_MENU is triggered by key release event.
56 // FocusManager::OnKeyEvent() returns false when the key has been consumed. 58 // FocusManager::OnKeyEvent() returns false when the key has been consumed.
57 if (key_code == ui::VKEY_MENU) { 59 if ((key_code == ui::VKEY_MENU) &&
60 (event.flags() & ~ui::EF_ALT_DOWN) == 0) {
58 should_handle_menu_key_release_ = true; 61 should_handle_menu_key_release_ = true;
59 return false; 62 return false;
60 } 63 }
61 // Pass through to the reset of OnKeyEvent. 64 // Pass through to the rest of OnKeyEvent.
62 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && 65 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ &&
63 (event.flags() & ~ui::EF_ALT_DOWN) == 0) { 66 (event.flags() & ~ui::EF_ALT_DOWN) == 0) {
64 // Trigger VKEY_MENU when only this key is pressed and released, and both 67 // Trigger VKEY_MENU when only this key is pressed and released, and both
65 // press and release events are not handled by others. 68 // press and release events are not handled by others.
66 ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false); 69 ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false);
67 return ProcessAccelerator(accelerator); 70 return ProcessAccelerator(accelerator);
68 } else { 71 } else if (event.type() != ui::ET_KEY_RELEASED) {
69 return false; 72 return false;
70 } 73 }
71 #else 74 #else
72 if (event.type() != ui::ET_KEY_PRESSED) 75 if (event.type() != ui::ET_KEY_PRESSED && event.type() != ui::ET_KEY_RELEASED)
73 return false; 76 return false;
74 #endif 77 #endif
75 78
76 ui::Accelerator accelerator(event.key_code(), 79 ui::Accelerator accelerator(event.key_code(),
77 event.IsShiftDown(), 80 event.IsShiftDown(),
78 event.IsControlDown(), 81 event.IsControlDown(),
79 event.IsAltDown()); 82 event.IsAltDown());
83 accelerator.set_type(event.type());
80 84
85 if (event.type() == ui::ET_KEY_PRESSED) {
81 #if defined(OS_WIN) 86 #if defined(OS_WIN)
82 // If the focused view wants to process the key event as is, let it be. 87 // If the focused view wants to process the key event as is, let it be.
83 // This is not used for linux/aura. 88 // This is not used for linux/aura.
84 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event) && 89 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event) &&
85 !accelerator_manager_->HasPriorityHandler(accelerator)) 90 !accelerator_manager_->HasPriorityHandler(accelerator))
86 return true; 91 return true;
87 #endif 92 #endif
88 93
89 // Intercept Tab related messages for focus traversal. 94 // Intercept Tab related messages for focus traversal.
90 // Note that we don't do focus traversal if the root window is not part of the 95 // Note that we don't do focus traversal if the root window is not part of
91 // active window hierarchy as this would mean we have no focused view and 96 // the active window hierarchy as this would mean we have no focused view
92 // would focus the first focusable view. 97 // and would focus the first focusable view.
93 #if defined(OS_WIN) && !defined(USE_AURA) 98 #if defined(OS_WIN) && !defined(USE_AURA)
94 HWND top_window = widget_->GetNativeView(); 99 HWND top_window = widget_->GetNativeView();
95 HWND active_window = ::GetActiveWindow(); 100 HWND active_window = ::GetActiveWindow();
96 if ((active_window == top_window || ::IsChild(active_window, top_window)) && 101 if ((active_window == top_window || ::IsChild(active_window, top_window)) &&
97 IsTabTraversalKeyEvent(event)) { 102 IsTabTraversalKeyEvent(event)) {
98 AdvanceFocus(event.IsShiftDown()); 103 AdvanceFocus(event.IsShiftDown());
99 return false; 104 return false;
100 } 105 }
101 #else 106 #else
102 if (IsTabTraversalKeyEvent(event)) { 107 if (IsTabTraversalKeyEvent(event)) {
103 AdvanceFocus(event.IsShiftDown()); 108 AdvanceFocus(event.IsShiftDown());
104 return false; 109 return false;
105 } 110 }
106 #endif 111 #endif
107 112
108 // Intercept arrow key messages to switch between grouped views. 113 // Intercept arrow key messages to switch between grouped views.
109 if (focused_view_ && focused_view_->GetGroup() != -1 && 114 if (focused_view_ && focused_view_->GetGroup() != -1 &&
110 (key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN || 115 (key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN ||
111 key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT)) { 116 key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT)) {
112 bool next = (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN); 117 bool next = (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN);
113 View::Views views; 118 View::Views views;
114 focused_view_->parent()->GetViewsInGroup(focused_view_->GetGroup(), &views); 119 focused_view_->parent()->GetViewsInGroup(focused_view_->GetGroup(),
115 View::Views::const_iterator i( 120 &views);
116 std::find(views.begin(), views.end(), focused_view_)); 121 View::Views::const_iterator i(
117 DCHECK(i != views.end()); 122 std::find(views.begin(), views.end(), focused_view_));
118 int index = static_cast<int>(i - views.begin()); 123 DCHECK(i != views.end());
119 index += next ? 1 : -1; 124 int index = static_cast<int>(i - views.begin());
120 if (index < 0) { 125 index += next ? 1 : -1;
121 index = static_cast<int>(views.size()) - 1; 126 if (index < 0) {
122 } else if (index >= static_cast<int>(views.size())) { 127 index = static_cast<int>(views.size()) - 1;
123 index = 0; 128 } else if (index >= static_cast<int>(views.size())) {
129 index = 0;
130 }
131 SetFocusedViewWithReason(views[index], kReasonFocusTraversal);
132 return false;
124 } 133 }
125 SetFocusedViewWithReason(views[index], kReasonFocusTraversal);
126 return false;
127 } 134 }
128 135
129 // Process keyboard accelerators. 136 // Process keyboard accelerators.
130 // If the key combination matches an accelerator, the accelerator is 137 // If the key combination matches an accelerator, the accelerator is
131 // triggered, otherwise the key event is processed as usual. 138 // triggered, otherwise the key event is processed as usual.
132 if (ProcessAccelerator(accelerator)) { 139 if (ProcessAccelerator(accelerator)) {
133 // If a shortcut was activated for this keydown message, do not propagate 140 // If a shortcut was activated for this keydown message, do not propagate
134 // the event further. 141 // the event further.
135 return false; 142 return false;
136 } 143 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 void FocusManager::UnregisterAccelerator(const ui::Accelerator& accelerator, 420 void FocusManager::UnregisterAccelerator(const ui::Accelerator& accelerator,
414 ui::AcceleratorTarget* target) { 421 ui::AcceleratorTarget* target) {
415 accelerator_manager_->Unregister(accelerator, target); 422 accelerator_manager_->Unregister(accelerator, target);
416 } 423 }
417 424
418 void FocusManager::UnregisterAccelerators(ui::AcceleratorTarget* target) { 425 void FocusManager::UnregisterAccelerators(ui::AcceleratorTarget* target) {
419 accelerator_manager_->UnregisterAll(target); 426 accelerator_manager_->UnregisterAll(target);
420 } 427 }
421 428
422 bool FocusManager::ProcessAccelerator(const ui::Accelerator& accelerator) { 429 bool FocusManager::ProcessAccelerator(const ui::Accelerator& accelerator) {
423 return accelerator_manager_->Process(accelerator); 430 if (accelerator_manager_->Process(accelerator))
431 return true;
432 if (delegate_.get())
433 return delegate_->ProcessAccelerator(accelerator);
434 return false;
424 } 435 }
425 436
426 void FocusManager::MaybeResetMenuKeyState(const KeyEvent& key) { 437 void FocusManager::MaybeResetMenuKeyState(const KeyEvent& key) {
427 #if defined(USE_X11) 438 #if defined(USE_X11)
428 // Always reset |should_handle_menu_key_release_| unless we are handling a 439 // Always reset |should_handle_menu_key_release_| unless we are handling a
429 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only 440 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only
430 // be activated when handling a VKEY_MENU key release event which is preceded 441 // be activated when handling a VKEY_MENU key release event which is preceded
431 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent(). 442 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent().
432 if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) 443 if (key.key_code() != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED)
433 should_handle_menu_key_release_ = false; 444 should_handle_menu_key_release_ = false;
434 #endif 445 #endif
435 } 446 }
436 447
437 ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( 448 ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator(
438 const ui::Accelerator& accelerator) const { 449 const ui::Accelerator& accelerator) const {
439 return accelerator_manager_->GetCurrentTarget(accelerator); 450 ui::AcceleratorTarget* target =
451 accelerator_manager_->GetCurrentTarget(accelerator);
452 if (!target && delegate_.get())
453 target = delegate_->GetCurrentTargetForAccelerator(accelerator);
454 return target;
440 } 455 }
441 456
442 bool FocusManager::HasPriorityHandler( 457 bool FocusManager::HasPriorityHandler(
443 const ui::Accelerator& accelerator) const { 458 const ui::Accelerator& accelerator) const {
444 return accelerator_manager_->HasPriorityHandler(accelerator); 459 return accelerator_manager_->HasPriorityHandler(accelerator);
445 } 460 }
446 461
447 // static 462 // static
448 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { 463 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) {
449 return key_event.key_code() == ui::VKEY_TAB && !key_event.IsControlDown(); 464 return key_event.key_code() == ui::VKEY_TAB && !key_event.IsControlDown();
(...skipping 10 matching lines...) Expand all
460 475
461 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) { 476 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) {
462 focus_change_listeners_.AddObserver(listener); 477 focus_change_listeners_.AddObserver(listener);
463 } 478 }
464 479
465 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) { 480 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) {
466 focus_change_listeners_.RemoveObserver(listener); 481 focus_change_listeners_.RemoveObserver(listener);
467 } 482 }
468 483
469 } // namespace views 484 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/focus/focus_manager_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698