Index: ui/views/focus/focus_manager.cc |
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc |
index 1467f252275335f1088af327941b2284b997f76b..1799831f9e77931a5d76dbd6fb0bdf99df58cf5b 100644 |
--- a/ui/views/focus/focus_manager.cc |
+++ b/ui/views/focus/focus_manager.cc |
@@ -11,6 +11,7 @@ |
#include "build/build_config.h" |
#include "ui/base/accelerators/accelerator.h" |
#include "ui/base/keycodes/keyboard_codes.h" |
+#include "ui/views/focus/focus_manager_delegate.h" |
#include "ui/views/focus/focus_search.h" |
#include "ui/views/focus/view_storage.h" |
#include "ui/views/focus/widget_focus_manager.h" |
@@ -20,8 +21,9 @@ |
namespace views { |
-FocusManager::FocusManager(Widget* widget) |
+FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate) |
: widget_(widget), |
+ delegate_(delegate), |
focused_view_(NULL), |
accelerator_manager_(new ui::AcceleratorManager), |
focus_change_reason_(kReasonDirectFocusChange), |
@@ -54,22 +56,23 @@ bool FocusManager::OnKeyEvent(const KeyEvent& event) { |
if (event.type() == ui::ET_KEY_PRESSED) { |
// VKEY_MENU is triggered by key release event. |
// FocusManager::OnKeyEvent() returns false when the key has been consumed. |
- if (key_code == ui::VKEY_MENU) { |
+ if ((key_code == ui::VKEY_MENU) && |
+ (event.flags() & ~ui::EF_ALT_DOWN) == 0) { |
should_handle_menu_key_release_ = true; |
return false; |
} |
- // Pass through to the reset of OnKeyEvent. |
+ // Pass through to the rest of OnKeyEvent. |
} else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && |
(event.flags() & ~ui::EF_ALT_DOWN) == 0) { |
// Trigger VKEY_MENU when only this key is pressed and released, and both |
// press and release events are not handled by others. |
ui::Accelerator accelerator(ui::VKEY_MENU, false, false, false); |
return ProcessAccelerator(accelerator); |
- } else { |
+ } else if (event.type() != ui::ET_KEY_RELEASED) { |
return false; |
} |
#else |
- if (event.type() != ui::ET_KEY_PRESSED) |
+ if (event.type() != ui::ET_KEY_PRESSED && event.type() != ui::ET_KEY_RELEASED) |
return false; |
#endif |
@@ -77,53 +80,57 @@ bool FocusManager::OnKeyEvent(const KeyEvent& event) { |
event.IsShiftDown(), |
event.IsControlDown(), |
event.IsAltDown()); |
+ accelerator.set_type(event.type()); |
+ if (event.type() == ui::ET_KEY_PRESSED) { |
#if defined(OS_WIN) |
- // If the focused view wants to process the key event as is, let it be. |
- // This is not used for linux/aura. |
- if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event) && |
- !accelerator_manager_->HasPriorityHandler(accelerator)) |
- return true; |
+ // If the focused view wants to process the key event as is, let it be. |
+ // This is not used for linux/aura. |
+ if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event) && |
+ !accelerator_manager_->HasPriorityHandler(accelerator)) |
+ return true; |
#endif |
- // Intercept Tab related messages for focus traversal. |
- // Note that we don't do focus traversal if the root window is not part of the |
- // active window hierarchy as this would mean we have no focused view and |
- // would focus the first focusable view. |
+ // Intercept Tab related messages for focus traversal. |
+ // Note that we don't do focus traversal if the root window is not part of |
+ // the active window hierarchy as this would mean we have no focused view |
+ // and would focus the first focusable view. |
#if defined(OS_WIN) && !defined(USE_AURA) |
- HWND top_window = widget_->GetNativeView(); |
- HWND active_window = ::GetActiveWindow(); |
- if ((active_window == top_window || ::IsChild(active_window, top_window)) && |
- IsTabTraversalKeyEvent(event)) { |
- AdvanceFocus(event.IsShiftDown()); |
- return false; |
- } |
+ HWND top_window = widget_->GetNativeView(); |
+ HWND active_window = ::GetActiveWindow(); |
+ if ((active_window == top_window || ::IsChild(active_window, top_window)) && |
+ IsTabTraversalKeyEvent(event)) { |
+ AdvanceFocus(event.IsShiftDown()); |
+ return false; |
+ } |
#else |
- if (IsTabTraversalKeyEvent(event)) { |
- AdvanceFocus(event.IsShiftDown()); |
- return false; |
- } |
+ if (IsTabTraversalKeyEvent(event)) { |
+ AdvanceFocus(event.IsShiftDown()); |
+ return false; |
+ } |
#endif |
- // Intercept arrow key messages to switch between grouped views. |
- if (focused_view_ && focused_view_->GetGroup() != -1 && |
- (key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN || |
- key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT)) { |
- bool next = (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN); |
- View::Views views; |
- focused_view_->parent()->GetViewsInGroup(focused_view_->GetGroup(), &views); |
- View::Views::const_iterator i( |
- std::find(views.begin(), views.end(), focused_view_)); |
- DCHECK(i != views.end()); |
- int index = static_cast<int>(i - views.begin()); |
- index += next ? 1 : -1; |
- if (index < 0) { |
- index = static_cast<int>(views.size()) - 1; |
- } else if (index >= static_cast<int>(views.size())) { |
- index = 0; |
+ // Intercept arrow key messages to switch between grouped views. |
+ if (focused_view_ && focused_view_->GetGroup() != -1 && |
+ (key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN || |
+ key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT)) { |
+ bool next = (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN); |
+ View::Views views; |
+ focused_view_->parent()->GetViewsInGroup(focused_view_->GetGroup(), |
+ &views); |
+ View::Views::const_iterator i( |
+ std::find(views.begin(), views.end(), focused_view_)); |
+ DCHECK(i != views.end()); |
+ int index = static_cast<int>(i - views.begin()); |
+ index += next ? 1 : -1; |
+ if (index < 0) { |
+ index = static_cast<int>(views.size()) - 1; |
+ } else if (index >= static_cast<int>(views.size())) { |
+ index = 0; |
+ } |
+ SetFocusedViewWithReason(views[index], kReasonFocusTraversal); |
+ return false; |
} |
- SetFocusedViewWithReason(views[index], kReasonFocusTraversal); |
- return false; |
} |
// Process keyboard accelerators. |
@@ -420,7 +427,11 @@ void FocusManager::UnregisterAccelerators(ui::AcceleratorTarget* target) { |
} |
bool FocusManager::ProcessAccelerator(const ui::Accelerator& accelerator) { |
- return accelerator_manager_->Process(accelerator); |
+ if (accelerator_manager_->Process(accelerator)) |
+ return true; |
+ if (delegate_.get()) |
+ return delegate_->ProcessAccelerator(accelerator); |
+ return false; |
} |
void FocusManager::MaybeResetMenuKeyState(const KeyEvent& key) { |
@@ -436,7 +447,11 @@ void FocusManager::MaybeResetMenuKeyState(const KeyEvent& key) { |
ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( |
const ui::Accelerator& accelerator) const { |
- return accelerator_manager_->GetCurrentTarget(accelerator); |
+ ui::AcceleratorTarget* target = |
+ accelerator_manager_->GetCurrentTarget(accelerator); |
+ if (!target && delegate_.get()) |
+ target = delegate_->GetCurrentTargetForAccelerator(accelerator); |
+ return target; |
} |
bool FocusManager::HasPriorityHandler( |