Home | History | Annotate | Download | only in accelerators
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ash/accelerators/nested_accelerator_delegate.h"
      6 
      7 #include "ash/accelerators/accelerator_controller.h"
      8 #include "ash/shell.h"
      9 #include "ui/aura/window_event_dispatcher.h"
     10 #include "ui/base/accelerators/accelerator.h"
     11 #include "ui/events/event.h"
     12 #include "ui/events/event_constants.h"
     13 #include "ui/events/event_utils.h"
     14 #include "ui/views/controls/menu/menu_controller.h"
     15 
     16 namespace ash {
     17 namespace {
     18 
     19 bool IsPossibleAcceleratorNotForMenu(const ui::Accelerator& accelerator) {
     20   // For shortcuts generated by Ctrl or Alt plus a letter, number or
     21   // the tab key, we want to exit the context menu first and then
     22   // repost the event. That allows for the shortcut execution after
     23   // the context menu has exited.
     24   if (accelerator.type() == ui::ET_KEY_PRESSED &&
     25       (accelerator.modifiers() & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN))) {
     26     const ui::KeyboardCode key_code = accelerator.key_code();
     27     if ((key_code >= ui::VKEY_A && key_code <= ui::VKEY_Z) ||
     28         (key_code >= ui::VKEY_0 && key_code <= ui::VKEY_9) ||
     29         (key_code == ui::VKEY_TAB)) {
     30       return true;
     31     }
     32   }
     33   return false;
     34 }
     35 
     36 bool ShouldProcessAcceleratorNow(const ui::Accelerator& accelerator) {
     37   if (!IsPossibleAcceleratorNotForMenu(accelerator))
     38     return true;
     39 
     40   if (views::MenuController* menu_controller =
     41           views::MenuController::GetActiveInstance()) {
     42     menu_controller->CancelAll();
     43     return false;
     44   }
     45   return true;
     46 }
     47 
     48 }  // namespace
     49 
     50 NestedAcceleratorDelegate::NestedAcceleratorDelegate() {
     51 }
     52 
     53 NestedAcceleratorDelegate::~NestedAcceleratorDelegate() {
     54 }
     55 
     56 NestedAcceleratorDelegate::Result NestedAcceleratorDelegate::ProcessAccelerator(
     57     const ui::Accelerator& accelerator) {
     58   if (!ShouldProcessAcceleratorNow(accelerator))
     59     return RESULT_PROCESS_LATER;
     60 
     61   ash::AcceleratorController* accelerator_controller =
     62       ash::Shell::GetInstance()->accelerator_controller();
     63   if (!accelerator_controller)
     64     return RESULT_NOT_PROCESSED;
     65   return accelerator_controller->Process(accelerator) ? RESULT_PROCESSED
     66                                                       : RESULT_NOT_PROCESSED;
     67 }
     68 
     69 }  // namespace ash
     70