Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / athena / input / accelerator_manager_impl.cc
blob4fabe628082e737b3f09b589b1ffc93acfd4842c
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.
5 #include "athena/input/accelerator_manager_impl.h"
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"
23 namespace athena {
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;
37 namespace {
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.
45 class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate {
46 public:
47 explicit NestedAcceleratorDelegate(
48 AcceleratorManagerImpl* accelerator_manager)
49 : accelerator_manager_(accelerator_manager) {}
50 virtual ~NestedAcceleratorDelegate() {}
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;
60 AcceleratorManagerImpl* accelerator_manager_;
62 DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate);
65 class AcceleratorDelegate : public wm::AcceleratorDelegate {
66 public:
67 explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager)
68 : accelerator_manager_(accelerator_manager) {}
69 virtual ~AcceleratorDelegate() {}
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;
82 return accelerator_manager_->Process(accelerator);
85 AcceleratorManagerImpl* accelerator_manager_;
86 DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate);
89 class FocusManagerDelegate : public views::FocusManagerDelegate {
90 public:
91 explicit FocusManagerDelegate(AcceleratorManagerImpl* accelerator_manager)
92 : accelerator_manager_(accelerator_manager) {}
93 virtual ~FocusManagerDelegate() {}
95 virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) OVERRIDE {
96 return accelerator_manager_->Process(accelerator);
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;
106 private:
107 AcceleratorManagerImpl* accelerator_manager_;
109 DISALLOW_COPY_AND_ASSIGN(FocusManagerDelegate);
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() {}
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_));
130 private:
131 AcceleratorManagerImpl* accelerator_manager_;
133 DISALLOW_COPY_AND_ASSIGN(FocusManagerFactory);
136 class UIAcceleratorManagerWrapper
137 : public AcceleratorManagerImpl::AcceleratorWrapper {
138 public:
139 UIAcceleratorManagerWrapper()
140 : ui_accelerator_manager_(new ui::AcceleratorManager) {}
141 virtual ~UIAcceleratorManagerWrapper() {}
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);
149 virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
150 return ui_accelerator_manager_->Process(accelerator);
153 virtual ui::AcceleratorTarget* GetCurrentTarget(
154 const ui::Accelerator& accelerator) const OVERRIDE {
155 return ui_accelerator_manager_->GetCurrentTarget(accelerator);
158 private:
159 scoped_ptr<ui::AcceleratorManager> ui_accelerator_manager_;
161 DISALLOW_COPY_AND_ASSIGN(UIAcceleratorManagerWrapper);
164 class FocusManagerWrapper : public AcceleratorManagerImpl::AcceleratorWrapper {
165 public:
166 explicit FocusManagerWrapper(views::FocusManager* focus_manager)
167 : focus_manager_(focus_manager) {}
168 virtual ~FocusManagerWrapper() {}
170 virtual void Register(const ui::Accelerator& accelerator,
171 ui::AcceleratorTarget* target) OVERRIDE {
172 return focus_manager_->RegisterAccelerator(
173 accelerator, ui::AcceleratorManager::kNormalPriority, target);
176 virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
177 NOTREACHED();
178 return true;
181 virtual ui::AcceleratorTarget* GetCurrentTarget(
182 const ui::Accelerator& accelerator) const OVERRIDE {
183 return focus_manager_->GetCurrentTargetForAccelerator(accelerator);
186 private:
187 views::FocusManager* focus_manager_;
189 DISALLOW_COPY_AND_ASSIGN(FocusManagerWrapper);
192 } // namespace
194 class AcceleratorManagerImpl::InternalData {
195 public:
196 InternalData(int command_id, AcceleratorHandler* handler, int flags)
197 : command_id_(command_id), handler_(handler), flags_(flags) {}
199 bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; }
200 bool IsDebug() const { return flags_ & AF_DEBUG; }
201 int flags() const { return flags_; }
203 bool IsCommandEnabled() const {
204 return handler_->IsCommandEnabled(command_id_);
207 bool OnAcceleratorFired(const ui::Accelerator& accelerator) {
208 return handler_->OnAcceleratorFired(command_id_, accelerator);
211 private:
212 int command_id_;
213 AcceleratorHandler* handler_;
214 int flags_;
216 // This class is copyable by design.
219 // static
220 AcceleratorManagerImpl*
221 AcceleratorManagerImpl::CreateGlobalAcceleratorManager() {
222 return new AcceleratorManagerImpl(new UIAcceleratorManagerWrapper());
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();
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);
240 void AcceleratorManagerImpl::Init() {
241 views::FocusManagerFactory::Install(new FocusManagerFactory(this));
243 ui::EventTarget* toplevel = InputManager::Get()->GetTopmostEventTarget();
244 nested_accelerator_controller_.reset(
245 new wm::NestedAcceleratorController(new NestedAcceleratorDelegate(this)));
247 scoped_ptr<wm::AcceleratorDelegate> accelerator_delegate(
248 new AcceleratorDelegate(this));
250 accelerator_filter_.reset(
251 new wm::AcceleratorFilter(accelerator_delegate.Pass()));
252 toplevel->AddPreTargetHandler(accelerator_filter_.get());
255 void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
256 aura::client::SetDispatcherClient(root_window,
257 nested_accelerator_controller_.get());
260 bool AcceleratorManagerImpl::Process(const ui::Accelerator& accelerator) {
261 return accelerator_wrapper_->Process(accelerator);
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;
274 AcceleratorManagerImpl::AcceleratorManagerImpl(
275 AcceleratorWrapper* accelerator_wrapper)
276 : accelerator_wrapper_(accelerator_wrapper),
277 debug_accelerators_enabled_(switches::IsDebugAcceleratorsEnabled()) {
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);
288 void AcceleratorManagerImpl::SetDebugAcceleratorsEnabled(bool enabled) {
289 debug_accelerators_enabled_ = enabled;
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;
307 bool AcceleratorManagerImpl::CanHandleAccelerators() const {
308 return true;
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)));
327 // static
328 AcceleratorManager* AcceleratorManager::Get() {
329 return InputManager::Get()->GetAcceleratorManager();
332 // static
333 scoped_ptr<AcceleratorManager> AcceleratorManager::CreateForFocusManager(
334 views::FocusManager* focus_manager) {
335 return AcceleratorManagerImpl::CreateForFocusManager(focus_manager).Pass();
338 } // namespace athena