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/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" 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 339