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"
25 // This wrapper interface provides a common interface that handles global
26 // accelerators as well as local accelerators.
27 class AcceleratorManagerImpl::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;
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
{
47 explicit NestedAcceleratorDelegate(
48 AcceleratorManagerImpl
* accelerator_manager
)
49 : accelerator_manager_(accelerator_manager
) {}
50 virtual ~NestedAcceleratorDelegate() {}
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
{
67 explicit AcceleratorDelegate(AcceleratorManagerImpl
* accelerator_manager
)
68 : accelerator_manager_(accelerator_manager
) {}
69 virtual ~AcceleratorDelegate() {}
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.
82 return accelerator_manager_
->Process(accelerator
);
85 AcceleratorManagerImpl
* accelerator_manager_
;
86 DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate
);
89 class FocusManagerDelegate
: public views::FocusManagerDelegate
{
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_
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
{
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(
127 desktop_widget
? NULL
: new FocusManagerDelegate(accelerator_manager_
));
131 AcceleratorManagerImpl
* accelerator_manager_
;
133 DISALLOW_COPY_AND_ASSIGN(FocusManagerFactory
);
136 class UIAcceleratorManagerWrapper
137 : public AcceleratorManagerImpl::AcceleratorWrapper
{
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
);
159 scoped_ptr
<ui::AcceleratorManager
> ui_accelerator_manager_
;
161 DISALLOW_COPY_AND_ASSIGN(UIAcceleratorManagerWrapper
);
164 class FocusManagerWrapper
: public AcceleratorManagerImpl::AcceleratorWrapper
{
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
{
181 virtual ui::AcceleratorTarget
* GetCurrentTarget(
182 const ui::Accelerator
& accelerator
) const OVERRIDE
{
183 return focus_manager_
->GetCurrentTargetForAccelerator(accelerator
);
187 views::FocusManager
* focus_manager_
;
189 DISALLOW_COPY_AND_ASSIGN(FocusManagerWrapper
);
194 class AcceleratorManagerImpl::InternalData
{
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
);
213 AcceleratorHandler
* handler_
;
216 // This class is copyable by design.
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
)))
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
,
266 std::map
<ui::Accelerator
, InternalData
>::const_iterator iter
=
267 accelerators_
.find(accelerator
);
268 if (iter
== accelerators_
.end())
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())
299 InternalData
& data
= iter
->second
;
300 if (data
.IsDebug() && !debug_accelerators_enabled_
)
302 if (accelerator
.IsRepeat() && data
.IsNonAutoRepeatable())
304 return data
.IsCommandEnabled() ? data
.OnAcceleratorFired(accelerator
) : false;
307 bool AcceleratorManagerImpl::CanHandleAccelerators() const {
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
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
,
324 accelerator_data
.accelerator_flags
)));
328 AcceleratorManager
* AcceleratorManager::Get() {
329 return InputManager::Get()->GetAcceleratorManager();
333 scoped_ptr
<AcceleratorManager
> AcceleratorManager::CreateForFocusManager(
334 views::FocusManager
* focus_manager
) {
335 return AcceleratorManagerImpl::CreateForFocusManager(focus_manager
).Pass();
338 } // namespace athena