Refactor partial screenshot region selector.
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blob73dbbee73ef74170fe9763bb22a6f0b8f07d6e15
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/focus_cycler.h"
18 #include "ash/gpu_support.h"
19 #include "ash/ime_control_delegate.h"
20 #include "ash/magnifier/magnification_controller.h"
21 #include "ash/magnifier/partial_magnification_controller.h"
22 #include "ash/media_delegate.h"
23 #include "ash/multi_profile_uma.h"
24 #include "ash/new_window_delegate.h"
25 #include "ash/root_window_controller.h"
26 #include "ash/rotator/screen_rotation.h"
27 #include "ash/screenshot_delegate.h"
28 #include "ash/session/session_state_delegate.h"
29 #include "ash/shelf/shelf.h"
30 #include "ash/shelf/shelf_delegate.h"
31 #include "ash/shelf/shelf_model.h"
32 #include "ash/shelf/shelf_widget.h"
33 #include "ash/shell.h"
34 #include "ash/shell_delegate.h"
35 #include "ash/shell_window_ids.h"
36 #include "ash/system/brightness_control_delegate.h"
37 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
38 #include "ash/system/status_area_widget.h"
39 #include "ash/system/tray/system_tray.h"
40 #include "ash/system/tray/system_tray_delegate.h"
41 #include "ash/system/tray/system_tray_notifier.h"
42 #include "ash/system/web_notification/web_notification_tray.h"
43 #include "ash/touch/touch_hud_debug.h"
44 #include "ash/utility/partial_screenshot_controller.h"
45 #include "ash/volume_control_delegate.h"
46 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
47 #include "ash/wm/mru_window_tracker.h"
48 #include "ash/wm/overview/window_selector_controller.h"
49 #include "ash/wm/power_button_controller.h"
50 #include "ash/wm/window_cycle_controller.h"
51 #include "ash/wm/window_state.h"
52 #include "ash/wm/window_util.h"
53 #include "ash/wm/wm_event.h"
54 #include "base/bind.h"
55 #include "base/command_line.h"
56 #include "base/metrics/user_metrics.h"
57 #include "ui/aura/env.h"
58 #include "ui/base/accelerators/accelerator.h"
59 #include "ui/base/accelerators/accelerator_manager.h"
60 #include "ui/compositor/layer.h"
61 #include "ui/compositor/layer_animation_sequence.h"
62 #include "ui/compositor/layer_animator.h"
63 #include "ui/events/event.h"
64 #include "ui/events/keycodes/keyboard_codes.h"
65 #include "ui/gfx/screen.h"
66 #include "ui/views/controls/webview/webview.h"
68 #if defined(OS_CHROMEOS)
69 #include "ash/system/chromeos/keyboard_brightness_controller.h"
70 #include "base/sys_info.h"
71 #include "ui/base/ime/chromeos/ime_keyboard.h"
72 #include "ui/base/ime/chromeos/input_method_manager.h"
73 #endif // defined(OS_CHROMEOS)
75 namespace ash {
76 namespace {
78 using base::UserMetricsAction;
80 bool CanHandleAccessibleFocusCycle() {
81 if (!Shell::GetInstance()->accessibility_delegate()->
82 IsSpokenFeedbackEnabled()) {
83 return false;
85 aura::Window* active_window = ash::wm::GetActiveWindow();
86 if (!active_window)
87 return false;
88 views::Widget* widget =
89 views::Widget::GetWidgetForNativeWindow(active_window);
90 if (!widget)
91 return false;
92 views::FocusManager* focus_manager = widget->GetFocusManager();
93 if (!focus_manager)
94 return false;
95 views::View* view = focus_manager->GetFocusedView();
96 return view && strcmp(view->GetClassName(), views::WebView::kViewClassName);
99 void HandleAccessibleFocusCycle(bool reverse) {
100 if (reverse)
101 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
102 else
103 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Next"));
105 aura::Window* active_window = ash::wm::GetActiveWindow();
106 views::Widget* widget =
107 views::Widget::GetWidgetForNativeWindow(active_window);
108 widget->GetFocusManager()->AdvanceFocus(reverse);
111 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
112 if (accelerator.key_code() == ui::VKEY_TAB)
113 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
115 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
116 WindowCycleController::BACKWARD);
119 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
120 if (accelerator.key_code() == ui::VKEY_TAB)
121 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
123 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
124 WindowCycleController::FORWARD);
127 void HandleRotatePaneFocus(Shell::Direction direction) {
128 Shell* shell = Shell::GetInstance();
129 switch (direction) {
130 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
131 case Shell::FORWARD: {
132 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
133 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
134 break;
136 case Shell::BACKWARD: {
137 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
138 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
139 break;
144 void HandleFocusShelf() {
145 Shell* shell = Shell::GetInstance();
146 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
147 shell->focus_cycler()->FocusWidget(
148 Shelf::ForPrimaryDisplay()->shelf_widget());
151 void HandleLaunchAppN(int n) {
152 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
153 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
156 void HandleLaunchLastApp() {
157 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
158 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
161 bool CanHandleMagnifyScreen() {
162 Shell* shell = Shell::GetInstance();
163 return shell->magnification_controller()->IsEnabled() ||
164 shell->partial_magnification_controller()->is_enabled();
167 // Magnify the screen
168 void HandleMagnifyScreen(int delta_index) {
169 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
170 // TODO(yoshiki): Move the following logic to MagnificationController.
171 float scale =
172 ash::Shell::GetInstance()->magnification_controller()->GetScale();
173 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
174 int scale_index = std::floor(
175 std::log(scale) / std::log(ui::kMagnificationScaleFactor) + 0.5);
177 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
179 ash::Shell::GetInstance()->magnification_controller()->SetScale(
180 std::pow(ui::kMagnificationScaleFactor, new_scale_index), true);
181 } else if (ash::Shell::GetInstance()->
182 partial_magnification_controller()->is_enabled()) {
183 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
184 ash::Shell::GetInstance()->partial_magnification_controller()->
185 SetScale(scale);
189 void HandleMediaNextTrack() {
190 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
193 void HandleMediaPlayPause() {
194 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
197 void HandleMediaPrevTrack() {
198 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
201 bool CanHandleNewIncognitoWindow() {
202 return Shell::GetInstance()->delegate()->IsIncognitoAllowed();
205 void HandleNewIncognitoWindow() {
206 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
207 Shell::GetInstance()->new_window_delegate()->NewWindow(
208 true /* is_incognito */);
211 void HandleNewTab(const ui::Accelerator& accelerator) {
212 if (accelerator.key_code() == ui::VKEY_T)
213 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
214 Shell::GetInstance()->new_window_delegate()->NewTab();
217 void HandleNewWindow() {
218 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
219 Shell::GetInstance()->new_window_delegate()->NewWindow(
220 false /* is_incognito */);
223 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
224 const ui::Accelerator& previous_accelerator) {
225 // This check is necessary e.g. not to process the Shift+Alt+
226 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
227 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
228 // is released.
229 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
230 if (previous_accelerator.type() == ui::ET_KEY_RELEASED &&
231 // Workaround for crbug.com/139556. CJK IME users tend to press
232 // Enter (or Space) and Shift+Alt almost at the same time to commit
233 // an IME string and then switch from the IME to the English layout.
234 // This workaround allows the user to trigger NEXT_IME even if the
235 // user presses Shift+Alt before releasing Enter.
236 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
237 previous_key_code != ui::VKEY_RETURN &&
238 previous_key_code != ui::VKEY_SPACE) {
239 // We totally ignore this accelerator.
240 // TODO(mazda): Fix crbug.com/158217
241 return false;
243 return ime_control_delegate && ime_control_delegate->CanCycleIme();
246 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
247 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
248 ime_control_delegate->HandleNextIme();
251 void HandleOpenFeedbackPage() {
252 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
253 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
256 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
257 return ime_control_delegate && ime_control_delegate->CanCycleIme();
260 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
261 const ui::Accelerator& accelerator) {
262 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
263 if (accelerator.type() == ui::ET_KEY_PRESSED)
264 ime_control_delegate->HandlePreviousIme();
265 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
268 void HandleRestoreTab() {
269 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
270 Shell::GetInstance()->new_window_delegate()->RestoreTab();
273 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
274 switch (current) {
275 case gfx::Display::ROTATE_0:
276 return gfx::Display::ROTATE_90;
277 case gfx::Display::ROTATE_90:
278 return gfx::Display::ROTATE_180;
279 case gfx::Display::ROTATE_180:
280 return gfx::Display::ROTATE_270;
281 case gfx::Display::ROTATE_270:
282 return gfx::Display::ROTATE_0;
284 NOTREACHED() << "Unknown rotation:" << current;
285 return gfx::Display::ROTATE_0;
288 // Rotates the screen.
289 void HandleRotateScreen() {
290 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
291 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
292 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
293 const DisplayInfo& display_info =
294 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
295 Shell::GetInstance()->display_manager()->SetDisplayRotation(
296 display.id(), GetNextRotation(display_info.rotation()));
299 // Rotate the active window.
300 void HandleRotateActiveWindow() {
301 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
302 aura::Window* active_window = wm::GetActiveWindow();
303 if (active_window) {
304 // The rotation animation bases its target transform on the current
305 // rotation and position. Since there could be an animation in progress
306 // right now, queue this animation so when it starts it picks up a neutral
307 // rotation and position. Use replace so we only enqueue one at a time.
308 active_window->layer()->GetAnimator()->
309 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
310 active_window->layer()->GetAnimator()->StartAnimation(
311 new ui::LayerAnimationSequence(
312 new ash::ScreenRotation(360, active_window->layer())));
316 bool CanHandleScaleReset() {
317 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
318 int64 display_id = display_manager->GetDisplayIdForUIScaling();
319 return (display_id != gfx::Display::kInvalidDisplayID &&
320 display_manager->GetDisplayInfo(display_id).configured_ui_scale() !=
321 1.0f);
324 void HandleScaleReset() {
325 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset"));
326 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
327 int64 display_id = display_manager->GetDisplayIdForUIScaling();
328 display_manager->SetDisplayUIScale(display_id, 1.0f);
331 bool CanHandleScaleUI() {
332 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
333 int64 display_id = display_manager->GetDisplayIdForUIScaling();
334 return display_id != gfx::Display::kInvalidDisplayID;
337 void HandleScaleUI(bool up) {
338 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
339 int64 display_id = display_manager->GetDisplayIdForUIScaling();
341 if (up) {
342 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up"));
343 } else {
344 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down"));
347 const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
348 float next_scale = DisplayManager::GetNextUIScale(display_info, up);
349 display_manager->SetDisplayUIScale(display_id, next_scale);
352 void HandleShowKeyboardOverlay() {
353 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
354 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
357 bool CanHandleShowMessageCenterBubble() {
358 RootWindowController* controller =
359 RootWindowController::ForTargetRootWindow();
360 StatusAreaWidget* status_area_widget =
361 controller->shelf()->status_area_widget();
362 return status_area_widget &&
363 status_area_widget->web_notification_tray()->visible();
366 void HandleShowMessageCenterBubble() {
367 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
368 RootWindowController* controller =
369 RootWindowController::ForTargetRootWindow();
370 StatusAreaWidget* status_area_widget =
371 controller->shelf()->status_area_widget();
372 if (status_area_widget) {
373 WebNotificationTray* notification_tray =
374 status_area_widget->web_notification_tray();
375 if (notification_tray->visible())
376 notification_tray->ShowMessageCenterBubble();
380 void HandleShowSystemTrayBubble() {
381 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
382 RootWindowController* controller =
383 RootWindowController::ForTargetRootWindow();
384 if (!controller->GetSystemTray()->HasSystemBubble())
385 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
388 void HandleShowTaskManager() {
389 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
390 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
393 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
394 const ui::Accelerator& accelerator) {
395 return ime_control_delegate &&
396 ime_control_delegate->CanSwitchIme(accelerator);
399 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
400 const ui::Accelerator& accelerator) {
401 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
402 ime_control_delegate->HandleSwitchIme(accelerator);
405 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
406 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
407 if (screenshot_delegate) {
408 ash::PartialScreenshotController::StartPartialScreenshotSession(
409 screenshot_delegate);
413 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
414 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
415 if (screenshot_delegate &&
416 screenshot_delegate->CanTakeScreenshot()) {
417 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
421 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
422 const ui::Accelerator& previous_accelerator) {
423 if (accelerator.key_code() == ui::VKEY_LWIN) {
424 // If something else was pressed between the Search key (LWIN)
425 // being pressed and released, then ignore the release of the
426 // Search key.
427 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
428 previous_accelerator.key_code() != ui::VKEY_LWIN) {
429 return false;
432 // When spoken feedback is enabled, we should neither toggle the list nor
433 // consume the key since Search+Shift is one of the shortcuts the a11y
434 // feature uses. crbug.com/132296
435 if (Shell::GetInstance()
436 ->accessibility_delegate()
437 ->IsSpokenFeedbackEnabled()) {
438 return false;
441 return true;
444 void HandleToggleAppList(const ui::Accelerator& accelerator) {
445 if (accelerator.key_code() == ui::VKEY_LWIN)
446 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
447 ash::Shell::GetInstance()->ToggleAppList(NULL);
450 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
451 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
452 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
453 accelerators::ToggleFullscreen();
456 void HandleToggleOverview() {
457 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
458 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
461 bool CanHandleWindowSnapOrDock() {
462 wm::WindowState* window_state = wm::GetActiveWindowState();
463 // Disable window snapping shortcut key for full screen window due to
464 // http://crbug.com/135487.
465 return (window_state &&
466 (window_state->window()->type() == ui::wm::WINDOW_TYPE_NORMAL ||
467 window_state->window()->type() == ui::wm::WINDOW_TYPE_PANEL) &&
468 !window_state->IsFullscreen());
471 void HandleWindowSnapOrDock(AcceleratorAction action) {
472 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
473 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
474 else
475 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
477 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT ?
478 wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT :
479 wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
480 wm::GetActiveWindowState()->OnWMEvent(&event);
483 void HandleWindowMinimize() {
484 base::RecordAction(
485 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
486 accelerators::ToggleMinimized();
489 bool CanHandlePositionCenter() {
490 // Docked windows do not support centering.
491 wm::WindowState* window_state = wm::GetActiveWindowState();
492 return (window_state && !window_state->IsDocked());
495 void HandlePositionCenter() {
496 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
497 wm::CenterWindow(wm::GetActiveWindow());
500 #if defined(OS_CHROMEOS)
501 void HandleBrightnessDown(BrightnessControlDelegate* delegate,
502 const ui::Accelerator& accelerator) {
503 if (delegate)
504 delegate->HandleBrightnessDown(accelerator);
507 void HandleBrightnessUp(BrightnessControlDelegate* delegate,
508 const ui::Accelerator& accelerator) {
509 if (delegate)
510 delegate->HandleBrightnessUp(accelerator);
513 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
514 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
515 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
516 (previous_key_code != ui::VKEY_LSHIFT &&
517 previous_key_code != ui::VKEY_SHIFT &&
518 previous_key_code != ui::VKEY_RSHIFT)) {
519 // If something else was pressed between the Shift key being pressed
520 // and released, then ignore the release of the Shift key.
521 return false;
523 chromeos::input_method::InputMethodManager* ime =
524 chromeos::input_method::InputMethodManager::Get();
525 chromeos::input_method::ImeKeyboard* keyboard =
526 ime ? ime->GetImeKeyboard() : NULL;
527 return (keyboard && keyboard->CapsLockIsEnabled());
530 void HandleDisableCapsLock() {
531 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
532 chromeos::input_method::InputMethodManager* ime =
533 chromeos::input_method::InputMethodManager::Get();
534 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
537 void HandleKeyboardBrightnessDown(KeyboardBrightnessControlDelegate* delegate,
538 const ui::Accelerator& accelerator) {
539 if (delegate)
540 delegate->HandleKeyboardBrightnessDown(accelerator);
543 void HandleKeyboardBrightnessUp(KeyboardBrightnessControlDelegate* delegate,
544 const ui::Accelerator& accelerator) {
545 if (delegate)
546 delegate->HandleKeyboardBrightnessUp(accelerator);
549 void HandleLock() {
550 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
551 Shell::GetInstance()->session_state_delegate()->LockScreen();
554 void HandleCrosh() {
555 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
557 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
560 void HandleFileManager() {
561 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
563 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
566 bool CanHandleSilenceSpokenFeedback() {
567 AccessibilityDelegate* delegate =
568 Shell::GetInstance()->accessibility_delegate();
569 return delegate->IsSpokenFeedbackEnabled();
572 void HandleSilenceSpokenFeedback() {
573 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
574 Shell::GetInstance()->accessibility_delegate()->SilenceSpokenFeedback();
577 void HandleSwapPrimaryDisplay() {
578 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
579 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
582 bool CanHandleCycleUser() {
583 Shell* shell = Shell::GetInstance();
584 return shell->delegate()->IsMultiProfilesEnabled() &&
585 shell->session_state_delegate()->NumberOfLoggedInUsers() > 1;
588 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
589 MultiProfileUMA::RecordSwitchActiveUser(
590 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
591 switch (cycle_user) {
592 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
593 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
594 break;
595 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
596 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
597 break;
599 Shell::GetInstance()->session_state_delegate()->CycleActiveUser(cycle_user);
602 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
603 const ui::Accelerator& previous_accelerator) {
604 if (accelerator.key_code() == ui::VKEY_LWIN) {
605 // If something else was pressed between the Search key (LWIN)
606 // being pressed and released, then ignore the release of the
607 // Search key.
608 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
609 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
610 previous_accelerator.key_code() != ui::VKEY_LWIN)
611 return false;
613 chromeos::input_method::InputMethodManager* ime =
614 chromeos::input_method::InputMethodManager::Get();
615 return ime && ime->GetImeKeyboard();
618 void HandleToggleCapsLock() {
619 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
620 chromeos::input_method::InputMethodManager* ime =
621 chromeos::input_method::InputMethodManager::Get();
622 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
623 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
626 void HandleToggleMirrorMode() {
627 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
628 Shell::GetInstance()->display_controller()->ToggleMirrorMode();
631 void HandleToggleSpokenFeedback() {
632 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
634 Shell::GetInstance()->accessibility_delegate()->
635 ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_SHOW);
638 bool CanHandleToggleTouchViewTesting() {
639 return base::CommandLine::ForCurrentProcess()->HasSwitch(
640 switches::kAshEnableTouchViewTesting);
643 void HandleToggleTouchViewTesting() {
644 // TODO(skuhne): This is only temporary! Remove this!
645 MaximizeModeController* controller = Shell::GetInstance()->
646 maximize_mode_controller();
647 controller->EnableMaximizeModeWindowManager(
648 !controller->IsMaximizeModeWindowManagerEnabled());
651 bool CanHandleTouchHud() {
652 return RootWindowController::ForTargetRootWindow()->touch_hud_debug();
655 void HandleTouchHudClear() {
656 RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear();
659 void HandleTouchHudModeChange() {
660 RootWindowController* controller =
661 RootWindowController::ForTargetRootWindow();
662 controller->touch_hud_debug()->ChangeToNextMode();
665 void HandleVolumeDown(const ui::Accelerator& accelerator) {
666 VolumeControlDelegate* volume_delegate =
667 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
668 if (volume_delegate)
669 volume_delegate->HandleVolumeDown(accelerator);
672 void HandleVolumeMute(const ui::Accelerator& accelerator) {
673 VolumeControlDelegate* volume_delegate =
674 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
675 if (volume_delegate)
676 volume_delegate->HandleVolumeMute(accelerator);
679 void HandleVolumeUp(const ui::Accelerator& accelerator) {
680 VolumeControlDelegate* volume_delegate =
681 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
682 if (volume_delegate)
683 volume_delegate->HandleVolumeUp(accelerator);
686 #endif // defined(OS_CHROMEOS)
688 } // namespace
690 ////////////////////////////////////////////////////////////////////////////////
691 // AcceleratorController, public:
693 AcceleratorController::AcceleratorController()
694 : accelerator_manager_(new ui::AcceleratorManager),
695 accelerator_history_(new ui::AcceleratorHistory) {
696 Init();
699 AcceleratorController::~AcceleratorController() {
702 void AcceleratorController::Register(const ui::Accelerator& accelerator,
703 ui::AcceleratorTarget* target) {
704 accelerator_manager_->Register(accelerator,
705 ui::AcceleratorManager::kNormalPriority,
706 target);
709 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
710 ui::AcceleratorTarget* target) {
711 accelerator_manager_->Unregister(accelerator, target);
714 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
715 accelerator_manager_->UnregisterAll(target);
718 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
719 if (ime_control_delegate_) {
720 return accelerator_manager_->Process(
721 ime_control_delegate_->RemapAccelerator(accelerator));
723 return accelerator_manager_->Process(accelerator);
726 bool AcceleratorController::IsRegistered(
727 const ui::Accelerator& accelerator) const {
728 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
731 bool AcceleratorController::IsPreferred(
732 const ui::Accelerator& accelerator) const {
733 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
734 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
736 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
737 accelerators_.find(remapped_accelerator);
738 if (iter == accelerators_.end())
739 return false; // not an accelerator.
741 return preferred_actions_.find(iter->second) != preferred_actions_.end();
744 bool AcceleratorController::IsReserved(
745 const ui::Accelerator& accelerator) const {
746 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
747 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
749 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
750 accelerators_.find(remapped_accelerator);
751 if (iter == accelerators_.end())
752 return false; // not an accelerator.
754 return reserved_actions_.find(iter->second) != reserved_actions_.end();
757 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
758 if (CanPerformAction(action, ui::Accelerator())) {
759 PerformAction(action, ui::Accelerator());
760 return true;
762 return false;
765 AcceleratorController::AcceleratorProcessingRestriction
766 AcceleratorController::GetCurrentAcceleratorRestriction() {
767 return GetAcceleratorProcessingRestriction(-1);
770 void AcceleratorController::SetBrightnessControlDelegate(
771 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
772 brightness_control_delegate_ = brightness_control_delegate.Pass();
775 void AcceleratorController::SetImeControlDelegate(
776 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
777 ime_control_delegate_ = ime_control_delegate.Pass();
780 void AcceleratorController::SetScreenshotDelegate(
781 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
782 screenshot_delegate_ = screenshot_delegate.Pass();
785 ////////////////////////////////////////////////////////////////////////////////
786 // AcceleratorController, ui::AcceleratorTarget implementation:
788 bool AcceleratorController::AcceleratorPressed(
789 const ui::Accelerator& accelerator) {
790 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
791 accelerators_.find(accelerator);
792 DCHECK(it != accelerators_.end());
793 AcceleratorAction action = it->second;
794 if (CanPerformAction(action, accelerator)) {
795 PerformAction(action, accelerator);
796 return ShouldActionConsumeKeyEvent(action);
798 return false;
801 bool AcceleratorController::CanHandleAccelerators() const {
802 return true;
805 ///////////////////////////////////////////////////////////////////////////////
806 // AcceleratorController, private:
808 void AcceleratorController::Init() {
809 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
810 actions_allowed_at_login_screen_.insert(
811 kActionsAllowedAtLoginOrLockScreen[i]);
812 actions_allowed_at_lock_screen_.insert(
813 kActionsAllowedAtLoginOrLockScreen[i]);
815 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
816 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
817 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
818 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
819 for (size_t i = 0; i < kPreferredActionsLength; ++i)
820 preferred_actions_.insert(kPreferredActions[i]);
821 for (size_t i = 0; i < kReservedActionsLength; ++i)
822 reserved_actions_.insert(kReservedActions[i]);
823 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
824 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
825 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
826 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
827 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
828 actions_needing_window_.insert(kActionsNeedingWindow[i]);
830 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
832 if (debug::DebugAcceleratorsEnabled()) {
833 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
834 // All debug accelerators are reserved.
835 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
836 reserved_actions_.insert(kDebugAcceleratorData[i].action);
839 #if defined(OS_CHROMEOS)
840 keyboard_brightness_control_delegate_.reset(
841 new KeyboardBrightnessController());
842 #endif
845 void AcceleratorController::RegisterAccelerators(
846 const AcceleratorData accelerators[],
847 size_t accelerators_length) {
848 for (size_t i = 0; i < accelerators_length; ++i) {
849 ui::Accelerator accelerator(accelerators[i].keycode,
850 accelerators[i].modifiers);
851 accelerator.set_type(accelerators[i].trigger_on_press ?
852 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
853 Register(accelerator, this);
854 accelerators_.insert(
855 std::make_pair(accelerator, accelerators[i].action));
859 bool AcceleratorController::CanPerformAction(
860 AcceleratorAction action,
861 const ui::Accelerator& accelerator) {
862 AcceleratorProcessingRestriction restriction =
863 GetAcceleratorProcessingRestriction(action);
864 if (restriction != RESTRICTION_NONE)
865 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
867 const ui::Accelerator& previous_accelerator =
868 accelerator_history_->previous_accelerator();
870 // True should be returned if running |action| does something. Otherwise,
871 // false should be returned to give the web contents a chance at handling the
872 // accelerator.
873 switch (action) {
874 case ACCESSIBLE_FOCUS_NEXT:
875 case ACCESSIBLE_FOCUS_PREVIOUS:
876 return CanHandleAccessibleFocusCycle();
877 case DEBUG_PRINT_LAYER_HIERARCHY:
878 case DEBUG_PRINT_VIEW_HIERARCHY:
879 case DEBUG_PRINT_WINDOW_HIERARCHY:
880 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
881 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
882 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
883 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
884 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
885 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
886 return debug::DebugAcceleratorsEnabled();
887 case MAGNIFY_SCREEN_ZOOM_IN:
888 case MAGNIFY_SCREEN_ZOOM_OUT:
889 return CanHandleMagnifyScreen();
890 case NEW_INCOGNITO_WINDOW:
891 return CanHandleNewIncognitoWindow();
892 case NEXT_IME:
893 return CanHandleNextIme(ime_control_delegate_.get(),
894 previous_accelerator);
895 case PREVIOUS_IME:
896 return CanHandlePreviousIme(ime_control_delegate_.get());
897 case SCALE_UI_RESET:
898 return CanHandleScaleReset();
899 case SCALE_UI_UP:
900 case SCALE_UI_DOWN:
901 return CanHandleScaleUI();
902 case SHOW_MESSAGE_CENTER_BUBBLE:
903 return CanHandleShowMessageCenterBubble();
904 case SWITCH_IME:
905 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
906 case TOGGLE_APP_LIST:
907 return CanHandleToggleAppList(accelerator, previous_accelerator);
908 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
909 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
910 return CanHandleWindowSnapOrDock();
911 case WINDOW_POSITION_CENTER:
912 return CanHandlePositionCenter();
913 #if defined(OS_CHROMEOS)
914 case DEBUG_ADD_REMOVE_DISPLAY:
915 return debug::DebugAcceleratorsEnabled();
916 case DISABLE_CAPS_LOCK:
917 return CanHandleDisableCapsLock(previous_accelerator);
918 case SILENCE_SPOKEN_FEEDBACK:
919 return CanHandleSilenceSpokenFeedback();
920 case SWITCH_TO_PREVIOUS_USER:
921 case SWITCH_TO_NEXT_USER:
922 return CanHandleCycleUser();
923 case TOGGLE_CAPS_LOCK:
924 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
925 case TOGGLE_TOUCH_VIEW_TESTING:
926 return CanHandleToggleTouchViewTesting();
927 case TOUCH_HUD_CLEAR:
928 case TOUCH_HUD_MODE_CHANGE:
929 return CanHandleTouchHud();
930 #endif
932 case CYCLE_BACKWARD_MRU:
933 case CYCLE_FORWARD_MRU:
934 case EXIT:
935 case FOCUS_NEXT_PANE:
936 case FOCUS_PREVIOUS_PANE:
937 case FOCUS_SHELF:
938 case LAUNCH_APP_0:
939 case LAUNCH_APP_1:
940 case LAUNCH_APP_2:
941 case LAUNCH_APP_3:
942 case LAUNCH_APP_4:
943 case LAUNCH_APP_5:
944 case LAUNCH_APP_6:
945 case LAUNCH_APP_7:
946 case LAUNCH_LAST_APP:
947 case MEDIA_NEXT_TRACK:
948 case MEDIA_PLAY_PAUSE:
949 case MEDIA_PREV_TRACK:
950 case NEW_TAB:
951 case NEW_WINDOW:
952 case OPEN_FEEDBACK_PAGE:
953 case PRINT_UI_HIERARCHIES:
954 case RESTORE_TAB:
955 case ROTATE_SCREEN:
956 case ROTATE_WINDOW:
957 case SHOW_KEYBOARD_OVERLAY:
958 case SHOW_SYSTEM_TRAY_BUBBLE:
959 case SHOW_TASK_MANAGER:
960 case TAKE_PARTIAL_SCREENSHOT:
961 case TAKE_SCREENSHOT:
962 case TOGGLE_FULLSCREEN:
963 case TOGGLE_MAXIMIZED:
964 case TOGGLE_OVERVIEW:
965 case WINDOW_MINIMIZE:
966 #if defined(OS_CHROMEOS)
967 case BRIGHTNESS_DOWN:
968 case BRIGHTNESS_UP:
969 case DISABLE_GPU_WATCHDOG:
970 case KEYBOARD_BRIGHTNESS_DOWN:
971 case KEYBOARD_BRIGHTNESS_UP:
972 case LOCK_PRESSED:
973 case LOCK_RELEASED:
974 case LOCK_SCREEN:
975 case OPEN_CROSH:
976 case OPEN_FILE_MANAGER:
977 case POWER_PRESSED:
978 case POWER_RELEASED:
979 case SWAP_PRIMARY_DISPLAY:
980 case TOGGLE_MIRROR_MODE:
981 case TOGGLE_SPOKEN_FEEDBACK:
982 case TOGGLE_WIFI:
983 case TOUCH_HUD_PROJECTION_TOGGLE:
984 case VOLUME_DOWN:
985 case VOLUME_MUTE:
986 case VOLUME_UP:
987 #else
988 case DUMMY_FOR_RESERVED:
989 #endif
990 return true;
992 return false;
995 void AcceleratorController::PerformAction(AcceleratorAction action,
996 const ui::Accelerator& accelerator) {
997 AcceleratorProcessingRestriction restriction =
998 GetAcceleratorProcessingRestriction(action);
999 if (restriction != RESTRICTION_NONE)
1000 return;
1002 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
1003 accelerator.IsRepeat()) {
1004 return;
1007 // If your accelerator invokes more than one line of code, please either
1008 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
1009 // below) or pull it into a HandleFoo() function above.
1010 switch (action) {
1011 case ACCESSIBLE_FOCUS_NEXT:
1012 HandleAccessibleFocusCycle(false);
1013 break;
1014 case ACCESSIBLE_FOCUS_PREVIOUS:
1015 HandleAccessibleFocusCycle(true);
1016 break;
1017 case CYCLE_BACKWARD_MRU:
1018 HandleCycleBackwardMRU(accelerator);
1019 break;
1020 case CYCLE_FORWARD_MRU:
1021 HandleCycleForwardMRU(accelerator);
1022 break;
1023 case DEBUG_PRINT_LAYER_HIERARCHY:
1024 case DEBUG_PRINT_VIEW_HIERARCHY:
1025 case DEBUG_PRINT_WINDOW_HIERARCHY:
1026 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
1027 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
1028 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
1029 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
1030 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
1031 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
1032 debug::PerformDebugActionIfEnabled(action);
1033 break;
1034 case EXIT:
1035 // UMA metrics are recorded in the handler.
1036 exit_warning_handler_.HandleAccelerator();
1037 break;
1038 case FOCUS_NEXT_PANE:
1039 HandleRotatePaneFocus(Shell::FORWARD);
1040 break;
1041 case FOCUS_PREVIOUS_PANE:
1042 HandleRotatePaneFocus(Shell::BACKWARD);
1043 break;
1044 case FOCUS_SHELF:
1045 HandleFocusShelf();
1046 break;
1047 case LAUNCH_APP_0:
1048 HandleLaunchAppN(0);
1049 break;
1050 case LAUNCH_APP_1:
1051 HandleLaunchAppN(1);
1052 break;
1053 case LAUNCH_APP_2:
1054 HandleLaunchAppN(2);
1055 break;
1056 case LAUNCH_APP_3:
1057 HandleLaunchAppN(3);
1058 break;
1059 case LAUNCH_APP_4:
1060 HandleLaunchAppN(4);
1061 break;
1062 case LAUNCH_APP_5:
1063 HandleLaunchAppN(5);
1064 break;
1065 case LAUNCH_APP_6:
1066 HandleLaunchAppN(6);
1067 break;
1068 case LAUNCH_APP_7:
1069 HandleLaunchAppN(7);
1070 break;
1071 case LAUNCH_LAST_APP:
1072 HandleLaunchLastApp();
1073 break;
1074 case MAGNIFY_SCREEN_ZOOM_IN:
1075 HandleMagnifyScreen(1);
1076 break;
1077 case MAGNIFY_SCREEN_ZOOM_OUT:
1078 HandleMagnifyScreen(-1);
1079 break;
1080 case MEDIA_NEXT_TRACK:
1081 HandleMediaNextTrack();
1082 break;
1083 case MEDIA_PLAY_PAUSE:
1084 HandleMediaPlayPause();
1085 break;
1086 case MEDIA_PREV_TRACK:
1087 HandleMediaPrevTrack();
1088 break;
1089 case NEW_INCOGNITO_WINDOW:
1090 HandleNewIncognitoWindow();
1091 break;
1092 case NEW_TAB:
1093 HandleNewTab(accelerator);
1094 break;
1095 case NEW_WINDOW:
1096 HandleNewWindow();
1097 break;
1098 case NEXT_IME:
1099 HandleNextIme(ime_control_delegate_.get());
1100 break;
1101 case OPEN_FEEDBACK_PAGE:
1102 HandleOpenFeedbackPage();
1103 break;
1104 case PREVIOUS_IME:
1105 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1106 break;
1107 case PRINT_UI_HIERARCHIES:
1108 debug::PrintUIHierarchies();
1109 break;
1110 case RESTORE_TAB:
1111 HandleRestoreTab();
1112 break;
1113 case ROTATE_SCREEN:
1114 HandleRotateScreen();
1115 break;
1116 case ROTATE_WINDOW:
1117 HandleRotateActiveWindow();
1118 break;
1119 case SCALE_UI_DOWN:
1120 HandleScaleUI(false /* down */);
1121 break;
1122 case SCALE_UI_RESET:
1123 HandleScaleReset();
1124 break;
1125 case SCALE_UI_UP:
1126 HandleScaleUI(true /* up */);
1127 break;
1128 case SHOW_KEYBOARD_OVERLAY:
1129 HandleShowKeyboardOverlay();
1130 break;
1131 case SHOW_MESSAGE_CENTER_BUBBLE:
1132 HandleShowMessageCenterBubble();
1133 break;
1134 case SHOW_SYSTEM_TRAY_BUBBLE:
1135 HandleShowSystemTrayBubble();
1136 break;
1137 case SHOW_TASK_MANAGER:
1138 HandleShowTaskManager();
1139 break;
1140 case SWITCH_IME:
1141 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1142 break;
1143 case TAKE_PARTIAL_SCREENSHOT:
1144 HandleTakePartialScreenshot(screenshot_delegate_.get());
1145 break;
1146 case TAKE_SCREENSHOT:
1147 HandleTakeScreenshot(screenshot_delegate_.get());
1148 break;
1149 case TOGGLE_APP_LIST:
1150 HandleToggleAppList(accelerator);
1151 break;
1152 case TOGGLE_FULLSCREEN:
1153 HandleToggleFullscreen(accelerator);
1154 break;
1155 case TOGGLE_MAXIMIZED:
1156 accelerators::ToggleMaximized();
1157 break;
1158 case TOGGLE_OVERVIEW:
1159 HandleToggleOverview();
1160 break;
1161 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1162 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1163 HandleWindowSnapOrDock(action);
1164 break;
1165 case WINDOW_MINIMIZE:
1166 HandleWindowMinimize();
1167 break;
1168 case WINDOW_POSITION_CENTER:
1169 HandlePositionCenter();
1170 break;
1171 #if defined(OS_CHROMEOS)
1172 case BRIGHTNESS_DOWN:
1173 HandleBrightnessDown(brightness_control_delegate_.get(), accelerator);
1174 break;
1175 case BRIGHTNESS_UP:
1176 HandleBrightnessUp(brightness_control_delegate_.get(), accelerator);
1177 break;
1178 case DEBUG_ADD_REMOVE_DISPLAY:
1179 debug::PerformDebugActionIfEnabled(action);
1180 break;
1181 case DISABLE_CAPS_LOCK:
1182 HandleDisableCapsLock();
1183 break;
1184 case DISABLE_GPU_WATCHDOG:
1185 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
1186 break;
1187 case KEYBOARD_BRIGHTNESS_DOWN:
1188 HandleKeyboardBrightnessDown(keyboard_brightness_control_delegate_.get(),
1189 accelerator);
1190 break;
1191 case KEYBOARD_BRIGHTNESS_UP:
1192 HandleKeyboardBrightnessUp(keyboard_brightness_control_delegate_.get(),
1193 accelerator);
1194 break;
1195 case LOCK_PRESSED:
1196 case LOCK_RELEASED:
1197 Shell::GetInstance()->power_button_controller()->
1198 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1199 break;
1200 case LOCK_SCREEN:
1201 HandleLock();
1202 break;
1203 case OPEN_CROSH:
1204 HandleCrosh();
1205 break;
1206 case OPEN_FILE_MANAGER:
1207 HandleFileManager();
1208 break;
1209 case POWER_PRESSED: // fallthrough
1210 case POWER_RELEASED:
1211 if (!base::SysInfo::IsRunningOnChromeOS()) {
1212 // There is no powerd in linux desktop, so call the
1213 // PowerButtonController here.
1214 Shell::GetInstance()->power_button_controller()->
1215 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1217 // We don't do anything with these at present on the device,
1218 // (power button events are reported to us from powerm via
1219 // D-BUS), but we consume them to prevent them from getting
1220 // passed to apps -- see http://crbug.com/146609.
1221 break;
1222 case SILENCE_SPOKEN_FEEDBACK:
1223 HandleSilenceSpokenFeedback();
1224 break;
1225 case SWAP_PRIMARY_DISPLAY:
1226 HandleSwapPrimaryDisplay();
1227 break;
1228 case SWITCH_TO_NEXT_USER:
1229 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
1230 break;
1231 case SWITCH_TO_PREVIOUS_USER:
1232 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
1233 break;
1234 case TOGGLE_CAPS_LOCK:
1235 HandleToggleCapsLock();
1236 break;
1237 case TOGGLE_MIRROR_MODE:
1238 HandleToggleMirrorMode();
1239 break;
1240 case TOGGLE_SPOKEN_FEEDBACK:
1241 HandleToggleSpokenFeedback();
1242 break;
1243 case TOGGLE_TOUCH_VIEW_TESTING:
1244 HandleToggleTouchViewTesting();
1245 break;
1246 case TOGGLE_WIFI:
1247 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
1248 break;
1249 case TOUCH_HUD_CLEAR:
1250 HandleTouchHudClear();
1251 break;
1252 case TOUCH_HUD_MODE_CHANGE:
1253 HandleTouchHudModeChange();
1254 break;
1255 case TOUCH_HUD_PROJECTION_TOGGLE:
1256 accelerators::ToggleTouchHudProjection();
1257 break;
1258 case VOLUME_DOWN:
1259 HandleVolumeDown(accelerator);
1260 break;
1261 case VOLUME_MUTE:
1262 HandleVolumeMute(accelerator);
1263 break;
1264 case VOLUME_UP:
1265 HandleVolumeUp(accelerator);
1266 break;
1267 #else
1268 case DUMMY_FOR_RESERVED:
1269 NOTREACHED();
1270 break;
1271 #endif
1275 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1276 AcceleratorAction action) {
1277 if (action == NEXT_IME || action == SWITCH_IME) {
1278 // NEXT_IME is bound to Alt-Shift key up event. SWITCH_IME is bound to
1279 // HANKAKU_ZENKAKU, HENKAN, MUHENKAN keys. To be consistent with Windows
1280 // behavior, do not consume the key event here.
1281 return false;
1283 #if defined(OS_CHROMEOS)
1284 if (action == SILENCE_SPOKEN_FEEDBACK)
1285 return false;
1286 #endif
1288 // Adding new exceptions is *STRONGLY* discouraged.
1289 return true;
1292 AcceleratorController::AcceleratorProcessingRestriction
1293 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1294 ash::Shell* shell = ash::Shell::GetInstance();
1295 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1296 actions_allowed_at_login_screen_.find(action) ==
1297 actions_allowed_at_login_screen_.end()) {
1298 return RESTRICTION_PREVENT_PROCESSING;
1300 if (shell->session_state_delegate()->IsScreenLocked() &&
1301 actions_allowed_at_lock_screen_.find(action) ==
1302 actions_allowed_at_lock_screen_.end()) {
1303 return RESTRICTION_PREVENT_PROCESSING;
1305 if (shell->delegate()->IsRunningInForcedAppMode() &&
1306 actions_allowed_in_app_mode_.find(action) ==
1307 actions_allowed_in_app_mode_.end()) {
1308 return RESTRICTION_PREVENT_PROCESSING;
1310 if (shell->IsSystemModalWindowOpen() &&
1311 actions_allowed_at_modal_window_.find(action) ==
1312 actions_allowed_at_modal_window_.end()) {
1313 // Note we prevent the shortcut from propagating so it will not
1314 // be passed to the modal window. This is important for things like
1315 // Alt+Tab that would cause an undesired effect in the modal window by
1316 // cycling through its window elements.
1317 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1319 if (MruWindowTracker::BuildWindowList().empty() &&
1320 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1321 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1322 ui::A11Y_ALERT_WINDOW_NEEDED);
1323 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1325 return RESTRICTION_NONE;
1328 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1329 scoped_ptr<KeyboardBrightnessControlDelegate>
1330 keyboard_brightness_control_delegate) {
1331 keyboard_brightness_control_delegate_ =
1332 keyboard_brightness_control_delegate.Pass();
1335 } // namespace ash