| 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(
|
|
|