Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / athena / input / accelerator_manager_impl.cc
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/input/public/input_manager.h"
8 #include "athena/util/switches.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