146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "athena/input/accelerator_manager_impl.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "athena/input/public/input_manager.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "athena/util/switches.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/logging.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/aura/window.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/base/accelerators/accelerator_manager.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/events/event.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/events/event_target.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/focus/focus_manager.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/focus/focus_manager_delegate.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/focus/focus_manager_factory.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/core/accelerator_delegate.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/core/accelerator_filter.h"
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/core/nested_accelerator_controller.h"
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/core/nested_accelerator_delegate.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/wm/public/dispatcher_client.h"
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace athena {
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// This wrapper interface provides a common interface that handles global
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// accelerators as well as local accelerators.
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class AcceleratorManagerImpl::AcceleratorWrapper {
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~AcceleratorWrapper() {}
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void Register(const ui::Accelerator& accelerator,
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        ui::AcceleratorTarget* target) = 0;
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool Process(const ui::Accelerator& accelerator) = 0;
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::AcceleratorTarget* GetCurrentTarget(
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Accelerator& accelertor) const = 0;
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Accelerators inside nested message loop are handled by
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// wm::NestedAcceleratorController while accelerators in normal case are
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// handled by wm::AcceleratorFilter. These delegates act bridges in these
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// two different environment so that AcceleratorManagerImpl can handle
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// accelerators in an uniform way.
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate {
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  explicit NestedAcceleratorDelegate(
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      AcceleratorManagerImpl* accelerator_manager)
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : accelerator_manager_(accelerator_manager) {}
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~NestedAcceleratorDelegate() {}
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // wm::NestedAcceleratorDelegate:
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual Result ProcessAccelerator(
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const ui::Accelerator& accelerator) OVERRIDE {
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return accelerator_manager_->Process(accelerator) ? RESULT_PROCESSED
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                      : RESULT_NOT_PROCESSED;
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AcceleratorManagerImpl* accelerator_manager_;
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate);
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class AcceleratorDelegate : public wm::AcceleratorDelegate {
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager)
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : accelerator_manager_(accelerator_manager) {}
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~AcceleratorDelegate() {}
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // wm::AcceleratorDelegate:
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual bool ProcessAccelerator(const ui::KeyEvent& event,
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const ui::Accelerator& accelerator,
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  KeyType key_type) OVERRIDE {
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    aura::Window* target = static_cast<aura::Window*>(event.target());
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!target->IsRootWindow() &&
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        !accelerator_manager_->IsRegistered(accelerator, AF_RESERVED)) {
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // TODO(oshima): do the same when the active window is in fullscreen.
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return false;
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return accelerator_manager_->Process(accelerator);
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AcceleratorManagerImpl* accelerator_manager_;
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate);
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class FocusManagerDelegate : public views::FocusManagerDelegate {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit FocusManagerDelegate(AcceleratorManagerImpl* accelerator_manager)
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : accelerator_manager_(accelerator_manager) {}
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~FocusManagerDelegate() {}
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) OVERRIDE {
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return accelerator_manager_->Process(accelerator);
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Accelerator& accelerator) const OVERRIDE {
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return accelerator_manager_->IsRegistered(accelerator, AF_NONE)
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)               ? accelerator_manager_
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)               : NULL;
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AcceleratorManagerImpl* accelerator_manager_;
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusManagerDelegate);
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Key strokes must be sent to web contents to give them a chance to
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// consume them unless they are reserved, and unhandled key events are
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// sent back to focus manager asynchronously. This installs the athena's
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// focus manager that handles athena shell's accelerators.
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class FocusManagerFactory : public views::FocusManagerFactory {
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit FocusManagerFactory(AcceleratorManagerImpl* accelerator_manager)
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : accelerator_manager_(accelerator_manager) {}
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~FocusManagerFactory() {}
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual views::FocusManager* CreateFocusManager(
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      views::Widget* widget,
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bool desktop_widget) OVERRIDE {
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return new views::FocusManager(
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        widget,
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        desktop_widget ? NULL : new FocusManagerDelegate(accelerator_manager_));
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AcceleratorManagerImpl* accelerator_manager_;
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusManagerFactory);
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class UIAcceleratorManagerWrapper
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : public AcceleratorManagerImpl::AcceleratorWrapper {
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UIAcceleratorManagerWrapper()
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : ui_accelerator_manager_(new ui::AcceleratorManager) {}
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~UIAcceleratorManagerWrapper() {}
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void Register(const ui::Accelerator& accelerator,
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        ui::AcceleratorTarget* target) OVERRIDE {
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return ui_accelerator_manager_->Register(
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        accelerator, ui::AcceleratorManager::kNormalPriority, target);
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return ui_accelerator_manager_->Process(accelerator);
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::AcceleratorTarget* GetCurrentTarget(
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Accelerator& accelerator) const OVERRIDE {
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return ui_accelerator_manager_->GetCurrentTarget(accelerator);
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::AcceleratorManager> ui_accelerator_manager_;
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UIAcceleratorManagerWrapper);
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class FocusManagerWrapper : public AcceleratorManagerImpl::AcceleratorWrapper {
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit FocusManagerWrapper(views::FocusManager* focus_manager)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : focus_manager_(focus_manager) {}
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~FocusManagerWrapper() {}
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void Register(const ui::Accelerator& accelerator,
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        ui::AcceleratorTarget* target) OVERRIDE {
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return focus_manager_->RegisterAccelerator(
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        accelerator, ui::AcceleratorManager::kNormalPriority, target);
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NOTREACHED();
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::AcceleratorTarget* GetCurrentTarget(
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Accelerator& accelerator) const OVERRIDE {
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return focus_manager_->GetCurrentTargetForAccelerator(accelerator);
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::FocusManager* focus_manager_;
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusManagerWrapper);
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class AcceleratorManagerImpl::InternalData {
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  InternalData(int command_id, AcceleratorHandler* handler, int flags)
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : command_id_(command_id), handler_(handler), flags_(flags) {}
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; }
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool IsDebug() const { return flags_ & AF_DEBUG; }
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int flags() const { return flags_; }
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool IsCommandEnabled() const {
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return handler_->IsCommandEnabled(command_id_);
20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool OnAcceleratorFired(const ui::Accelerator& accelerator) {
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return handler_->OnAcceleratorFired(command_id_, accelerator);
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int command_id_;
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AcceleratorHandler* handler_;
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int flags_;
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // This class is copyable by design.
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AcceleratorManagerImpl*
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AcceleratorManagerImpl::CreateGlobalAcceleratorManager() {
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return new AcceleratorManagerImpl(new UIAcceleratorManagerWrapper());
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<AcceleratorManager> AcceleratorManagerImpl::CreateForFocusManager(
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    views::FocusManager* focus_manager) {
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return scoped_ptr<AcceleratorManager>(
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)             new AcceleratorManagerImpl(new FocusManagerWrapper(focus_manager)))
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .Pass();
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AcceleratorManagerImpl::~AcceleratorManagerImpl() {
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  nested_accelerator_controller_.reset();
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  accelerator_filter_.reset();
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Reset to use the default focus manager because the athena's
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FocusManager has the reference to this object.
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::FocusManagerFactory::Install(NULL);
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AcceleratorManagerImpl::Init() {
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::FocusManagerFactory::Install(new FocusManagerFactory(this));
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::EventTarget* toplevel = InputManager::Get()->GetTopmostEventTarget();
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  nested_accelerator_controller_.reset(
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new wm::NestedAcceleratorController(new NestedAcceleratorDelegate(this)));
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<wm::AcceleratorDelegate> accelerator_delegate(
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new AcceleratorDelegate(this));
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  accelerator_filter_.reset(
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new wm::AcceleratorFilter(accelerator_delegate.Pass()));
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  toplevel->AddPreTargetHandler(accelerator_filter_.get());
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  aura::client::SetDispatcherClient(root_window,
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    nested_accelerator_controller_.get());
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool AcceleratorManagerImpl::Process(const ui::Accelerator& accelerator) {
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return accelerator_wrapper_->Process(accelerator);
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool AcceleratorManagerImpl::IsRegistered(const ui::Accelerator& accelerator,
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                          int flags) const {
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::map<ui::Accelerator, InternalData>::const_iterator iter =
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      accelerators_.find(accelerator);
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (iter == accelerators_.end())
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(accelerator_wrapper_->GetCurrentTarget(accelerator));
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return flags == AF_NONE || iter->second.flags() & flags;
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AcceleratorManagerImpl::AcceleratorManagerImpl(
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    AcceleratorWrapper* accelerator_wrapper)
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : accelerator_wrapper_(accelerator_wrapper),
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      debug_accelerators_enabled_(switches::IsDebugAcceleratorsEnabled()) {
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AcceleratorManagerImpl::RegisterAccelerators(
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const AcceleratorData accelerators[],
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    size_t num_accelerators,
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AcceleratorHandler* handler) {
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (size_t i = 0; i < num_accelerators; ++i)
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RegisterAccelerator(accelerators[i], handler);
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AcceleratorManagerImpl::SetDebugAcceleratorsEnabled(bool enabled) {
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  debug_accelerators_enabled_ = enabled;
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool AcceleratorManagerImpl::AcceleratorPressed(
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const ui::Accelerator& accelerator) {
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::map<ui::Accelerator, InternalData>::iterator iter =
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      accelerators_.find(accelerator);
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(iter != accelerators_.end());
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (iter == accelerators_.end())
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  InternalData& data = iter->second;
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (data.IsDebug() && !debug_accelerators_enabled_)
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (accelerator.IsRepeat() && data.IsNonAutoRepeatable())
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return data.IsCommandEnabled() ? data.OnAcceleratorFired(accelerator) : false;
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool AcceleratorManagerImpl::CanHandleAccelerators() const {
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return true;
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AcceleratorManagerImpl::RegisterAccelerator(
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const AcceleratorData& accelerator_data,
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AcceleratorHandler* handler) {
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::Accelerator accelerator(accelerator_data.keycode,
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              accelerator_data.keyevent_flags);
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  accelerator.set_type(accelerator_data.trigger_event == TRIGGER_ON_PRESS
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           ? ui::ET_KEY_PRESSED
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           : ui::ET_KEY_RELEASED);
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  accelerator_wrapper_->Register(accelerator, this);
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  accelerators_.insert(
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      std::make_pair(accelerator,
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     InternalData(accelerator_data.command_id,
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  handler,
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  accelerator_data.accelerator_flags)));
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AcceleratorManager* AcceleratorManager::Get() {
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return InputManager::Get()->GetAcceleratorManager();
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<AcceleratorManager> AcceleratorManager::CreateForFocusManager(
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    views::FocusManager* focus_manager) {
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return AcceleratorManagerImpl::CreateForFocusManager(focus_manager).Pass();
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace athena
339