Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blobbee96b28178e9c5bc18f6d5fad0fb91ff91335e6
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.
5 #include "ash/accelerators/accelerator_controller.h"
7 #include <algorithm>
8 #include <cmath>
9 #include <string>
11 #include "ash/accelerators/accelerator_commands.h"
12 #include "ash/accelerators/debug_commands.h"
13 #include "ash/ash_switches.h"
14 #include "ash/debug.h"
15 #include "ash/display/display_controller.h"
16 #include "ash/display/display_manager.h"
17 #include "ash/display/display_util.h"
18 #include "ash/focus_cycler.h"
19 #include "ash/gpu_support.h"
20 #include "ash/ime_control_delegate.h"
21 #include "ash/magnifier/magnification_controller.h"
22 #include "ash/magnifier/partial_magnification_controller.h"
23 #include "ash/media_delegate.h"
24 #include "ash/multi_profile_uma.h"
25 #include "ash/new_window_delegate.h"
26 #include "ash/root_window_controller.h"
27 #include "ash/rotator/screen_rotation_animator.h"
28 #include "ash/rotator/window_rotation.h"
29 #include "ash/screenshot_delegate.h"
30 #include "ash/session/session_state_delegate.h"
31 #include "ash/shelf/shelf.h"
32 #include "ash/shelf/shelf_delegate.h"
33 #include "ash/shelf/shelf_model.h"
34 #include "ash/shelf/shelf_widget.h"
35 #include "ash/shell.h"
36 #include "ash/shell_delegate.h"
37 #include "ash/shell_window_ids.h"
38 #include "ash/system/brightness_control_delegate.h"
39 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
40 #include "ash/system/status_area_widget.h"
41 #include "ash/system/tray/system_tray.h"
42 #include "ash/system/tray/system_tray_delegate.h"
43 #include "ash/system/tray/system_tray_notifier.h"
44 #include "ash/system/web_notification/web_notification_tray.h"
45 #include "ash/touch/touch_hud_debug.h"
46 #include "ash/utility/partial_screenshot_controller.h"
47 #include "ash/volume_control_delegate.h"
48 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
49 #include "ash/wm/mru_window_tracker.h"
50 #include "ash/wm/overview/window_selector_controller.h"
51 #include "ash/wm/power_button_controller.h"
52 #include "ash/wm/window_cycle_controller.h"
53 #include "ash/wm/window_state.h"
54 #include "ash/wm/window_util.h"
55 #include "ash/wm/wm_event.h"
56 #include "base/bind.h"
57 #include "base/command_line.h"
58 #include "base/metrics/user_metrics.h"
59 #include "ui/aura/env.h"
60 #include "ui/base/accelerators/accelerator.h"
61 #include "ui/base/accelerators/accelerator_manager.h"
62 #include "ui/compositor/layer.h"
63 #include "ui/compositor/layer_animation_sequence.h"
64 #include "ui/compositor/layer_animator.h"
65 #include "ui/events/event.h"
66 #include "ui/events/keycodes/keyboard_codes.h"
67 #include "ui/gfx/screen.h"
68 #include "ui/views/controls/webview/webview.h"
70 #if defined(OS_CHROMEOS)
71 #include "ash/system/chromeos/keyboard_brightness_controller.h"
72 #include "base/sys_info.h"
73 #include "ui/base/ime/chromeos/ime_keyboard.h"
74 #include "ui/base/ime/chromeos/input_method_manager.h"
75 #endif // defined(OS_CHROMEOS)
77 namespace ash {
78 namespace {
80 using base::UserMetricsAction;
82 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
83 if (accelerator.key_code() == ui::VKEY_TAB)
84 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
86 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
87 WindowCycleController::BACKWARD);
90 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
91 if (accelerator.key_code() == ui::VKEY_TAB)
92 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
94 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
95 WindowCycleController::FORWARD);
98 void HandleRotatePaneFocus(Shell::Direction direction) {
99 Shell* shell = Shell::GetInstance();
100 switch (direction) {
101 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
102 case Shell::FORWARD: {
103 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
104 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
105 break;
107 case Shell::BACKWARD: {
108 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
109 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
110 break;
115 void HandleFocusShelf() {
116 Shell* shell = Shell::GetInstance();
117 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
118 shell->focus_cycler()->FocusWidget(
119 Shelf::ForPrimaryDisplay()->shelf_widget());
122 void HandleLaunchAppN(int n) {
123 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
124 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
127 void HandleLaunchLastApp() {
128 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
129 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
132 bool CanHandleMagnifyScreen() {
133 Shell* shell = Shell::GetInstance();
134 return shell->magnification_controller()->IsEnabled() ||
135 shell->partial_magnification_controller()->is_enabled();
138 // Magnify the screen
139 void HandleMagnifyScreen(int delta_index) {
140 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
141 // TODO(yoshiki): Move the following logic to MagnificationController.
142 float scale =
143 ash::Shell::GetInstance()->magnification_controller()->GetScale();
144 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
145 int scale_index = std::floor(
146 std::log(scale) / std::log(ui::kMagnificationScaleFactor) + 0.5);
148 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
150 ash::Shell::GetInstance()->magnification_controller()->SetScale(
151 std::pow(ui::kMagnificationScaleFactor, new_scale_index), true);
152 } else if (ash::Shell::GetInstance()->
153 partial_magnification_controller()->is_enabled()) {
154 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
155 ash::Shell::GetInstance()->partial_magnification_controller()->
156 SetScale(scale);
160 void HandleMediaNextTrack() {
161 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
164 void HandleMediaPlayPause() {
165 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
168 void HandleMediaPrevTrack() {
169 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
172 bool CanHandleNewIncognitoWindow() {
173 return Shell::GetInstance()->delegate()->IsIncognitoAllowed();
176 void HandleNewIncognitoWindow() {
177 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
178 Shell::GetInstance()->new_window_delegate()->NewWindow(
179 true /* is_incognito */);
182 void HandleNewTab(const ui::Accelerator& accelerator) {
183 if (accelerator.key_code() == ui::VKEY_T)
184 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
185 Shell::GetInstance()->new_window_delegate()->NewTab();
188 void HandleNewWindow() {
189 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
190 Shell::GetInstance()->new_window_delegate()->NewWindow(
191 false /* is_incognito */);
194 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
195 const ui::Accelerator& previous_accelerator) {
196 // This check is necessary e.g. not to process the Shift+Alt+
197 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
198 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
199 // is released.
200 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
201 if (previous_accelerator.type() == ui::ET_KEY_RELEASED &&
202 // Workaround for crbug.com/139556. CJK IME users tend to press
203 // Enter (or Space) and Shift+Alt almost at the same time to commit
204 // an IME string and then switch from the IME to the English layout.
205 // This workaround allows the user to trigger NEXT_IME even if the
206 // user presses Shift+Alt before releasing Enter.
207 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
208 previous_key_code != ui::VKEY_RETURN &&
209 previous_key_code != ui::VKEY_SPACE) {
210 // We totally ignore this accelerator.
211 // TODO(mazda): Fix crbug.com/158217
212 return false;
214 return ime_control_delegate && ime_control_delegate->CanCycleIme();
217 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
218 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
219 ime_control_delegate->HandleNextIme();
222 void HandleOpenFeedbackPage() {
223 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
224 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
227 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
228 return ime_control_delegate && ime_control_delegate->CanCycleIme();
231 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
232 const ui::Accelerator& accelerator) {
233 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
234 if (accelerator.type() == ui::ET_KEY_PRESSED)
235 ime_control_delegate->HandlePreviousIme();
236 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
239 void HandleRestoreTab() {
240 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
241 Shell::GetInstance()->new_window_delegate()->RestoreTab();
244 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
245 switch (current) {
246 case gfx::Display::ROTATE_0:
247 return gfx::Display::ROTATE_90;
248 case gfx::Display::ROTATE_90:
249 return gfx::Display::ROTATE_180;
250 case gfx::Display::ROTATE_180:
251 return gfx::Display::ROTATE_270;
252 case gfx::Display::ROTATE_270:
253 return gfx::Display::ROTATE_0;
255 NOTREACHED() << "Unknown rotation:" << current;
256 return gfx::Display::ROTATE_0;
259 // Rotates the screen.
260 void HandleRotateScreen() {
261 if (Shell::GetInstance()->display_manager()->IsInUnifiedMode())
262 return;
264 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
265 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
266 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
267 const DisplayInfo& display_info =
268 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
269 ash::ScreenRotationAnimator(display.id())
270 .Rotate(GetNextRotation(display_info.GetActiveRotation()),
271 gfx::Display::ROTATION_SOURCE_USER);
274 // Rotate the active window.
275 void HandleRotateActiveWindow() {
276 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
277 aura::Window* active_window = wm::GetActiveWindow();
278 if (active_window) {
279 // The rotation animation bases its target transform on the current
280 // rotation and position. Since there could be an animation in progress
281 // right now, queue this animation so when it starts it picks up a neutral
282 // rotation and position. Use replace so we only enqueue one at a time.
283 active_window->layer()->GetAnimator()->
284 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
285 active_window->layer()->GetAnimator()->StartAnimation(
286 new ui::LayerAnimationSequence(
287 new ash::WindowRotation(360, active_window->layer())));
291 bool CanHandleScaleReset() {
292 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
293 int64 display_id = display_manager->GetDisplayIdForUIScaling();
294 return (display_id != gfx::Display::kInvalidDisplayID &&
295 display_manager->GetDisplayInfo(display_id).configured_ui_scale() !=
296 1.0f);
299 void HandleScaleReset() {
300 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset"));
301 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
302 int64 display_id = display_manager->GetDisplayIdForUIScaling();
303 display_manager->SetDisplayUIScale(display_id, 1.0f);
306 bool CanHandleScaleUI() {
307 return Shell::GetInstance()->display_manager()->IsDisplayUIScalingEnabled();
310 void HandleScaleUI(bool up) {
311 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
312 int64 display_id = display_manager->GetDisplayIdForUIScaling();
314 if (up) {
315 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up"));
316 } else {
317 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down"));
320 const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
321 float next_scale = GetNextUIScale(display_info, up);
322 display_manager->SetDisplayUIScale(display_id, next_scale);
325 void HandleShowKeyboardOverlay() {
326 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
327 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
330 bool CanHandleShowMessageCenterBubble() {
331 RootWindowController* controller =
332 RootWindowController::ForTargetRootWindow();
333 StatusAreaWidget* status_area_widget =
334 controller->shelf()->status_area_widget();
335 return status_area_widget &&
336 status_area_widget->web_notification_tray()->visible();
339 void HandleShowMessageCenterBubble() {
340 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
341 RootWindowController* controller =
342 RootWindowController::ForTargetRootWindow();
343 StatusAreaWidget* status_area_widget =
344 controller->shelf()->status_area_widget();
345 if (status_area_widget) {
346 WebNotificationTray* notification_tray =
347 status_area_widget->web_notification_tray();
348 if (notification_tray->visible())
349 notification_tray->ShowMessageCenterBubble();
353 void HandleShowSystemTrayBubble() {
354 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
355 RootWindowController* controller =
356 RootWindowController::ForTargetRootWindow();
357 if (!controller->GetSystemTray()->HasSystemBubble())
358 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
361 void HandleShowTaskManager() {
362 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
363 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
366 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
367 const ui::Accelerator& accelerator) {
368 return ime_control_delegate &&
369 ime_control_delegate->CanSwitchIme(accelerator);
372 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
373 const ui::Accelerator& accelerator) {
374 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
375 ime_control_delegate->HandleSwitchIme(accelerator);
378 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
379 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
380 DCHECK(screenshot_delegate);
381 Shell::GetInstance()
382 ->partial_screenshot_controller()
383 ->StartPartialScreenshotSession(screenshot_delegate);
386 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
387 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
388 DCHECK(screenshot_delegate);
389 if (screenshot_delegate->CanTakeScreenshot())
390 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
393 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
394 const ui::Accelerator& previous_accelerator) {
395 if (accelerator.key_code() == ui::VKEY_LWIN) {
396 // If something else was pressed between the Search key (LWIN)
397 // being pressed and released, then ignore the release of the
398 // Search key.
399 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
400 previous_accelerator.key_code() != ui::VKEY_LWIN) {
401 return false;
404 // When spoken feedback is enabled, we should neither toggle the list nor
405 // consume the key since Search+Shift is one of the shortcuts the a11y
406 // feature uses. crbug.com/132296
407 if (Shell::GetInstance()
408 ->accessibility_delegate()
409 ->IsSpokenFeedbackEnabled()) {
410 return false;
413 return true;
416 void HandleToggleAppList(const ui::Accelerator& accelerator) {
417 if (accelerator.key_code() == ui::VKEY_LWIN)
418 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
419 ash::Shell::GetInstance()->ToggleAppList(NULL);
422 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
423 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
424 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
425 accelerators::ToggleFullscreen();
428 void HandleToggleOverview() {
429 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
430 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
433 bool CanHandleWindowSnapOrDock() {
434 wm::WindowState* window_state = wm::GetActiveWindowState();
435 // Disable window snapping shortcut key for full screen window due to
436 // http://crbug.com/135487.
437 return (window_state && window_state->IsUserPositionable() &&
438 !window_state->IsFullscreen());
441 void HandleWindowSnapOrDock(AcceleratorAction action) {
442 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
443 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
444 else
445 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
447 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT ?
448 wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT :
449 wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
450 wm::GetActiveWindowState()->OnWMEvent(&event);
453 void HandleWindowMinimize() {
454 base::RecordAction(
455 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
456 accelerators::ToggleMinimized();
459 bool CanHandlePositionCenter() {
460 // Docked windows do not support centering.
461 wm::WindowState* window_state = wm::GetActiveWindowState();
462 return (window_state && !window_state->IsDocked());
465 void HandlePositionCenter() {
466 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
467 wm::CenterWindow(wm::GetActiveWindow());
470 #if defined(OS_CHROMEOS)
471 void HandleBrightnessDown(BrightnessControlDelegate* delegate,
472 const ui::Accelerator& accelerator) {
473 if (delegate)
474 delegate->HandleBrightnessDown(accelerator);
477 void HandleBrightnessUp(BrightnessControlDelegate* delegate,
478 const ui::Accelerator& accelerator) {
479 if (delegate)
480 delegate->HandleBrightnessUp(accelerator);
483 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
484 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
485 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
486 (previous_key_code != ui::VKEY_LSHIFT &&
487 previous_key_code != ui::VKEY_SHIFT &&
488 previous_key_code != ui::VKEY_RSHIFT)) {
489 // If something else was pressed between the Shift key being pressed
490 // and released, then ignore the release of the Shift key.
491 return false;
493 chromeos::input_method::InputMethodManager* ime =
494 chromeos::input_method::InputMethodManager::Get();
495 chromeos::input_method::ImeKeyboard* keyboard =
496 ime ? ime->GetImeKeyboard() : NULL;
497 return (keyboard && keyboard->CapsLockIsEnabled());
500 void HandleDisableCapsLock() {
501 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
502 chromeos::input_method::InputMethodManager* ime =
503 chromeos::input_method::InputMethodManager::Get();
504 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
507 void HandleKeyboardBrightnessDown(KeyboardBrightnessControlDelegate* delegate,
508 const ui::Accelerator& accelerator) {
509 if (delegate)
510 delegate->HandleKeyboardBrightnessDown(accelerator);
513 void HandleKeyboardBrightnessUp(KeyboardBrightnessControlDelegate* delegate,
514 const ui::Accelerator& accelerator) {
515 if (delegate)
516 delegate->HandleKeyboardBrightnessUp(accelerator);
519 void HandleLock() {
520 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
521 Shell::GetInstance()->session_state_delegate()->LockScreen();
524 void HandleCrosh() {
525 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
527 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
530 void HandleFileManager() {
531 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
533 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
536 void HandleGetHelp() {
537 Shell::GetInstance()->new_window_delegate()->OpenGetHelp();
540 bool CanHandleSilenceSpokenFeedback() {
541 AccessibilityDelegate* delegate =
542 Shell::GetInstance()->accessibility_delegate();
543 return delegate->IsSpokenFeedbackEnabled();
546 void HandleSilenceSpokenFeedback() {
547 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
548 Shell::GetInstance()->accessibility_delegate()->SilenceSpokenFeedback();
551 void HandleSwapPrimaryDisplay() {
552 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
553 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
556 bool CanHandleCycleUser() {
557 Shell* shell = Shell::GetInstance();
558 return shell->delegate()->IsMultiProfilesEnabled() &&
559 shell->session_state_delegate()->NumberOfLoggedInUsers() > 1;
562 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
563 MultiProfileUMA::RecordSwitchActiveUser(
564 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
565 switch (cycle_user) {
566 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
567 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
568 break;
569 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
570 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
571 break;
573 Shell::GetInstance()->session_state_delegate()->CycleActiveUser(cycle_user);
576 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
577 const ui::Accelerator& previous_accelerator) {
578 if (accelerator.key_code() == ui::VKEY_LWIN) {
579 // If something else was pressed between the Search key (LWIN)
580 // being pressed and released, then ignore the release of the
581 // Search key.
582 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
583 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
584 previous_accelerator.key_code() != ui::VKEY_LWIN)
585 return false;
587 chromeos::input_method::InputMethodManager* ime =
588 chromeos::input_method::InputMethodManager::Get();
589 return ime && ime->GetImeKeyboard();
592 void HandleToggleCapsLock() {
593 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
594 chromeos::input_method::InputMethodManager* ime =
595 chromeos::input_method::InputMethodManager::Get();
596 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
597 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
600 void HandleToggleMirrorMode() {
601 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
602 Shell::GetInstance()->display_controller()->ToggleMirrorMode();
605 void HandleToggleSpokenFeedback() {
606 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
608 Shell::GetInstance()->accessibility_delegate()->
609 ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_SHOW);
612 bool CanHandleToggleTouchViewTesting() {
613 return base::CommandLine::ForCurrentProcess()->HasSwitch(
614 switches::kAshEnableTouchViewTesting);
617 void HandleToggleTouchViewTesting() {
618 // TODO(skuhne): This is only temporary! Remove this!
619 MaximizeModeController* controller = Shell::GetInstance()->
620 maximize_mode_controller();
621 controller->EnableMaximizeModeWindowManager(
622 !controller->IsMaximizeModeWindowManagerEnabled());
625 bool CanHandleTouchHud() {
626 return RootWindowController::ForTargetRootWindow()->touch_hud_debug();
629 void HandleTouchHudClear() {
630 RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear();
633 void HandleTouchHudModeChange() {
634 RootWindowController* controller =
635 RootWindowController::ForTargetRootWindow();
636 controller->touch_hud_debug()->ChangeToNextMode();
639 void HandleVolumeDown(const ui::Accelerator& accelerator) {
640 VolumeControlDelegate* volume_delegate =
641 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
642 if (volume_delegate)
643 volume_delegate->HandleVolumeDown(accelerator);
646 void HandleVolumeMute(const ui::Accelerator& accelerator) {
647 VolumeControlDelegate* volume_delegate =
648 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
649 if (volume_delegate)
650 volume_delegate->HandleVolumeMute(accelerator);
653 void HandleVolumeUp(const ui::Accelerator& accelerator) {
654 VolumeControlDelegate* volume_delegate =
655 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
656 if (volume_delegate)
657 volume_delegate->HandleVolumeUp(accelerator);
660 #endif // defined(OS_CHROMEOS)
662 } // namespace
664 ////////////////////////////////////////////////////////////////////////////////
665 // AcceleratorController, public:
667 AcceleratorController::AcceleratorController()
668 : accelerator_manager_(new ui::AcceleratorManager),
669 accelerator_history_(new ui::AcceleratorHistory) {
670 Init();
673 AcceleratorController::~AcceleratorController() {
676 void AcceleratorController::Register(const ui::Accelerator& accelerator,
677 ui::AcceleratorTarget* target) {
678 accelerator_manager_->Register(accelerator,
679 ui::AcceleratorManager::kNormalPriority,
680 target);
683 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
684 ui::AcceleratorTarget* target) {
685 accelerator_manager_->Unregister(accelerator, target);
688 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
689 accelerator_manager_->UnregisterAll(target);
692 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
693 if (ime_control_delegate_) {
694 return accelerator_manager_->Process(
695 ime_control_delegate_->RemapAccelerator(accelerator));
697 return accelerator_manager_->Process(accelerator);
700 bool AcceleratorController::IsRegistered(
701 const ui::Accelerator& accelerator) const {
702 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
705 bool AcceleratorController::IsPreferred(
706 const ui::Accelerator& accelerator) const {
707 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
708 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
710 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
711 accelerators_.find(remapped_accelerator);
712 if (iter == accelerators_.end())
713 return false; // not an accelerator.
715 return preferred_actions_.find(iter->second) != preferred_actions_.end();
718 bool AcceleratorController::IsReserved(
719 const ui::Accelerator& accelerator) const {
720 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
721 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
723 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
724 accelerators_.find(remapped_accelerator);
725 if (iter == accelerators_.end())
726 return false; // not an accelerator.
728 return reserved_actions_.find(iter->second) != reserved_actions_.end();
731 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
732 if (CanPerformAction(action, ui::Accelerator())) {
733 PerformAction(action, ui::Accelerator());
734 return true;
736 return false;
739 AcceleratorController::AcceleratorProcessingRestriction
740 AcceleratorController::GetCurrentAcceleratorRestriction() {
741 return GetAcceleratorProcessingRestriction(-1);
744 void AcceleratorController::SetBrightnessControlDelegate(
745 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
746 brightness_control_delegate_ = brightness_control_delegate.Pass();
749 void AcceleratorController::SetImeControlDelegate(
750 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
751 ime_control_delegate_ = ime_control_delegate.Pass();
754 void AcceleratorController::SetScreenshotDelegate(
755 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
756 screenshot_delegate_ = screenshot_delegate.Pass();
759 ////////////////////////////////////////////////////////////////////////////////
760 // AcceleratorController, ui::AcceleratorTarget implementation:
762 bool AcceleratorController::AcceleratorPressed(
763 const ui::Accelerator& accelerator) {
764 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
765 accelerators_.find(accelerator);
766 DCHECK(it != accelerators_.end());
767 AcceleratorAction action = it->second;
768 if (CanPerformAction(action, accelerator)) {
769 PerformAction(action, accelerator);
770 return ShouldActionConsumeKeyEvent(action);
772 return false;
775 bool AcceleratorController::CanHandleAccelerators() const {
776 return true;
779 ///////////////////////////////////////////////////////////////////////////////
780 // AcceleratorController, private:
782 void AcceleratorController::Init() {
783 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
784 actions_allowed_at_login_screen_.insert(
785 kActionsAllowedAtLoginOrLockScreen[i]);
786 actions_allowed_at_lock_screen_.insert(
787 kActionsAllowedAtLoginOrLockScreen[i]);
789 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
790 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
791 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
792 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
793 for (size_t i = 0; i < kPreferredActionsLength; ++i)
794 preferred_actions_.insert(kPreferredActions[i]);
795 for (size_t i = 0; i < kReservedActionsLength; ++i)
796 reserved_actions_.insert(kReservedActions[i]);
797 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
798 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
799 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
800 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
801 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
802 actions_needing_window_.insert(kActionsNeedingWindow[i]);
804 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
806 if (debug::DebugAcceleratorsEnabled()) {
807 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
808 // All debug accelerators are reserved.
809 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
810 reserved_actions_.insert(kDebugAcceleratorData[i].action);
813 #if defined(OS_CHROMEOS)
814 keyboard_brightness_control_delegate_.reset(
815 new KeyboardBrightnessController());
816 #endif
819 void AcceleratorController::RegisterAccelerators(
820 const AcceleratorData accelerators[],
821 size_t accelerators_length) {
822 for (size_t i = 0; i < accelerators_length; ++i) {
823 ui::Accelerator accelerator(accelerators[i].keycode,
824 accelerators[i].modifiers);
825 accelerator.set_type(accelerators[i].trigger_on_press ?
826 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
827 Register(accelerator, this);
828 accelerators_.insert(
829 std::make_pair(accelerator, accelerators[i].action));
833 bool AcceleratorController::CanPerformAction(
834 AcceleratorAction action,
835 const ui::Accelerator& accelerator) {
836 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
837 accelerator.IsRepeat()) {
838 return false;
841 AcceleratorProcessingRestriction restriction =
842 GetAcceleratorProcessingRestriction(action);
843 if (restriction != RESTRICTION_NONE)
844 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
846 const ui::Accelerator& previous_accelerator =
847 accelerator_history_->previous_accelerator();
849 // True should be returned if running |action| does something. Otherwise,
850 // false should be returned to give the web contents a chance at handling the
851 // accelerator.
852 switch (action) {
853 case DEBUG_PRINT_LAYER_HIERARCHY:
854 case DEBUG_PRINT_VIEW_HIERARCHY:
855 case DEBUG_PRINT_WINDOW_HIERARCHY:
856 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
857 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
858 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
859 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
860 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
861 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
862 return debug::DebugAcceleratorsEnabled();
863 case MAGNIFY_SCREEN_ZOOM_IN:
864 case MAGNIFY_SCREEN_ZOOM_OUT:
865 return CanHandleMagnifyScreen();
866 case NEW_INCOGNITO_WINDOW:
867 return CanHandleNewIncognitoWindow();
868 case NEXT_IME:
869 return CanHandleNextIme(ime_control_delegate_.get(),
870 previous_accelerator);
871 case PREVIOUS_IME:
872 return CanHandlePreviousIme(ime_control_delegate_.get());
873 case SCALE_UI_RESET:
874 return CanHandleScaleReset();
875 case SCALE_UI_UP:
876 case SCALE_UI_DOWN:
877 return CanHandleScaleUI();
878 case SHOW_MESSAGE_CENTER_BUBBLE:
879 return CanHandleShowMessageCenterBubble();
880 case SWITCH_IME:
881 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
882 case TOGGLE_APP_LIST:
883 return CanHandleToggleAppList(accelerator, previous_accelerator);
884 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
885 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
886 return CanHandleWindowSnapOrDock();
887 case WINDOW_POSITION_CENTER:
888 return CanHandlePositionCenter();
889 #if defined(OS_CHROMEOS)
890 case DEBUG_ADD_REMOVE_DISPLAY:
891 return debug::DebugAcceleratorsEnabled();
892 case DISABLE_CAPS_LOCK:
893 return CanHandleDisableCapsLock(previous_accelerator);
894 case SILENCE_SPOKEN_FEEDBACK:
895 return CanHandleSilenceSpokenFeedback();
896 case SWITCH_TO_PREVIOUS_USER:
897 case SWITCH_TO_NEXT_USER:
898 return CanHandleCycleUser();
899 case TOGGLE_CAPS_LOCK:
900 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
901 case TOGGLE_TOUCH_VIEW_TESTING:
902 return CanHandleToggleTouchViewTesting();
903 case TOUCH_HUD_CLEAR:
904 case TOUCH_HUD_MODE_CHANGE:
905 return CanHandleTouchHud();
906 #endif
908 case CYCLE_BACKWARD_MRU:
909 case CYCLE_FORWARD_MRU:
910 case EXIT:
911 case FOCUS_NEXT_PANE:
912 case FOCUS_PREVIOUS_PANE:
913 case FOCUS_SHELF:
914 case LAUNCH_APP_0:
915 case LAUNCH_APP_1:
916 case LAUNCH_APP_2:
917 case LAUNCH_APP_3:
918 case LAUNCH_APP_4:
919 case LAUNCH_APP_5:
920 case LAUNCH_APP_6:
921 case LAUNCH_APP_7:
922 case LAUNCH_LAST_APP:
923 case MEDIA_NEXT_TRACK:
924 case MEDIA_PLAY_PAUSE:
925 case MEDIA_PREV_TRACK:
926 case NEW_TAB:
927 case NEW_WINDOW:
928 case OPEN_FEEDBACK_PAGE:
929 case PRINT_UI_HIERARCHIES:
930 case RESTORE_TAB:
931 case ROTATE_SCREEN:
932 case ROTATE_WINDOW:
933 case SHOW_KEYBOARD_OVERLAY:
934 case SHOW_SYSTEM_TRAY_BUBBLE:
935 case SHOW_TASK_MANAGER:
936 case TAKE_PARTIAL_SCREENSHOT:
937 case TAKE_SCREENSHOT:
938 case TOGGLE_FULLSCREEN:
939 case TOGGLE_MAXIMIZED:
940 case TOGGLE_OVERVIEW:
941 case WINDOW_MINIMIZE:
942 #if defined(OS_CHROMEOS)
943 case BRIGHTNESS_DOWN:
944 case BRIGHTNESS_UP:
945 case DISABLE_GPU_WATCHDOG:
946 case KEYBOARD_BRIGHTNESS_DOWN:
947 case KEYBOARD_BRIGHTNESS_UP:
948 case LOCK_PRESSED:
949 case LOCK_RELEASED:
950 case LOCK_SCREEN:
951 case OPEN_CROSH:
952 case OPEN_FILE_MANAGER:
953 case OPEN_GET_HELP:
954 case POWER_PRESSED:
955 case POWER_RELEASED:
956 case SWAP_PRIMARY_DISPLAY:
957 case TOGGLE_MIRROR_MODE:
958 case TOGGLE_SPOKEN_FEEDBACK:
959 case TOGGLE_WIFI:
960 case TOUCH_HUD_PROJECTION_TOGGLE:
961 case VOLUME_DOWN:
962 case VOLUME_MUTE:
963 case VOLUME_UP:
964 #else
965 case DUMMY_FOR_RESERVED:
966 #endif
967 return true;
969 return false;
972 void AcceleratorController::PerformAction(AcceleratorAction action,
973 const ui::Accelerator& accelerator) {
974 AcceleratorProcessingRestriction restriction =
975 GetAcceleratorProcessingRestriction(action);
976 if (restriction != RESTRICTION_NONE)
977 return;
979 // If your accelerator invokes more than one line of code, please either
980 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
981 // below) or pull it into a HandleFoo() function above.
982 switch (action) {
983 case CYCLE_BACKWARD_MRU:
984 HandleCycleBackwardMRU(accelerator);
985 break;
986 case CYCLE_FORWARD_MRU:
987 HandleCycleForwardMRU(accelerator);
988 break;
989 case DEBUG_PRINT_LAYER_HIERARCHY:
990 case DEBUG_PRINT_VIEW_HIERARCHY:
991 case DEBUG_PRINT_WINDOW_HIERARCHY:
992 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
993 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
994 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
995 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
996 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
997 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
998 debug::PerformDebugActionIfEnabled(action);
999 break;
1000 case EXIT:
1001 // UMA metrics are recorded in the handler.
1002 exit_warning_handler_.HandleAccelerator();
1003 break;
1004 case FOCUS_NEXT_PANE:
1005 HandleRotatePaneFocus(Shell::FORWARD);
1006 break;
1007 case FOCUS_PREVIOUS_PANE:
1008 HandleRotatePaneFocus(Shell::BACKWARD);
1009 break;
1010 case FOCUS_SHELF:
1011 HandleFocusShelf();
1012 break;
1013 case LAUNCH_APP_0:
1014 HandleLaunchAppN(0);
1015 break;
1016 case LAUNCH_APP_1:
1017 HandleLaunchAppN(1);
1018 break;
1019 case LAUNCH_APP_2:
1020 HandleLaunchAppN(2);
1021 break;
1022 case LAUNCH_APP_3:
1023 HandleLaunchAppN(3);
1024 break;
1025 case LAUNCH_APP_4:
1026 HandleLaunchAppN(4);
1027 break;
1028 case LAUNCH_APP_5:
1029 HandleLaunchAppN(5);
1030 break;
1031 case LAUNCH_APP_6:
1032 HandleLaunchAppN(6);
1033 break;
1034 case LAUNCH_APP_7:
1035 HandleLaunchAppN(7);
1036 break;
1037 case LAUNCH_LAST_APP:
1038 HandleLaunchLastApp();
1039 break;
1040 case MAGNIFY_SCREEN_ZOOM_IN:
1041 HandleMagnifyScreen(1);
1042 break;
1043 case MAGNIFY_SCREEN_ZOOM_OUT:
1044 HandleMagnifyScreen(-1);
1045 break;
1046 case MEDIA_NEXT_TRACK:
1047 HandleMediaNextTrack();
1048 break;
1049 case MEDIA_PLAY_PAUSE:
1050 HandleMediaPlayPause();
1051 break;
1052 case MEDIA_PREV_TRACK:
1053 HandleMediaPrevTrack();
1054 break;
1055 case NEW_INCOGNITO_WINDOW:
1056 HandleNewIncognitoWindow();
1057 break;
1058 case NEW_TAB:
1059 HandleNewTab(accelerator);
1060 break;
1061 case NEW_WINDOW:
1062 HandleNewWindow();
1063 break;
1064 case NEXT_IME:
1065 HandleNextIme(ime_control_delegate_.get());
1066 break;
1067 case OPEN_FEEDBACK_PAGE:
1068 HandleOpenFeedbackPage();
1069 break;
1070 case PREVIOUS_IME:
1071 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1072 break;
1073 case PRINT_UI_HIERARCHIES:
1074 debug::PrintUIHierarchies();
1075 break;
1076 case RESTORE_TAB:
1077 HandleRestoreTab();
1078 break;
1079 case ROTATE_SCREEN:
1080 HandleRotateScreen();
1081 break;
1082 case ROTATE_WINDOW:
1083 HandleRotateActiveWindow();
1084 break;
1085 case SCALE_UI_DOWN:
1086 HandleScaleUI(false /* down */);
1087 break;
1088 case SCALE_UI_RESET:
1089 HandleScaleReset();
1090 break;
1091 case SCALE_UI_UP:
1092 HandleScaleUI(true /* up */);
1093 break;
1094 case SHOW_KEYBOARD_OVERLAY:
1095 HandleShowKeyboardOverlay();
1096 break;
1097 case SHOW_MESSAGE_CENTER_BUBBLE:
1098 HandleShowMessageCenterBubble();
1099 break;
1100 case SHOW_SYSTEM_TRAY_BUBBLE:
1101 HandleShowSystemTrayBubble();
1102 break;
1103 case SHOW_TASK_MANAGER:
1104 HandleShowTaskManager();
1105 break;
1106 case SWITCH_IME:
1107 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1108 break;
1109 case TAKE_PARTIAL_SCREENSHOT:
1110 HandleTakePartialScreenshot(screenshot_delegate_.get());
1111 break;
1112 case TAKE_SCREENSHOT:
1113 HandleTakeScreenshot(screenshot_delegate_.get());
1114 break;
1115 case TOGGLE_APP_LIST:
1116 HandleToggleAppList(accelerator);
1117 break;
1118 case TOGGLE_FULLSCREEN:
1119 HandleToggleFullscreen(accelerator);
1120 break;
1121 case TOGGLE_MAXIMIZED:
1122 accelerators::ToggleMaximized();
1123 break;
1124 case TOGGLE_OVERVIEW:
1125 HandleToggleOverview();
1126 break;
1127 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1128 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1129 HandleWindowSnapOrDock(action);
1130 break;
1131 case WINDOW_MINIMIZE:
1132 HandleWindowMinimize();
1133 break;
1134 case WINDOW_POSITION_CENTER:
1135 HandlePositionCenter();
1136 break;
1137 #if defined(OS_CHROMEOS)
1138 case BRIGHTNESS_DOWN:
1139 HandleBrightnessDown(brightness_control_delegate_.get(), accelerator);
1140 break;
1141 case BRIGHTNESS_UP:
1142 HandleBrightnessUp(brightness_control_delegate_.get(), accelerator);
1143 break;
1144 case DEBUG_ADD_REMOVE_DISPLAY:
1145 debug::PerformDebugActionIfEnabled(action);
1146 break;
1147 case DISABLE_CAPS_LOCK:
1148 HandleDisableCapsLock();
1149 break;
1150 case DISABLE_GPU_WATCHDOG:
1151 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
1152 break;
1153 case KEYBOARD_BRIGHTNESS_DOWN:
1154 HandleKeyboardBrightnessDown(keyboard_brightness_control_delegate_.get(),
1155 accelerator);
1156 break;
1157 case KEYBOARD_BRIGHTNESS_UP:
1158 HandleKeyboardBrightnessUp(keyboard_brightness_control_delegate_.get(),
1159 accelerator);
1160 break;
1161 case LOCK_PRESSED:
1162 case LOCK_RELEASED:
1163 Shell::GetInstance()->power_button_controller()->
1164 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1165 break;
1166 case LOCK_SCREEN:
1167 HandleLock();
1168 break;
1169 case OPEN_CROSH:
1170 HandleCrosh();
1171 break;
1172 case OPEN_FILE_MANAGER:
1173 HandleFileManager();
1174 break;
1175 case OPEN_GET_HELP:
1176 HandleGetHelp();
1177 break;
1178 case POWER_PRESSED: // fallthrough
1179 case POWER_RELEASED:
1180 if (!base::SysInfo::IsRunningOnChromeOS()) {
1181 // There is no powerd, the Chrome OS power manager, in linux desktop,
1182 // so call the PowerButtonController here.
1183 Shell::GetInstance()->power_button_controller()->
1184 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1186 // We don't do anything with these at present on the device,
1187 // (power button events are reported to us from powerm via
1188 // D-BUS), but we consume them to prevent them from getting
1189 // passed to apps -- see http://crbug.com/146609.
1190 break;
1191 case SILENCE_SPOKEN_FEEDBACK:
1192 HandleSilenceSpokenFeedback();
1193 break;
1194 case SWAP_PRIMARY_DISPLAY:
1195 HandleSwapPrimaryDisplay();
1196 break;
1197 case SWITCH_TO_NEXT_USER:
1198 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
1199 break;
1200 case SWITCH_TO_PREVIOUS_USER:
1201 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
1202 break;
1203 case TOGGLE_CAPS_LOCK:
1204 HandleToggleCapsLock();
1205 break;
1206 case TOGGLE_MIRROR_MODE:
1207 HandleToggleMirrorMode();
1208 break;
1209 case TOGGLE_SPOKEN_FEEDBACK:
1210 HandleToggleSpokenFeedback();
1211 break;
1212 case TOGGLE_TOUCH_VIEW_TESTING:
1213 HandleToggleTouchViewTesting();
1214 break;
1215 case TOGGLE_WIFI:
1216 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
1217 break;
1218 case TOUCH_HUD_CLEAR:
1219 HandleTouchHudClear();
1220 break;
1221 case TOUCH_HUD_MODE_CHANGE:
1222 HandleTouchHudModeChange();
1223 break;
1224 case TOUCH_HUD_PROJECTION_TOGGLE:
1225 accelerators::ToggleTouchHudProjection();
1226 break;
1227 case VOLUME_DOWN:
1228 HandleVolumeDown(accelerator);
1229 break;
1230 case VOLUME_MUTE:
1231 HandleVolumeMute(accelerator);
1232 break;
1233 case VOLUME_UP:
1234 HandleVolumeUp(accelerator);
1235 break;
1236 #else
1237 case DUMMY_FOR_RESERVED:
1238 NOTREACHED();
1239 break;
1240 #endif
1244 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1245 AcceleratorAction action) {
1246 #if defined(OS_CHROMEOS)
1247 if (action == SILENCE_SPOKEN_FEEDBACK)
1248 return false;
1249 #endif
1251 // Adding new exceptions is *STRONGLY* discouraged.
1252 return true;
1255 AcceleratorController::AcceleratorProcessingRestriction
1256 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1257 ash::Shell* shell = ash::Shell::GetInstance();
1258 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1259 actions_allowed_at_login_screen_.find(action) ==
1260 actions_allowed_at_login_screen_.end()) {
1261 return RESTRICTION_PREVENT_PROCESSING;
1263 if (shell->session_state_delegate()->IsScreenLocked() &&
1264 actions_allowed_at_lock_screen_.find(action) ==
1265 actions_allowed_at_lock_screen_.end()) {
1266 return RESTRICTION_PREVENT_PROCESSING;
1268 if (shell->delegate()->IsRunningInForcedAppMode() &&
1269 actions_allowed_in_app_mode_.find(action) ==
1270 actions_allowed_in_app_mode_.end()) {
1271 return RESTRICTION_PREVENT_PROCESSING;
1273 if (shell->IsSystemModalWindowOpen() &&
1274 actions_allowed_at_modal_window_.find(action) ==
1275 actions_allowed_at_modal_window_.end()) {
1276 // Note we prevent the shortcut from propagating so it will not
1277 // be passed to the modal window. This is important for things like
1278 // Alt+Tab that would cause an undesired effect in the modal window by
1279 // cycling through its window elements.
1280 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1282 if (shell->mru_window_tracker()->BuildMruWindowList().empty() &&
1283 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1284 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1285 ui::A11Y_ALERT_WINDOW_NEEDED);
1286 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1288 return RESTRICTION_NONE;
1291 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1292 scoped_ptr<KeyboardBrightnessControlDelegate>
1293 keyboard_brightness_control_delegate) {
1294 keyboard_brightness_control_delegate_ =
1295 keyboard_brightness_control_delegate.Pass();
1298 } // namespace ash