• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~AcceleratorWrapper()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:
NestedAcceleratorDelegate(AcceleratorManagerImpl * accelerator_manager)47   explicit NestedAcceleratorDelegate(
48       AcceleratorManagerImpl* accelerator_manager)
49       : accelerator_manager_(accelerator_manager) {}
~NestedAcceleratorDelegate()50   virtual ~NestedAcceleratorDelegate() {}
51 
52  private:
53   // wm::NestedAcceleratorDelegate:
ProcessAccelerator(const ui::Accelerator & accelerator)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:
AcceleratorDelegate(AcceleratorManagerImpl * accelerator_manager)67   explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager)
68       : accelerator_manager_(accelerator_manager) {}
~AcceleratorDelegate()69   virtual ~AcceleratorDelegate() {}
70 
71  private:
72   // wm::AcceleratorDelegate:
ProcessAccelerator(const ui::KeyEvent & event,const ui::Accelerator & accelerator,KeyType key_type)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:
FocusManagerDelegate(AcceleratorManagerImpl * accelerator_manager)91   explicit FocusManagerDelegate(AcceleratorManagerImpl* accelerator_manager)
92       : accelerator_manager_(accelerator_manager) {}
~FocusManagerDelegate()93   virtual ~FocusManagerDelegate() {}
94 
ProcessAccelerator(const ui::Accelerator & accelerator)95   virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) OVERRIDE {
96     return accelerator_manager_->Process(accelerator);
97   }
98 
GetCurrentTargetForAccelerator(const ui::Accelerator & accelerator) const99   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:
FocusManagerFactory(AcceleratorManagerImpl * accelerator_manager)118   explicit FocusManagerFactory(AcceleratorManagerImpl* accelerator_manager)
119       : accelerator_manager_(accelerator_manager) {}
~FocusManagerFactory()120   virtual ~FocusManagerFactory() {}
121 
CreateFocusManager(views::Widget * widget,bool desktop_widget)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:
UIAcceleratorManagerWrapper()139   UIAcceleratorManagerWrapper()
140       : ui_accelerator_manager_(new ui::AcceleratorManager) {}
~UIAcceleratorManagerWrapper()141   virtual ~UIAcceleratorManagerWrapper() {}
142 
Register(const ui::Accelerator & accelerator,ui::AcceleratorTarget * target)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 
Process(const ui::Accelerator & accelerator)149   virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
150     return ui_accelerator_manager_->Process(accelerator);
151   }
152 
GetCurrentTarget(const ui::Accelerator & accelerator) const153   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:
FocusManagerWrapper(views::FocusManager * focus_manager)166   explicit FocusManagerWrapper(views::FocusManager* focus_manager)
167       : focus_manager_(focus_manager) {}
~FocusManagerWrapper()168   virtual ~FocusManagerWrapper() {}
169 
Register(const ui::Accelerator & accelerator,ui::AcceleratorTarget * target)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 
Process(const ui::Accelerator & accelerator)176   virtual bool Process(const ui::Accelerator& accelerator) OVERRIDE {
177     NOTREACHED();
178     return true;
179   }
180 
GetCurrentTarget(const ui::Accelerator & accelerator) const181   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:
InternalData(int command_id,AcceleratorHandler * handler,int flags)196   InternalData(int command_id, AcceleratorHandler* handler, int flags)
197       : command_id_(command_id), handler_(handler), flags_(flags) {}
198 
IsNonAutoRepeatable() const199   bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; }
IsDebug() const200   bool IsDebug() const { return flags_ & AF_DEBUG; }
flags() const201   int flags() const { return flags_; }
202 
IsCommandEnabled() const203   bool IsCommandEnabled() const {
204     return handler_->IsCommandEnabled(command_id_);
205   }
206 
OnAcceleratorFired(const ui::Accelerator & accelerator)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*
CreateGlobalAcceleratorManager()221 AcceleratorManagerImpl::CreateGlobalAcceleratorManager() {
222   return new AcceleratorManagerImpl(new UIAcceleratorManagerWrapper());
223 }
224 
CreateForFocusManager(views::FocusManager * focus_manager)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 
~AcceleratorManagerImpl()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 
Init()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 
OnRootWindowCreated(aura::Window * root_window)255 void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
256   aura::client::SetDispatcherClient(root_window,
257                                     nested_accelerator_controller_.get());
258 }
259 
Process(const ui::Accelerator & accelerator)260 bool AcceleratorManagerImpl::Process(const ui::Accelerator& accelerator) {
261   return accelerator_wrapper_->Process(accelerator);
262 }
263 
IsRegistered(const ui::Accelerator & accelerator,int flags) const264 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 
AcceleratorManagerImpl(AcceleratorWrapper * accelerator_wrapper)274 AcceleratorManagerImpl::AcceleratorManagerImpl(
275     AcceleratorWrapper* accelerator_wrapper)
276     : accelerator_wrapper_(accelerator_wrapper),
277       debug_accelerators_enabled_(switches::IsDebugAcceleratorsEnabled()) {
278 }
279 
RegisterAccelerators(const AcceleratorData accelerators[],size_t num_accelerators,AcceleratorHandler * handler)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 
SetDebugAcceleratorsEnabled(bool enabled)288 void AcceleratorManagerImpl::SetDebugAcceleratorsEnabled(bool enabled) {
289   debug_accelerators_enabled_ = enabled;
290 }
291 
AcceleratorPressed(const ui::Accelerator & accelerator)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 
CanHandleAccelerators() const307 bool AcceleratorManagerImpl::CanHandleAccelerators() const {
308   return true;
309 }
310 
RegisterAccelerator(const AcceleratorData & accelerator_data,AcceleratorHandler * handler)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
Get()328 AcceleratorManager* AcceleratorManager::Get() {
329   return InputManager::Get()->GetAcceleratorManager();
330 }
331 
332 // static
CreateForFocusManager(views::FocusManager * focus_manager)333 scoped_ptr<AcceleratorManager> AcceleratorManager::CreateForFocusManager(
334     views::FocusManager* focus_manager) {
335   return AcceleratorManagerImpl::CreateForFocusManager(focus_manager).Pass();
336 }
337 
338 }  // namespace athena
339