Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: ash/accelerators/accelerator_controller.cc

Issue 2166793005: Moves accelerator code using common types to ash/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@debug_commands
Patch Set: not relative Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "ash/accelerators/accelerator_controller.h"
6
7 #include "ash/accelerators/accelerator_commands.h"
8 #include "ash/accelerators/accelerator_controller_delegate.h"
9 #include "ash/accelerators/debug_commands.h"
10 #include "ash/common/accessibility_delegate.h"
11 #include "ash/common/accessibility_types.h"
12 #include "ash/common/focus_cycler.h"
13 #include "ash/common/media_delegate.h"
14 #include "ash/common/multi_profile_uma.h"
15 #include "ash/common/session/session_state_delegate.h"
16 #include "ash/common/shell_delegate.h"
17 #include "ash/common/system/brightness_control_delegate.h"
18 #include "ash/common/system/keyboard_brightness_control_delegate.h"
19 #include "ash/common/system/tray/system_tray_delegate.h"
20 #include "ash/common/system/tray/system_tray_notifier.h"
21 #include "ash/common/system/volume_control_delegate.h"
22 #include "ash/common/wm/mru_window_tracker.h"
23 #include "ash/common/wm/overview/window_selector_controller.h"
24 #include "ash/common/wm/window_cycle_controller.h"
25 #include "ash/common/wm/window_positioning_utils.h"
26 #include "ash/common/wm/window_state.h"
27 #include "ash/common/wm/wm_event.h"
28 #include "ash/common/wm_shell.h"
29 #include "ash/common/wm_window.h"
30 #include "ash/ime_control_delegate.h"
31 #include "base/metrics/histogram_macros.h"
32 #include "base/metrics/user_metrics.h"
33 #include "ui/base/accelerators/accelerator.h"
34 #include "ui/base/accelerators/accelerator_manager.h"
35
36 #if defined(OS_CHROMEOS)
37 #include "chromeos/dbus/dbus_thread_manager.h"
38 #include "chromeos/dbus/power_manager_client.h"
39 #include "ui/base/ime/chromeos/ime_keyboard.h"
40 #include "ui/base/ime/chromeos/input_method_manager.h"
41 #endif // defined(OS_CHROMEOS)
42
43 namespace ash {
44 namespace {
45
46 using base::UserMetricsAction;
47
48 ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode,
49 int modifiers,
50 bool trigger_on_press) {
51 ui::Accelerator accelerator(keycode, modifiers);
52 accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED
53 : ui::ET_KEY_RELEASED);
54 return accelerator;
55 }
56
57 void RecordUmaHistogram(const char* histogram_name,
58 DeprecatedAcceleratorUsage sample) {
59 auto* histogram = base::LinearHistogram::FactoryGet(
60 histogram_name, 1, DEPRECATED_USAGE_COUNT, DEPRECATED_USAGE_COUNT + 1,
61 base::HistogramBase::kUmaTargetedHistogramFlag);
62 histogram->Add(sample);
63 }
64
65 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
66 if (accelerator.key_code() == ui::VKEY_TAB)
67 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
68
69 WmShell::Get()->window_cycle_controller()->HandleCycleWindow(
70 WindowCycleController::BACKWARD);
71 }
72
73 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
74 if (accelerator.key_code() == ui::VKEY_TAB)
75 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
76
77 WmShell::Get()->window_cycle_controller()->HandleCycleWindow(
78 WindowCycleController::FORWARD);
79 }
80
81 void HandleRotatePaneFocus(FocusCycler::Direction direction) {
82 switch (direction) {
83 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
84 case FocusCycler::FORWARD: {
85 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
86 break;
87 }
88 case FocusCycler::BACKWARD: {
89 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
90 break;
91 }
92 }
93 WmShell::Get()->focus_cycler()->RotateFocus(direction);
94 }
95
96 void HandleMediaNextTrack() {
97 WmShell::Get()->media_delegate()->HandleMediaNextTrack();
98 }
99
100 void HandleMediaPlayPause() {
101 WmShell::Get()->media_delegate()->HandleMediaPlayPause();
102 }
103
104 void HandleMediaPrevTrack() {
105 WmShell::Get()->media_delegate()->HandleMediaPrevTrack();
106 }
107
108 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate) {
109 return ime_control_delegate && ime_control_delegate->CanCycleIme();
110 }
111
112 // We must avoid showing the Deprecated NEXT_IME notification erronously.
113 bool ShouldShowDeprecatedNextImeNotification(
114 const ui::Accelerator& previous_accelerator) {
115 // We only show the deprecation notification if the previous accelerator key
116 // is ONLY either Shift, or Alt.
117 const ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
118 switch (previous_key_code) {
119 case ui::VKEY_SHIFT:
120 case ui::VKEY_LSHIFT:
121 case ui::VKEY_RSHIFT:
122 case ui::VKEY_MENU:
123 case ui::VKEY_LMENU:
124 case ui::VKEY_RMENU:
125 return true;
126
127 default:
128 return false;
129 }
130 }
131
132 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
133 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
134 ime_control_delegate->HandleNextIme();
135 }
136
137 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
138 return ime_control_delegate && ime_control_delegate->CanCycleIme();
139 }
140
141 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
142 const ui::Accelerator& accelerator) {
143 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
144 if (accelerator.type() == ui::ET_KEY_PRESSED)
145 ime_control_delegate->HandlePreviousIme();
146 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
147 }
148
149 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
150 const ui::Accelerator& accelerator) {
151 return ime_control_delegate &&
152 ime_control_delegate->CanSwitchIme(accelerator);
153 }
154
155 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
156 const ui::Accelerator& accelerator) {
157 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
158 ime_control_delegate->HandleSwitchIme(accelerator);
159 }
160
161 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
162 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
163 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
164 accelerators::ToggleFullscreen();
165 }
166
167 void HandleToggleOverview() {
168 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
169 WmShell::Get()->window_selector_controller()->ToggleOverview();
170 }
171
172 bool CanHandleWindowSnapOrDock() {
173 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
174 if (!active_window)
175 return false;
176 wm::WindowState* window_state = active_window->GetWindowState();
177 // Disable window snapping shortcut key for full screen window due to
178 // http://crbug.com/135487.
179 return (window_state && window_state->IsUserPositionable() &&
180 !window_state->IsFullscreen());
181 }
182
183 void HandleWindowSnapOrDock(AcceleratorAction action) {
184 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
185 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
186 else
187 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
188
189 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT
190 ? wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT
191 : wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
192 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
193 DCHECK(active_window);
194 active_window->GetWindowState()->OnWMEvent(&event);
195 }
196
197 void HandleWindowMinimize() {
198 base::RecordAction(base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
199 accelerators::ToggleMinimized();
200 }
201
202 bool CanHandlePositionCenter() {
203 // Docked windows do not support centering.
204 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
205 return (active_window && !active_window->GetWindowState()->IsDocked());
206 }
207
208 void HandlePositionCenter() {
209 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
210 wm::CenterWindow(WmShell::Get()->GetActiveWindow());
211 }
212
213 #if defined(OS_CHROMEOS)
214 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
215 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
216 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
217 (previous_key_code != ui::VKEY_LSHIFT &&
218 previous_key_code != ui::VKEY_SHIFT &&
219 previous_key_code != ui::VKEY_RSHIFT)) {
220 // If something else was pressed between the Shift key being pressed
221 // and released, then ignore the release of the Shift key.
222 return false;
223 }
224 chromeos::input_method::InputMethodManager* ime =
225 chromeos::input_method::InputMethodManager::Get();
226 chromeos::input_method::ImeKeyboard* keyboard =
227 ime ? ime->GetImeKeyboard() : NULL;
228 return (keyboard && keyboard->CapsLockIsEnabled());
229 }
230
231 void HandleDisableCapsLock() {
232 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
233 chromeos::input_method::InputMethodManager* ime =
234 chromeos::input_method::InputMethodManager::Get();
235 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
236 }
237
238 bool CanHandleLock() {
239 return WmShell::Get()->GetSessionStateDelegate()->CanLockScreen();
240 }
241
242 void HandleLock() {
243 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
244 WmShell::Get()->GetSessionStateDelegate()->LockScreen();
245 }
246
247 void HandleSuspend() {
248 base::RecordAction(UserMetricsAction("Accel_Suspend"));
249 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestSuspend();
250 }
251
252 bool CanHandleCycleUser() {
253 return WmShell::Get()->delegate()->IsMultiProfilesEnabled() &&
254 WmShell::Get()->GetSessionStateDelegate()->NumberOfLoggedInUsers() > 1;
255 }
256
257 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
258 MultiProfileUMA::RecordSwitchActiveUser(
259 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
260 switch (cycle_user) {
261 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
262 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
263 break;
264 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
265 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
266 break;
267 }
268 WmShell::Get()->GetSessionStateDelegate()->CycleActiveUser(cycle_user);
269 }
270
271 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
272 const ui::Accelerator& previous_accelerator) {
273 if (accelerator.key_code() == ui::VKEY_LWIN) {
274 // If something else was pressed between the Search key (LWIN)
275 // being pressed and released, then ignore the release of the
276 // Search key.
277 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
278 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
279 previous_accelerator.key_code() != ui::VKEY_LWIN)
280 return false;
281 }
282 chromeos::input_method::InputMethodManager* ime =
283 chromeos::input_method::InputMethodManager::Get();
284 return ime && ime->GetImeKeyboard();
285 }
286
287 void HandleToggleCapsLock() {
288 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
289 chromeos::input_method::InputMethodManager* ime =
290 chromeos::input_method::InputMethodManager::Get();
291 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
292 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
293 }
294
295 void HandleToggleSpokenFeedback() {
296 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
297
298 WmShell::Get()->accessibility_delegate()->ToggleSpokenFeedback(
299 A11Y_NOTIFICATION_SHOW);
300 }
301
302 void HandleVolumeDown(const ui::Accelerator& accelerator) {
303 VolumeControlDelegate* volume_delegate =
304 WmShell::Get()->system_tray_delegate()->GetVolumeControlDelegate();
305 if (volume_delegate)
306 volume_delegate->HandleVolumeDown(accelerator);
307 }
308
309 void HandleVolumeMute(const ui::Accelerator& accelerator) {
310 VolumeControlDelegate* volume_delegate =
311 WmShell::Get()->system_tray_delegate()->GetVolumeControlDelegate();
312 if (volume_delegate)
313 volume_delegate->HandleVolumeMute(accelerator);
314 }
315
316 void HandleVolumeUp(const ui::Accelerator& accelerator) {
317 VolumeControlDelegate* volume_delegate =
318 WmShell::Get()->system_tray_delegate()->GetVolumeControlDelegate();
319 if (volume_delegate)
320 volume_delegate->HandleVolumeUp(accelerator);
321 }
322
323 #endif // defined(OS_CHROMEOS)
324
325 } // namespace
326
327 ////////////////////////////////////////////////////////////////////////////////
328 // AcceleratorController, public:
329
330 AcceleratorController::AcceleratorController(
331 AcceleratorControllerDelegate* delegate)
332 : delegate_(delegate),
333 accelerator_manager_(new ui::AcceleratorManager),
334 accelerator_history_(new ui::AcceleratorHistory) {
335 Init();
336 }
337
338 AcceleratorController::~AcceleratorController() {}
339
340 void AcceleratorController::Register(const ui::Accelerator& accelerator,
341 ui::AcceleratorTarget* target) {
342 accelerator_manager_->Register(
343 accelerator, ui::AcceleratorManager::kNormalPriority, target);
344 }
345
346 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
347 ui::AcceleratorTarget* target) {
348 accelerator_manager_->Unregister(accelerator, target);
349 }
350
351 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
352 accelerator_manager_->UnregisterAll(target);
353 }
354
355 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
356 return accelerator_manager_->Process(accelerator);
357 }
358
359 bool AcceleratorController::IsRegistered(
360 const ui::Accelerator& accelerator) const {
361 return accelerator_manager_->IsRegistered(accelerator);
362 }
363
364 bool AcceleratorController::IsPreferred(
365 const ui::Accelerator& accelerator) const {
366 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
367 accelerators_.find(accelerator);
368 if (iter == accelerators_.end())
369 return false; // not an accelerator.
370
371 return preferred_actions_.find(iter->second) != preferred_actions_.end();
372 }
373
374 bool AcceleratorController::IsReserved(
375 const ui::Accelerator& accelerator) const {
376 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
377 accelerators_.find(accelerator);
378 if (iter == accelerators_.end())
379 return false; // not an accelerator.
380
381 return reserved_actions_.find(iter->second) != reserved_actions_.end();
382 }
383
384 bool AcceleratorController::IsDeprecated(
385 const ui::Accelerator& accelerator) const {
386 return deprecated_accelerators_.count(accelerator) != 0;
387 }
388
389 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
390 if (CanPerformAction(action, ui::Accelerator())) {
391 PerformAction(action, ui::Accelerator());
392 return true;
393 }
394 return false;
395 }
396
397 AcceleratorController::AcceleratorProcessingRestriction
398 AcceleratorController::GetCurrentAcceleratorRestriction() {
399 return GetAcceleratorProcessingRestriction(-1);
400 }
401
402 void AcceleratorController::SetImeControlDelegate(
403 std::unique_ptr<ImeControlDelegate> ime_control_delegate) {
404 ime_control_delegate_ = std::move(ime_control_delegate);
405 }
406
407 bool AcceleratorController::ShouldCloseMenuAndRepostAccelerator(
408 const ui::Accelerator& accelerator) const {
409 auto itr = accelerators_.find(accelerator);
410 if (itr == accelerators_.end())
411 return false; // Menu shouldn't be closed for an invalid accelerator.
412
413 AcceleratorAction action = itr->second;
414 return actions_keeping_menu_open_.count(action) == 0;
415 }
416
417 ////////////////////////////////////////////////////////////////////////////////
418 // AcceleratorController, ui::AcceleratorTarget implementation:
419
420 bool AcceleratorController::AcceleratorPressed(
421 const ui::Accelerator& accelerator) {
422 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
423 accelerators_.find(accelerator);
424 DCHECK(it != accelerators_.end());
425 AcceleratorAction action = it->second;
426 if (CanPerformAction(action, accelerator)) {
427 // Handling the deprecated accelerators (if any) only if action can be
428 // performed.
429 auto itr = actions_with_deprecations_.find(action);
430 if (itr != actions_with_deprecations_.end()) {
431 const DeprecatedAcceleratorData* data = itr->second;
432 if (deprecated_accelerators_.count(accelerator)) {
433 // This accelerator has been deprecated and should be treated according
434 // to its |DeprecatedAcceleratorData|.
435
436 // Record UMA stats.
437 RecordUmaHistogram(data->uma_histogram_name, DEPRECATED_USED);
438
439 // We always display the notification as long as this entry exists,
440 // except for NEXT_IME, we must check to avoid showing it for the wrong
441 // shortcut, as Alt+Shift is tricky and trigger the action on release.
442 if (delegate_ &&
443 (action != NEXT_IME ||
444 (action == NEXT_IME &&
445 ShouldShowDeprecatedNextImeNotification(
446 accelerator_history_->previous_accelerator())))) {
447 delegate_->ShowDeprecatedAcceleratorNotification(
448 data->uma_histogram_name, data->notification_message_id,
449 data->old_shortcut_id, data->new_shortcut_id);
450 }
451
452 if (!data->deprecated_enabled)
453 return false;
454 } else {
455 // This is a new accelerator replacing the old deprecated one.
456 // Record UMA stats and proceed normally.
457 RecordUmaHistogram(data->uma_histogram_name, NEW_USED);
458 }
459 }
460
461 PerformAction(action, accelerator);
462 return ShouldActionConsumeKeyEvent(action);
463 }
464 return false;
465 }
466
467 bool AcceleratorController::CanHandleAccelerators() const {
468 return true;
469 }
470
471 ///////////////////////////////////////////////////////////////////////////////
472 // AcceleratorController, private:
473
474 void AcceleratorController::Init() {
475 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
476 actions_allowed_at_login_screen_.insert(
477 kActionsAllowedAtLoginOrLockScreen[i]);
478 actions_allowed_at_lock_screen_.insert(
479 kActionsAllowedAtLoginOrLockScreen[i]);
480 }
481 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
482 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
483 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
484 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
485 for (size_t i = 0; i < kPreferredActionsLength; ++i)
486 preferred_actions_.insert(kPreferredActions[i]);
487 for (size_t i = 0; i < kReservedActionsLength; ++i)
488 reserved_actions_.insert(kReservedActions[i]);
489 for (size_t i = 0; i < kRepeatableActionsLength; ++i)
490 repeatable_actions_.insert(kRepeatableActions[i]);
491 for (size_t i = 0; i < kActionsAllowedInAppModeOrPinnedModeLength; ++i) {
492 actions_allowed_in_app_mode_.insert(
493 kActionsAllowedInAppModeOrPinnedMode[i]);
494 actions_allowed_in_pinned_mode_.insert(
495 kActionsAllowedInAppModeOrPinnedMode[i]);
496 }
497 for (size_t i = 0; i < kActionsAllowedInPinnedModeLength; ++i)
498 actions_allowed_in_pinned_mode_.insert(kActionsAllowedInPinnedMode[i]);
499 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
500 actions_needing_window_.insert(kActionsNeedingWindow[i]);
501 for (size_t i = 0; i < kActionsKeepingMenuOpenLength; ++i)
502 actions_keeping_menu_open_.insert(kActionsKeepingMenuOpen[i]);
503
504 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
505
506 RegisterDeprecatedAccelerators();
507
508 if (debug::DebugAcceleratorsEnabled()) {
509 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
510 // All debug accelerators are reserved.
511 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
512 reserved_actions_.insert(kDebugAcceleratorData[i].action);
513 }
514 }
515
516 void AcceleratorController::RegisterAccelerators(
517 const AcceleratorData accelerators[],
518 size_t accelerators_length) {
519 for (size_t i = 0; i < accelerators_length; ++i) {
520 ui::Accelerator accelerator =
521 CreateAccelerator(accelerators[i].keycode, accelerators[i].modifiers,
522 accelerators[i].trigger_on_press);
523 Register(accelerator, this);
524 accelerators_.insert(std::make_pair(accelerator, accelerators[i].action));
525 }
526 }
527
528 void AcceleratorController::RegisterDeprecatedAccelerators() {
529 #if defined(OS_CHROMEOS)
530 for (size_t i = 0; i < kDeprecatedAcceleratorsDataLength; ++i) {
531 const DeprecatedAcceleratorData* data = &kDeprecatedAcceleratorsData[i];
532 actions_with_deprecations_[data->action] = data;
533 }
534
535 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) {
536 const AcceleratorData& accelerator_data = kDeprecatedAccelerators[i];
537 const ui::Accelerator deprecated_accelerator =
538 CreateAccelerator(accelerator_data.keycode, accelerator_data.modifiers,
539 accelerator_data.trigger_on_press);
540
541 Register(deprecated_accelerator, this);
542 accelerators_[deprecated_accelerator] = accelerator_data.action;
543 deprecated_accelerators_.insert(deprecated_accelerator);
544 }
545 #endif // defined(OS_CHROMEOS)
546 }
547
548 bool AcceleratorController::CanPerformAction(
549 AcceleratorAction action,
550 const ui::Accelerator& accelerator) {
551 if (accelerator.IsRepeat() && !repeatable_actions_.count(action))
552 return false;
553
554 AcceleratorProcessingRestriction restriction =
555 GetAcceleratorProcessingRestriction(action);
556 if (restriction != RESTRICTION_NONE)
557 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
558
559 const ui::Accelerator& previous_accelerator =
560 accelerator_history_->previous_accelerator();
561
562 // True should be returned if running |action| does something. Otherwise,
563 // false should be returned to give the web contents a chance at handling the
564 // accelerator.
565 switch (action) {
566 case DEBUG_PRINT_LAYER_HIERARCHY:
567 case DEBUG_PRINT_VIEW_HIERARCHY:
568 case DEBUG_PRINT_WINDOW_HIERARCHY:
569 return debug::DebugAcceleratorsEnabled();
570 case NEXT_IME:
571 return CanHandleNextIme(ime_control_delegate_.get());
572 case PREVIOUS_IME:
573 return CanHandlePreviousIme(ime_control_delegate_.get());
574 case SWITCH_IME:
575 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
576 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
577 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
578 return CanHandleWindowSnapOrDock();
579 case WINDOW_POSITION_CENTER:
580 return CanHandlePositionCenter();
581 #if defined(OS_CHROMEOS)
582 case DEBUG_SHOW_TOAST:
583 case DEBUG_TOGGLE_TOUCH_PAD:
584 case DEBUG_TOGGLE_TOUCH_SCREEN:
585 case DEBUG_TOGGLE_TOUCH_VIEW:
586 return debug::DebugAcceleratorsEnabled();
587 case DISABLE_CAPS_LOCK:
588 return CanHandleDisableCapsLock(previous_accelerator);
589 case LOCK_SCREEN:
590 return CanHandleLock();
591 case SWITCH_TO_PREVIOUS_USER:
592 case SWITCH_TO_NEXT_USER:
593 return CanHandleCycleUser();
594 case TOGGLE_CAPS_LOCK:
595 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
596 #endif
597 case CYCLE_BACKWARD_MRU:
598 case CYCLE_FORWARD_MRU:
599 case EXIT:
600 case FOCUS_NEXT_PANE:
601 case FOCUS_PREVIOUS_PANE:
602 case MEDIA_NEXT_TRACK:
603 case MEDIA_PLAY_PAUSE:
604 case MEDIA_PREV_TRACK:
605 case PRINT_UI_HIERARCHIES:
606 case TOGGLE_FULLSCREEN:
607 case TOGGLE_MAXIMIZED:
608 case TOGGLE_OVERVIEW:
609 case WINDOW_MINIMIZE:
610 #if defined(OS_CHROMEOS)
611 case BRIGHTNESS_DOWN:
612 case BRIGHTNESS_UP:
613 case KEYBOARD_BRIGHTNESS_DOWN:
614 case KEYBOARD_BRIGHTNESS_UP:
615 case SUSPEND:
616 case TOGGLE_SPOKEN_FEEDBACK:
617 case TOGGLE_WIFI:
618 case VOLUME_DOWN:
619 case VOLUME_MUTE:
620 case VOLUME_UP:
621 #else
622 case DUMMY_FOR_RESERVED:
623 #endif
624 return true;
625
626 default:
627 // Default switch is temporary until mash transition complete. Needed as
628 // some actions don't yet work with mash.
629 break;
630 }
631 return delegate_ && delegate_->HandlesAction(action) &&
632 delegate_->CanPerformAction(action, accelerator, previous_accelerator);
633 }
634
635 void AcceleratorController::PerformAction(AcceleratorAction action,
636 const ui::Accelerator& accelerator) {
637 AcceleratorProcessingRestriction restriction =
638 GetAcceleratorProcessingRestriction(action);
639 if (restriction != RESTRICTION_NONE)
640 return;
641
642 // If your accelerator invokes more than one line of code, please either
643 // implement it in your module's controller code or pull it into a HandleFoo()
644 // function above.
645 switch (action) {
646 case CYCLE_BACKWARD_MRU:
647 HandleCycleBackwardMRU(accelerator);
648 break;
649 case CYCLE_FORWARD_MRU:
650 HandleCycleForwardMRU(accelerator);
651 break;
652 case DEBUG_PRINT_LAYER_HIERARCHY:
653 case DEBUG_PRINT_VIEW_HIERARCHY:
654 case DEBUG_PRINT_WINDOW_HIERARCHY:
655 debug::PerformDebugActionIfEnabled(action);
656 break;
657 case EXIT:
658 // UMA metrics are recorded in the handler.
659 exit_warning_handler_.HandleAccelerator();
660 break;
661 case FOCUS_NEXT_PANE:
662 HandleRotatePaneFocus(FocusCycler::FORWARD);
663 break;
664 case FOCUS_PREVIOUS_PANE:
665 HandleRotatePaneFocus(FocusCycler::BACKWARD);
666 break;
667 case MEDIA_NEXT_TRACK:
668 HandleMediaNextTrack();
669 break;
670 case MEDIA_PLAY_PAUSE:
671 HandleMediaPlayPause();
672 break;
673 case MEDIA_PREV_TRACK:
674 HandleMediaPrevTrack();
675 break;
676 case NEXT_IME:
677 HandleNextIme(ime_control_delegate_.get());
678 break;
679 case PREVIOUS_IME:
680 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
681 break;
682 case PRINT_UI_HIERARCHIES:
683 debug::PrintUIHierarchies();
684 break;
685 case SWITCH_IME:
686 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
687 break;
688 case TOGGLE_FULLSCREEN:
689 HandleToggleFullscreen(accelerator);
690 break;
691 case TOGGLE_MAXIMIZED:
692 accelerators::ToggleMaximized();
693 break;
694 case TOGGLE_OVERVIEW:
695 HandleToggleOverview();
696 break;
697 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
698 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
699 HandleWindowSnapOrDock(action);
700 break;
701 case WINDOW_MINIMIZE:
702 HandleWindowMinimize();
703 break;
704 case WINDOW_POSITION_CENTER:
705 HandlePositionCenter();
706 break;
707 #if defined(OS_CHROMEOS)
708 case BRIGHTNESS_DOWN: {
709 BrightnessControlDelegate* delegate =
710 WmShell::Get()->brightness_control_delegate();
711 if (delegate)
712 delegate->HandleBrightnessDown(accelerator);
713 break;
714 }
715 case BRIGHTNESS_UP: {
716 BrightnessControlDelegate* delegate =
717 WmShell::Get()->brightness_control_delegate();
718 if (delegate)
719 delegate->HandleBrightnessUp(accelerator);
720 break;
721 }
722 case DEBUG_SHOW_TOAST:
723 case DEBUG_TOGGLE_TOUCH_PAD:
724 case DEBUG_TOGGLE_TOUCH_SCREEN:
725 case DEBUG_TOGGLE_TOUCH_VIEW:
726 debug::PerformDebugActionIfEnabled(action);
727 break;
728 case DISABLE_CAPS_LOCK:
729 HandleDisableCapsLock();
730 break;
731 case KEYBOARD_BRIGHTNESS_DOWN: {
732 KeyboardBrightnessControlDelegate* delegate =
733 WmShell::Get()->keyboard_brightness_control_delegate();
734 if (delegate)
735 delegate->HandleKeyboardBrightnessDown(accelerator);
736 break;
737 }
738 case KEYBOARD_BRIGHTNESS_UP: {
739 KeyboardBrightnessControlDelegate* delegate =
740 WmShell::Get()->keyboard_brightness_control_delegate();
741 if (delegate)
742 delegate->HandleKeyboardBrightnessUp(accelerator);
743 break;
744 }
745 case LOCK_SCREEN:
746 HandleLock();
747 break;
748 case SUSPEND:
749 HandleSuspend();
750 break;
751 case SWITCH_TO_NEXT_USER:
752 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
753 break;
754 case SWITCH_TO_PREVIOUS_USER:
755 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
756 break;
757 case TOGGLE_CAPS_LOCK:
758 HandleToggleCapsLock();
759 break;
760 case TOGGLE_SPOKEN_FEEDBACK:
761 HandleToggleSpokenFeedback();
762 break;
763 case TOGGLE_WIFI:
764 WmShell::Get()->system_tray_notifier()->NotifyRequestToggleWifi();
765 break;
766 case VOLUME_DOWN:
767 HandleVolumeDown(accelerator);
768 break;
769 case VOLUME_MUTE:
770 HandleVolumeMute(accelerator);
771 break;
772 case VOLUME_UP:
773 HandleVolumeUp(accelerator);
774 break;
775 #else
776 case DUMMY_FOR_RESERVED:
777 NOTREACHED();
778 break;
779 #endif
780 default:
781 // Temporary until mash transition complete. Needed as some actions
782 // don't yet work with mash.
783 DCHECK(delegate_ && delegate_->HandlesAction(action));
784 delegate_->PerformAction(action, accelerator);
785 break;
786 }
787 }
788
789 bool AcceleratorController::ShouldActionConsumeKeyEvent(
790 AcceleratorAction action) {
791 // Adding new exceptions is *STRONGLY* discouraged.
792 return true;
793 }
794
795 AcceleratorController::AcceleratorProcessingRestriction
796 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
797 if (WmShell::Get()->IsPinned() &&
798 actions_allowed_in_pinned_mode_.find(action) ==
799 actions_allowed_in_pinned_mode_.end()) {
800 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
801 }
802 WmShell* wm_shell = WmShell::Get();
803 if (!wm_shell->GetSessionStateDelegate()->IsActiveUserSessionStarted() &&
804 actions_allowed_at_login_screen_.find(action) ==
805 actions_allowed_at_login_screen_.end()) {
806 return RESTRICTION_PREVENT_PROCESSING;
807 }
808 if (wm_shell->GetSessionStateDelegate()->IsScreenLocked() &&
809 actions_allowed_at_lock_screen_.find(action) ==
810 actions_allowed_at_lock_screen_.end()) {
811 return RESTRICTION_PREVENT_PROCESSING;
812 }
813 if (wm_shell->delegate()->IsRunningInForcedAppMode() &&
814 actions_allowed_in_app_mode_.find(action) ==
815 actions_allowed_in_app_mode_.end()) {
816 return RESTRICTION_PREVENT_PROCESSING;
817 }
818 if (WmShell::Get()->IsSystemModalWindowOpen() &&
819 actions_allowed_at_modal_window_.find(action) ==
820 actions_allowed_at_modal_window_.end()) {
821 // Note we prevent the shortcut from propagating so it will not
822 // be passed to the modal window. This is important for things like
823 // Alt+Tab that would cause an undesired effect in the modal window by
824 // cycling through its window elements.
825 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
826 }
827 if (wm_shell->mru_window_tracker()->BuildMruWindowList().empty() &&
828 actions_needing_window_.find(action) != actions_needing_window_.end()) {
829 wm_shell->accessibility_delegate()->TriggerAccessibilityAlert(
830 A11Y_ALERT_WINDOW_NEEDED);
831 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
832 }
833 return RESTRICTION_NONE;
834 }
835
836 } // namespace ash
OLDNEW
« no previous file with comments | « ash/accelerators/accelerator_controller.h ('k') | ash/accelerators/accelerator_controller_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698