Home | History | Annotate | Download | only in input
      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 "athena/input/accelerator_manager_impl.h"
      6 
      7 #include "athena/common/switches.h"
      8 #include "athena/input/public/input_manager.h"
      9 #include "base/logging.h"
     10 #include "ui/aura/window.h"
     11 #include "ui/base/accelerators/accelerator_manager.h"
     12 #include "ui/events/event.h"
     13 #include "ui/events/event_target.h"
     14 #include "ui/views/focus/focus_manager.h"
     15 #include "ui/views/focus/focus_manager_delegate.h"
     16 #include "ui/views/focus/focus_manager_factory.h"
     17 #include "ui/wm/core/accelerator_delegate.h"
     18 #include "ui/wm/core/accelerator_filter.h"
     19 #include "ui/wm/core/nested_accelerator_controller.h"
     20 #include "ui/wm/core/nested_accelerator_delegate.h"
     21 #include "ui/wm/public/dispatcher_client.h"
     22 
     23 namespace athena {
     24 
     25 // This wrapper interface provides a common interface that handles global
     26 // accelerators as well as local accelerators.
     27 class AcceleratorManagerImpl::AcceleratorWrapper {
     28  public:
     29   virtual ~AcceleratorWrapper() {}
     30   virtual void Register(const ui::Accelerator& accelerator,
     31                         ui::AcceleratorTarget* target) = 0;
     32   virtual bool Process(const ui::Accelerator& accelerator) = 0;
     33   virtual ui::AcceleratorTarget* GetCurrentTarget(
     34       const ui::Accelerator& accelertor) const = 0;
     35 };
     36 
     37 namespace {
     38 
     39 // Accelerators inside nested message loop are handled by
     40 // wm::NestedAcceleratorController while accelerators in normal case are
     41 // handled by wm::AcceleratorFilter. These delegates act bridges in these
     42 // two different environment so that AcceleratorManagerImpl can handle
     43 // accelerators in an uniform way.
     44 
     45 class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate {
     46  public:
     47   explicit NestedAcceleratorDelegate(
     48       AcceleratorManagerImpl* accelerator_manager)
     49       : accelerator_manager_(accelerator_manager) {}
     50   virtual ~NestedAcceleratorDelegate() {}
     51 
     52  private:
     53   // wm::NestedAcceleratorDelegate:
     54   virtual Result ProcessAccelerator(
     55       const ui::Accelerator& accelerator) OVERRIDE {
     56     return accelerator_manager_->Process(accelerator) ? RESULT_PROCESSED
     57                                                       : RESULT_NOT_PROCESSED;
     58   }
     59 
     60   AcceleratorManagerImpl* accelerator_manager_;
     61 
     62   DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate);
     63 };
     64 
     65 class AcceleratorDelegate : public wm::AcceleratorDelegate {
     66  public:
     67   explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager)
     68       : accelerator_manager_(accelerator_manager) {}
     69   virtual ~AcceleratorDelegate() {}
     70 
     71  private:
     72   // wm::AcceleratorDelegate:
     73   virtual bool ProcessAccelerator(const ui::KeyEvent& event,
     74                                   const ui::Accelerator& accelerator,
     75                                   KeyType key_type) OVERRIDE {
     76     aura::Window* target = static_cast<aura::Window*>(event.target());
     77     if (!target->IsRootWindow() &&
     78         !accelerator_manager_->IsRegistered(accelerator, AF_RESERVED)) {
     79       // TODO(oshima): do the same when the active window is in fullscreen.
     80       return false;
     81     }
     82     return accelerator_manager_->Process(accelerator);
     83   }
     84 
     85   AcceleratorManagerImpl* accelerator_manager_;
     86   DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate);
     87 };
     88 
     89 class FocusManagerDelegate : public views::FocusManagerDelegate {
     90  public:
     91   explicit FocusManagerDelegate(AcceleratorManagerImpl* accelerator_manager)
     92       : accelerator_manager_(accelerator_manager) {}
     93   virtual ~FocusManagerDelegate() {}
     94 
     95   virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) OVERRIDE {
     96     return accelerator_manager_->Process(accelerator);
     97   }
     98 
     99   virtual ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
    100       const ui::Accelerator& accelerator) const OVERRIDE {
    101     return accelerator_manager_->IsRegistered(accelerator, AF_NONE)
    102                ? accelerator_manager_
    103                : NULL;
    104   }
    105 
    106  private:
    107   AcceleratorManagerImpl* accelerator_manager_;
    108 
    109   DISALLOW_COPY_AND_ASSIGN(FocusManagerDelegate);
    110 };
    111 
    112 // Key strokes must be sent to web contents to give them a chance to
    113 // consume them unless they are reserved, and unhandled key events are
    114 // sent back to focus manager asynchronously. This installs the athena's
    115 // focus manager that handles athena shell's accelerators.
    116 class FocusManagerFactory : public views::FocusManagerFactory {
    117  public:
    118   explicit FocusManagerFactory(AcceleratorManagerImpl* accelerator_manager)
    119       : accelerator_manager_(accelerator_manager) {}
    120   virtual ~FocusManagerFactory() {}
    121 
    122   virtual views::FocusManager* CreateFocusManager(
    123       views::Widget* widget,
    124       bool desktop_widget) OVERRIDE {
    125     return new views::FocusManager(
    126         widget,
    127         desktop_widget ? NULL : new FocusManagerDelegate(accelerator_manager_));
    128   }
    129 
    130  private:
    131   AcceleratorManagerImpl* accelerator_manager_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(FocusManagerFactory);
    134 };
    135 
    136 class UIAcceleratorManagerWrapper
    137     : public AcceleratorManagerImpl::AcceleratorWrapper {
    138  public:
    139   UIAcceleratorManagerWrapper()
    140       : ui_accelerator_manager_(new ui::AcceleratorManager) {}
    141   virtual ~UIAcceleratorManagerWrapper() {}
    142 
    143   virtual void Register(const ui::Accelerator& accelerator,
    144                         ui::AcceleratorTarget* target) OVERRIDE {
    145     return ui_accelerator_manager_->Register(
    146         accelerator, ui::AcceleratorManager::kNormalPriority, target);
    147   }
    148 
    149   virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
    150     return ui_accelerator_manager_->Process(accelerator);
    151   }
    152 
    153   virtual ui::AcceleratorTarget* GetCurrentTarget(
    154       const ui::Accelerator& accelerator) const OVERRIDE {
    155     return ui_accelerator_manager_->GetCurrentTarget(accelerator);
    156   }
    157 
    158  private:
    159   scoped_ptr<ui::AcceleratorManager> ui_accelerator_manager_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(UIAcceleratorManagerWrapper);
    162 };
    163 
    164 class FocusManagerWrapper : public AcceleratorManagerImpl::AcceleratorWrapper {
    165  public:
    166   explicit FocusManagerWrapper(views::FocusManager* focus_manager)
    167       : focus_manager_(focus_manager) {}
    168   virtual ~FocusManagerWrapper() {}
    169 
    170   virtual void Register(const ui::Accelerator& accelerator,
    171                         ui::AcceleratorTarget* target) OVERRIDE {
    172     return focus_manager_->RegisterAccelerator(
    173         accelerator, ui::AcceleratorManager::kNormalPriority, target);
    174   }
    175 
    176   virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
    177     NOTREACHED();
    178     return true;
    179   }
    180 
    181   virtual ui::AcceleratorTarget* GetCurrentTarget(
    182       const ui::Accelerator& accelerator) const OVERRIDE {
    183     return focus_manager_->GetCurrentTargetForAccelerator(accelerator);
    184   }
    185 
    186  private:
    187   views::FocusManager* focus_manager_;
    188 
    189   DISALLOW_COPY_AND_ASSIGN(FocusManagerWrapper);
    190 };
    191 
    192 }  // namespace
    193 
    194 class AcceleratorManagerImpl::InternalData {
    195  public:
    196   InternalData(int command_id, AcceleratorHandler* handler, int flags)
    197       : command_id_(command_id), handler_(handler), flags_(flags) {}
    198 
    199   bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; }
    200   bool IsDebug() const { return flags_ & AF_DEBUG; }
    201   int flags() const { return flags_; }
    202 
    203   bool IsCommandEnabled() const {
    204     return handler_->IsCommandEnabled(command_id_);
    205   }
    206 
    207   bool OnAcceleratorFired(const ui::Accelerator& accelerator) {
    208     return handler_->OnAcceleratorFired(command_id_, accelerator);
    209   }
    210 
    211  private:
    212   int command_id_;
    213   AcceleratorHandler* handler_;
    214   int flags_;
    215 
    216   // This class is copyable by design.
    217 };
    218 
    219 // static
    220 AcceleratorManagerImpl*
    221 AcceleratorManagerImpl::CreateGlobalAcceleratorManager() {
    222   return new AcceleratorManagerImpl(new UIAcceleratorManagerWrapper());
    223 }
    224 
    225 scoped_ptr<AcceleratorManager> AcceleratorManagerImpl::CreateForFocusManager(
    226     views::FocusManager* focus_manager) {
    227   return scoped_ptr<AcceleratorManager>(
    228              new AcceleratorManagerImpl(new FocusManagerWrapper(focus_manager)))
    229       .Pass();
    230 }
    231 
    232 AcceleratorManagerImpl::~AcceleratorManagerImpl() {
    233   nested_accelerator_controller_.reset();
    234   accelerator_filter_.reset();
    235   // Reset to use the default focus manager because the athena's
    236   // FocusManager has the reference to this object.
    237   views::FocusManagerFactory::Install(NULL);
    238 }
    239 
    240 void AcceleratorManagerImpl::Init() {
    241   views::FocusManagerFactory::Install(new FocusManagerFactory(this));
    242 
    243   ui::EventTarget* toplevel = InputManager::Get()->GetTopmostEventTarget();
    244   nested_accelerator_controller_.reset(
    245       new wm::NestedAcceleratorController(new NestedAcceleratorDelegate(this)));
    246 
    247   scoped_ptr<wm::AcceleratorDelegate> accelerator_delegate(
    248       new AcceleratorDelegate(this));
    249 
    250   accelerator_filter_.reset(
    251       new wm::AcceleratorFilter(accelerator_delegate.Pass()));
    252   toplevel->AddPreTargetHandler(accelerator_filter_.get());
    253 }
    254 
    255 void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
    256   aura::client::SetDispatcherClient(root_window,
    257                                     nested_accelerator_controller_.get());
    258 }
    259 
    260 bool AcceleratorManagerImpl::Process(const ui::Accelerator& accelerator) {
    261   return accelerator_wrapper_->Process(accelerator);
    262 }
    263 
    264 bool AcceleratorManagerImpl::IsRegistered(const ui::Accelerator& accelerator,
    265                                           int flags) const {
    266   std::map<ui::Accelerator, InternalData>::const_iterator iter =
    267       accelerators_.find(accelerator);
    268   if (iter == accelerators_.end())
    269     return false;
    270   DCHECK(accelerator_wrapper_->GetCurrentTarget(accelerator));
    271   return flags == AF_NONE || iter->second.flags() & flags;
    272 }
    273 
    274 AcceleratorManagerImpl::AcceleratorManagerImpl(
    275     AcceleratorWrapper* accelerator_wrapper)
    276     : accelerator_wrapper_(accelerator_wrapper),
    277       debug_accelerators_enabled_(switches::IsDebugAcceleratorsEnabled()) {
    278 }
    279 
    280 void AcceleratorManagerImpl::RegisterAccelerators(
    281     const AcceleratorData accelerators[],
    282     size_t num_accelerators,
    283     AcceleratorHandler* handler) {
    284   for (size_t i = 0; i < num_accelerators; ++i)
    285     RegisterAccelerator(accelerators[i], handler);
    286 }
    287 
    288 void AcceleratorManagerImpl::SetDebugAcceleratorsEnabled(bool enabled) {
    289   debug_accelerators_enabled_ = enabled;
    290 }
    291 
    292 bool AcceleratorManagerImpl::AcceleratorPressed(
    293     const ui::Accelerator& accelerator) {
    294   std::map<ui::Accelerator, InternalData>::iterator iter =
    295       accelerators_.find(accelerator);
    296   DCHECK(iter != accelerators_.end());
    297   if (iter == accelerators_.end())
    298     return false;
    299   InternalData& data = iter->second;
    300   if (data.IsDebug() && !debug_accelerators_enabled_)
    301     return false;
    302   if (accelerator.IsRepeat() && data.IsNonAutoRepeatable())
    303     return false;
    304   return data.IsCommandEnabled() ? data.OnAcceleratorFired(accelerator) : false;
    305 }
    306 
    307 bool AcceleratorManagerImpl::CanHandleAccelerators() const {
    308   return true;
    309 }
    310 
    311 void AcceleratorManagerImpl::RegisterAccelerator(
    312     const AcceleratorData& accelerator_data,
    313     AcceleratorHandler* handler) {
    314   ui::Accelerator accelerator(accelerator_data.keycode,
    315                               accelerator_data.keyevent_flags);
    316   accelerator.set_type(accelerator_data.trigger_event == TRIGGER_ON_PRESS
    317                            ? ui::ET_KEY_PRESSED
    318                            : ui::ET_KEY_RELEASED);
    319   accelerator_wrapper_->Register(accelerator, this);
    320   accelerators_.insert(
    321       std::make_pair(accelerator,
    322                      InternalData(accelerator_data.command_id,
    323                                   handler,
    324                                   accelerator_data.accelerator_flags)));
    325 }
    326 
    327 // static
    328 AcceleratorManager* AcceleratorManager::Get() {
    329   return InputManager::Get()->GetAcceleratorManager();
    330 }
    331 
    332 // static
    333 scoped_ptr<AcceleratorManager> AcceleratorManager::CreateForFocusManager(
    334     views::FocusManager* focus_manager) {
    335   return AcceleratorManagerImpl::CreateForFocusManager(focus_manager).Pass();
    336 }
    337 
    338 }  // namespace athena
    339