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