Introduce "Preferred" accelerators, which may be processed by fullscreen, but will...
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blob0dc7bbceb54024459f4b597211446c52843e6036
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/accelerator_table.h"
13 #include "ash/accelerators/debug_commands.h"
14 #include "ash/ash_switches.h"
15 #include "ash/debug.h"
16 #include "ash/display/display_controller.h"
17 #include "ash/display/display_manager.h"
18 #include "ash/focus_cycler.h"
19 #include "ash/gpu_support.h"
20 #include "ash/host/ash_window_tree_host.h"
21 #include "ash/ime_control_delegate.h"
22 #include "ash/magnifier/magnification_controller.h"
23 #include "ash/magnifier/partial_magnification_controller.h"
24 #include "ash/media_delegate.h"
25 #include "ash/multi_profile_uma.h"
26 #include "ash/new_window_delegate.h"
27 #include "ash/root_window_controller.h"
28 #include "ash/rotator/screen_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/volume_control_delegate.h"
47 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
48 #include "ash/wm/mru_window_tracker.h"
49 #include "ash/wm/overview/window_selector_controller.h"
50 #include "ash/wm/partial_screenshot_view.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/aura/window_event_dispatcher.h"
61 #include "ui/base/accelerators/accelerator.h"
62 #include "ui/base/accelerators/accelerator_manager.h"
63 #include "ui/compositor/debug_utils.h"
64 #include "ui/compositor/layer.h"
65 #include "ui/compositor/layer_animation_sequence.h"
66 #include "ui/compositor/layer_animator.h"
67 #include "ui/events/event.h"
68 #include "ui/events/keycodes/keyboard_codes.h"
69 #include "ui/gfx/screen.h"
70 #include "ui/views/controls/webview/webview.h"
71 #include "ui/views/debug_utils.h"
72 #include "ui/views/widget/widget.h"
74 #if defined(OS_CHROMEOS)
75 #include "ash/system/chromeos/keyboard_brightness_controller.h"
76 #include "base/sys_info.h"
77 #include "chromeos/ime/ime_keyboard.h"
78 #include "chromeos/ime/input_method_manager.h"
79 #endif // defined(OS_CHROMEOS)
81 namespace ash {
82 namespace {
84 using base::UserMetricsAction;
86 bool DebugShortcutsEnabled() {
87 #if defined(NDEBUG)
88 return CommandLine::ForCurrentProcess()->HasSwitch(
89 switches::kAshDebugShortcuts);
90 #else
91 return true;
92 #endif
95 bool HandleAccessibleFocusCycle(bool reverse) {
96 if (reverse) {
97 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
98 } else {
99 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Next"));
102 if (!Shell::GetInstance()->accessibility_delegate()->
103 IsSpokenFeedbackEnabled()) {
104 return false;
106 aura::Window* active_window = ash::wm::GetActiveWindow();
107 if (!active_window)
108 return false;
109 views::Widget* widget =
110 views::Widget::GetWidgetForNativeWindow(active_window);
111 if (!widget)
112 return false;
113 views::FocusManager* focus_manager = widget->GetFocusManager();
114 if (!focus_manager)
115 return false;
116 views::View* view = focus_manager->GetFocusedView();
117 if (!view)
118 return false;
119 if (!strcmp(view->GetClassName(), views::WebView::kViewClassName))
120 return false;
122 focus_manager->AdvanceFocus(reverse);
123 return true;
126 bool HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
127 if (accelerator.key_code() == ui::VKEY_TAB)
128 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
130 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
131 WindowCycleController::BACKWARD);
132 return true;
135 bool HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
136 if (accelerator.key_code() == ui::VKEY_TAB)
137 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
139 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
140 WindowCycleController::FORWARD);
141 return true;
144 bool ToggleOverview(const ui::Accelerator& accelerator) {
145 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
146 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
147 return true;
150 bool HandleFocusShelf() {
151 Shell* shell = Shell::GetInstance();
152 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
153 return shell->focus_cycler()->FocusWidget(
154 Shelf::ForPrimaryDisplay()->shelf_widget());
157 bool HandleLaunchAppN(int n) {
158 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
159 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
160 return true;
163 bool HandleLaunchLastApp() {
164 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
165 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
166 return true;
169 // Magnify the screen
170 bool HandleMagnifyScreen(int delta_index) {
171 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
172 // TODO(yoshiki): Move the following logic to MagnificationController.
173 float scale =
174 ash::Shell::GetInstance()->magnification_controller()->GetScale();
175 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
176 int scale_index =
177 std::floor(std::log(scale) / std::log(kMagnificationScaleFactor) + 0.5);
179 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
181 ash::Shell::GetInstance()->magnification_controller()->
182 SetScale(std::pow(kMagnificationScaleFactor, new_scale_index), true);
183 } else if (ash::Shell::GetInstance()->
184 partial_magnification_controller()->is_enabled()) {
185 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
186 ash::Shell::GetInstance()->partial_magnification_controller()->
187 SetScale(scale);
190 return true;
193 bool HandleMediaNextTrack() {
194 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
195 return true;
198 bool HandleMediaPlayPause() {
199 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
200 return true;
203 bool HandleMediaPrevTrack() {
204 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
205 return true;
208 bool HandleNewIncognitoWindow() {
209 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
210 bool incognito_allowed =
211 Shell::GetInstance()->delegate()->IsIncognitoAllowed();
212 if (incognito_allowed)
213 Shell::GetInstance()->new_window_delegate()->NewWindow(
214 true /* is_incognito */);
215 return incognito_allowed;
218 bool HandleNewTab(ui::KeyboardCode key_code) {
219 if (key_code == ui::VKEY_T)
220 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
221 Shell::GetInstance()->new_window_delegate()->NewTab();
222 return true;
225 bool HandleNewWindow() {
226 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
227 Shell::GetInstance()->new_window_delegate()->NewWindow(
228 false /* is_incognito */);
229 return true;
232 void HandleNextIme(ImeControlDelegate* ime_control_delegate,
233 ui::EventType previous_event_type,
234 ui::KeyboardCode previous_key_code) {
235 // This check is necessary e.g. not to process the Shift+Alt+
236 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
237 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
238 // is released.
239 if (previous_event_type == ui::ET_KEY_RELEASED &&
240 // Workaround for crbug.com/139556. CJK IME users tend to press
241 // Enter (or Space) and Shift+Alt almost at the same time to commit
242 // an IME string and then switch from the IME to the English layout.
243 // This workaround allows the user to trigger NEXT_IME even if the
244 // user presses Shift+Alt before releasing Enter.
245 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
246 previous_key_code != ui::VKEY_RETURN &&
247 previous_key_code != ui::VKEY_SPACE) {
248 // We totally ignore this accelerator.
249 // TODO(mazda): Fix crbug.com/158217
250 return;
252 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
253 if (ime_control_delegate)
254 ime_control_delegate->HandleNextIme();
257 bool HandleOpenFeedbackPage() {
258 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
259 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
260 return true;
263 bool HandlePositionCenter() {
264 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
265 aura::Window* window = wm::GetActiveWindow();
266 // Docked windows do not support centering and ignore accelerator.
267 if (window && !wm::GetWindowState(window)->IsDocked()) {
268 wm::CenterWindow(window);
269 return true;
271 return false;
274 bool HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
275 const ui::Accelerator& accelerator) {
276 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
277 if (ime_control_delegate)
278 return ime_control_delegate->HandlePreviousIme(accelerator);
279 return false;
282 bool HandleRestoreTab() {
283 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
284 Shell::GetInstance()->new_window_delegate()->RestoreTab();
285 return true;
288 bool HandleRotatePaneFocus(Shell::Direction direction) {
289 Shell* shell = Shell::GetInstance();
290 switch (direction) {
291 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
292 case Shell::FORWARD: {
293 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
294 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
295 break;
297 case Shell::BACKWARD: {
298 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
299 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
300 break;
303 return true;
306 // Rotate the active window.
307 bool HandleRotateActiveWindow() {
308 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
309 aura::Window* active_window = wm::GetActiveWindow();
310 if (active_window) {
311 // The rotation animation bases its target transform on the current
312 // rotation and position. Since there could be an animation in progress
313 // right now, queue this animation so when it starts it picks up a neutral
314 // rotation and position. Use replace so we only enqueue one at a time.
315 active_window->layer()->GetAnimator()->
316 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
317 active_window->layer()->GetAnimator()->StartAnimation(
318 new ui::LayerAnimationSequence(
319 new ash::ScreenRotation(360, active_window->layer())));
321 return true;
324 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
325 switch (current) {
326 case gfx::Display::ROTATE_0:
327 return gfx::Display::ROTATE_90;
328 case gfx::Display::ROTATE_90:
329 return gfx::Display::ROTATE_180;
330 case gfx::Display::ROTATE_180:
331 return gfx::Display::ROTATE_270;
332 case gfx::Display::ROTATE_270:
333 return gfx::Display::ROTATE_0;
335 NOTREACHED() << "Unknown rotation:" << current;
336 return gfx::Display::ROTATE_0;
339 // Rotates the screen.
340 bool HandleRotateScreen() {
341 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
342 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
343 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
344 const DisplayInfo& display_info =
345 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
346 Shell::GetInstance()->display_manager()->SetDisplayRotation(
347 display.id(), GetNextRotation(display_info.rotation()));
348 return true;
351 bool HandleScaleReset() {
352 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
353 int64 display_id = display_manager->GetDisplayIdForUIScaling();
354 if (display_id == gfx::Display::kInvalidDisplayID)
355 return false;
357 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset"));
359 display_manager->SetDisplayUIScale(display_id, 1.0f);
360 return true;
363 bool HandleScaleUI(bool up) {
364 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
365 int64 display_id = display_manager->GetDisplayIdForUIScaling();
366 if (display_id == gfx::Display::kInvalidDisplayID)
367 return false;
369 if (up) {
370 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up"));
371 } else {
372 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down"));
375 const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
376 float next_scale = DisplayManager::GetNextUIScale(display_info, up);
377 display_manager->SetDisplayUIScale(display_id, next_scale);
378 return true;
381 #if defined(OS_CHROMEOS)
382 bool HandleSwapPrimaryDisplay() {
383 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
384 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
385 return true;
387 #endif
389 bool HandleShowKeyboardOverlay() {
390 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
391 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
393 return true;
396 void HandleShowMessageCenterBubble() {
397 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
398 RootWindowController* controller =
399 RootWindowController::ForTargetRootWindow();
400 StatusAreaWidget* status_area_widget =
401 controller->shelf()->status_area_widget();
402 if (status_area_widget) {
403 WebNotificationTray* notification_tray =
404 status_area_widget->web_notification_tray();
405 if (notification_tray->visible())
406 notification_tray->ShowMessageCenterBubble();
410 bool HandleShowSystemTrayBubble() {
411 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
412 RootWindowController* controller =
413 RootWindowController::ForTargetRootWindow();
414 if (!controller->GetSystemTray()->HasSystemBubble()) {
415 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
416 return true;
418 return false;
421 bool HandleShowTaskManager() {
422 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
423 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
424 return true;
427 #if defined(OS_CHROMEOS)
428 void HandleSilenceSpokenFeedback() {
429 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
431 AccessibilityDelegate* delegate =
432 Shell::GetInstance()->accessibility_delegate();
433 if (!delegate->IsSpokenFeedbackEnabled())
434 return;
435 delegate->SilenceSpokenFeedback();
437 #endif
439 bool HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
440 const ui::Accelerator& accelerator) {
441 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
442 if (ime_control_delegate)
443 return ime_control_delegate->HandleSwitchIme(accelerator);
444 return false;
447 bool HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
448 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
449 if (screenshot_delegate) {
450 ash::PartialScreenshotView::StartPartialScreenshot(
451 screenshot_delegate);
453 // Return true to prevent propagation of the key event because
454 // this key combination is reserved for partial screenshot.
455 return true;
458 bool HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
459 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
460 if (screenshot_delegate &&
461 screenshot_delegate->CanTakeScreenshot()) {
462 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
464 // Return true to prevent propagation of the key event.
465 return true;
468 bool HandleToggleAppList(ui::KeyboardCode key_code,
469 ui::EventType previous_event_type,
470 ui::KeyboardCode previous_key_code,
471 const ui::Accelerator& accelerator) {
472 // If something else was pressed between the Search key (LWIN)
473 // being pressed and released, then ignore the release of the
474 // Search key.
475 if (key_code == ui::VKEY_LWIN &&
476 (previous_event_type == ui::ET_KEY_RELEASED ||
477 previous_key_code != ui::VKEY_LWIN))
478 return false;
479 if (key_code == ui::VKEY_LWIN)
480 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
481 // When spoken feedback is enabled, we should neither toggle the list nor
482 // consume the key since Search+Shift is one of the shortcuts the a11y
483 // feature uses. crbug.com/132296
484 DCHECK_EQ(ui::VKEY_LWIN, accelerator.key_code());
485 if (Shell::GetInstance()->accessibility_delegate()->
486 IsSpokenFeedbackEnabled())
487 return false;
488 ash::Shell::GetInstance()->ToggleAppList(NULL);
489 return true;
492 bool HandleToggleFullscreen(ui::KeyboardCode key_code) {
493 if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) {
494 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
496 accelerators::ToggleFullscreen();
497 return true;
500 bool HandleToggleRootWindowFullScreen() {
501 Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen();
502 return true;
505 bool HandleWindowSnap(int action) {
506 wm::WindowState* window_state = wm::GetActiveWindowState();
507 // Disable window snapping shortcut key for full screen window due to
508 // http://crbug.com/135487.
509 if (!window_state ||
510 window_state->window()->type() != ui::wm::WINDOW_TYPE_NORMAL ||
511 window_state->IsFullscreen() ||
512 !window_state->CanSnap()) {
513 return false;
516 if (action == WINDOW_SNAP_LEFT) {
517 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
518 } else {
519 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
521 const wm::WMEvent event(action == WINDOW_SNAP_LEFT ?
522 wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
523 window_state->OnWMEvent(&event);
524 return true;
527 bool HandleWindowMinimize() {
528 base::RecordAction(
529 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
530 return accelerators::ToggleMinimized();
533 #if defined(OS_CHROMEOS)
534 bool HandleAddRemoveDisplay() {
535 base::RecordAction(UserMetricsAction("Accel_Add_Remove_Display"));
536 Shell::GetInstance()->display_manager()->AddRemoveDisplay();
537 return true;
540 bool HandleCrosh() {
541 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
543 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
544 return true;
547 bool HandleFileManager() {
548 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
550 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
551 return true;
554 bool HandleLock(ui::KeyboardCode key_code) {
555 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
556 Shell::GetInstance()->session_state_delegate()->LockScreen();
557 return true;
560 bool HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
561 if (!Shell::GetInstance()->delegate()->IsMultiProfilesEnabled())
562 return false;
563 ash::SessionStateDelegate* delegate =
564 ash::Shell::GetInstance()->session_state_delegate();
565 if (delegate->NumberOfLoggedInUsers() <= 1)
566 return false;
567 MultiProfileUMA::RecordSwitchActiveUser(
568 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
569 switch (cycle_user) {
570 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
571 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
572 break;
573 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
574 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
575 break;
577 delegate->CycleActiveUser(cycle_user);
578 return true;
581 bool HandleToggleMirrorMode() {
582 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
583 Shell::GetInstance()->display_controller()->ToggleMirrorMode();
584 return true;
587 bool HandleToggleSpokenFeedback() {
588 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
590 Shell::GetInstance()->accessibility_delegate()->
591 ToggleSpokenFeedback(A11Y_NOTIFICATION_SHOW);
592 return true;
595 bool HandleToggleTouchViewTesting() {
596 // TODO(skuhne): This is only temporary! Remove this!
597 if (CommandLine::ForCurrentProcess()->HasSwitch(
598 switches::kAshEnableTouchViewTesting)) {
599 MaximizeModeController* controller = Shell::GetInstance()->
600 maximize_mode_controller();
601 controller->EnableMaximizeModeWindowManager(
602 !controller->IsMaximizeModeWindowManagerEnabled());
603 return true;
605 return false;
608 bool HandleTouchHudClear() {
609 RootWindowController* controller =
610 RootWindowController::ForTargetRootWindow();
611 if (controller->touch_hud_debug()) {
612 controller->touch_hud_debug()->Clear();
613 return true;
615 return false;
618 bool HandleTouchHudModeChange() {
619 RootWindowController* controller =
620 RootWindowController::ForTargetRootWindow();
621 if (controller->touch_hud_debug()) {
622 controller->touch_hud_debug()->ChangeToNextMode();
623 return true;
625 return false;
628 bool HandleTouchHudProjectToggle() {
629 base::RecordAction(UserMetricsAction("Accel_Touch_Hud_Clear"));
630 bool enabled = Shell::GetInstance()->is_touch_hud_projection_enabled();
631 Shell::GetInstance()->SetTouchHudProjectionEnabled(!enabled);
632 return true;
635 bool HandleDisableCapsLock(ui::KeyboardCode key_code,
636 ui::EventType previous_event_type,
637 ui::KeyboardCode previous_key_code) {
638 if (previous_event_type == ui::ET_KEY_RELEASED ||
639 (previous_key_code != ui::VKEY_LSHIFT &&
640 previous_key_code != ui::VKEY_SHIFT &&
641 previous_key_code != ui::VKEY_RSHIFT)) {
642 // If something else was pressed between the Shift key being pressed
643 // and released, then ignore the release of the Shift key.
644 return false;
646 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
647 chromeos::input_method::InputMethodManager* ime =
648 chromeos::input_method::InputMethodManager::Get();
649 chromeos::input_method::ImeKeyboard* keyboard =
650 ime ? ime->GetImeKeyboard() : NULL;
651 if (keyboard && keyboard->CapsLockIsEnabled()) {
652 keyboard->SetCapsLockEnabled(false);
653 return true;
655 return false;
658 bool HandleToggleCapsLock(ui::KeyboardCode key_code,
659 ui::EventType previous_event_type,
660 ui::KeyboardCode previous_key_code) {
661 if (key_code == ui::VKEY_LWIN) {
662 // If something else was pressed between the Search key (LWIN)
663 // being pressed and released, then ignore the release of the
664 // Search key.
665 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
666 if (previous_event_type == ui::ET_KEY_RELEASED ||
667 previous_key_code != ui::VKEY_LWIN)
668 return false;
670 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
671 chromeos::input_method::InputMethodManager* ime =
672 chromeos::input_method::InputMethodManager::Get();
673 chromeos::input_method::ImeKeyboard* keyboard =
674 ime ? ime->GetImeKeyboard() : NULL;
675 if (keyboard)
676 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
677 return true;
680 #endif // defined(OS_CHROMEOS)
682 // Debug print methods.
684 bool HandlePrintLayerHierarchy() {
685 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
686 for (size_t i = 0; i < root_windows.size(); ++i) {
687 ui::PrintLayerHierarchy(
688 root_windows[i]->layer(),
689 root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
691 return true;
694 bool HandlePrintViewHierarchy() {
695 aura::Window* active_window = ash::wm::GetActiveWindow();
696 if (!active_window)
697 return true;
698 views::Widget* browser_widget =
699 views::Widget::GetWidgetForNativeWindow(active_window);
700 if (!browser_widget)
701 return true;
702 views::PrintViewHierarchy(browser_widget->GetRootView());
703 return true;
706 void PrintWindowHierarchy(aura::Window* window,
707 int indent,
708 std::ostringstream* out) {
709 std::string indent_str(indent, ' ');
710 std::string name(window->name());
711 if (name.empty())
712 name = "\"\"";
713 *out << indent_str << name << " (" << window << ")"
714 << " type=" << window->type()
715 << (wm::IsActiveWindow(window) ? " [active] " : " ")
716 << (window->IsVisible() ? " visible " : " ")
717 << window->bounds().ToString()
718 << '\n';
720 for (size_t i = 0; i < window->children().size(); ++i)
721 PrintWindowHierarchy(window->children()[i], indent + 3, out);
724 bool HandlePrintWindowHierarchy() {
725 Shell::RootWindowControllerList controllers =
726 Shell::GetAllRootWindowControllers();
727 for (size_t i = 0; i < controllers.size(); ++i) {
728 std::ostringstream out;
729 out << "RootWindow " << i << ":\n";
730 PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out);
731 // Error so logs can be collected from end-users.
732 LOG(ERROR) << out.str();
734 return true;
737 bool HandlePrintUIHierarchies() {
738 // This is a separate command so the user only has to hit one key to generate
739 // all the logs. Developers use the individual dumps repeatedly, so keep
740 // those as separate commands to avoid spamming their logs.
741 HandlePrintLayerHierarchy();
742 HandlePrintWindowHierarchy();
743 HandlePrintViewHierarchy();
744 return true;
747 class AutoSet {
748 public:
749 AutoSet(ui::Accelerator* scoped, ui::Accelerator new_value)
750 : scoped_(scoped), new_value_(new_value) {}
751 ~AutoSet() { *scoped_ = new_value_; }
753 private:
754 ui::Accelerator* scoped_;
755 const ui::Accelerator new_value_;
757 DISALLOW_COPY_AND_ASSIGN(AutoSet);
760 } // namespace
762 ////////////////////////////////////////////////////////////////////////////////
763 // AcceleratorController, public:
765 AcceleratorController::AcceleratorController()
766 : accelerator_manager_(new ui::AcceleratorManager) {
767 Init();
770 AcceleratorController::~AcceleratorController() {
773 void AcceleratorController::Init() {
774 previous_accelerator_.set_type(ui::ET_UNKNOWN);
775 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
776 actions_allowed_at_login_screen_.insert(
777 kActionsAllowedAtLoginOrLockScreen[i]);
778 actions_allowed_at_lock_screen_.insert(
779 kActionsAllowedAtLoginOrLockScreen[i]);
781 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
782 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
783 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
784 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
785 for (size_t i = 0; i < kPreferredActionsLength; ++i)
786 preferred_actions_.insert(kPreferredActions[i]);
787 for (size_t i = 0; i < kReservedActionsLength; ++i)
788 reserved_actions_.insert(kReservedActions[i]);
789 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
790 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
791 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
792 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
793 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
794 actions_needing_window_.insert(kActionsNeedingWindow[i]);
796 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
798 #if !defined(NDEBUG)
799 RegisterAccelerators(kDesktopAcceleratorData, kDesktopAcceleratorDataLength);
800 #endif
802 if (DebugShortcutsEnabled()) {
803 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
804 for (size_t i = 0; i < kReservedDebugActionsLength; ++i)
805 reserved_actions_.insert(kReservedDebugActions[i]);
808 #if defined(OS_CHROMEOS)
809 keyboard_brightness_control_delegate_.reset(
810 new KeyboardBrightnessController());
811 #endif
814 void AcceleratorController::Register(const ui::Accelerator& accelerator,
815 ui::AcceleratorTarget* target) {
816 accelerator_manager_->Register(accelerator,
817 ui::AcceleratorManager::kNormalPriority,
818 target);
821 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
822 ui::AcceleratorTarget* target) {
823 accelerator_manager_->Unregister(accelerator, target);
826 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
827 accelerator_manager_->UnregisterAll(target);
830 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
831 AutoSet auto_set(&previous_accelerator_, accelerator);
833 if (ime_control_delegate_) {
834 return accelerator_manager_->Process(
835 ime_control_delegate_->RemapAccelerator(accelerator));
837 return accelerator_manager_->Process(accelerator);
840 bool AcceleratorController::IsRegistered(
841 const ui::Accelerator& accelerator) const {
842 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
845 bool AcceleratorController::IsPreferred(
846 const ui::Accelerator& accelerator) const {
847 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
848 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
850 std::map<ui::Accelerator, int>::const_iterator iter =
851 accelerators_.find(remapped_accelerator);
852 if (iter == accelerators_.end())
853 return false; // not an accelerator.
855 return preferred_actions_.find(iter->second) != preferred_actions_.end();
858 bool AcceleratorController::IsReserved(
859 const ui::Accelerator& accelerator) const {
860 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
861 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
863 std::map<ui::Accelerator, int>::const_iterator iter =
864 accelerators_.find(remapped_accelerator);
865 if (iter == accelerators_.end())
866 return false; // not an accelerator.
868 return reserved_actions_.find(iter->second) != reserved_actions_.end();
871 bool AcceleratorController::PerformAction(int action,
872 const ui::Accelerator& accelerator) {
873 ash::Shell* shell = ash::Shell::GetInstance();
874 AcceleratorProcessingRestriction restriction =
875 GetAcceleratorProcessingRestriction(action);
876 if (restriction != RESTRICTION_NONE)
877 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
879 const ui::KeyboardCode key_code = accelerator.key_code();
880 // PerformAction() is performed from gesture controllers and passes
881 // empty Accelerator() instance as the second argument. Such events
882 // should never be suspended.
883 const bool gesture_event = key_code == ui::VKEY_UNKNOWN;
884 // Ignore accelerators invoked as repeated (while holding a key for a long
885 // time, if their handling is nonrepeatable.
886 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
887 accelerator.IsRepeat() && !gesture_event) {
888 return true;
890 // Type of the previous accelerator. Used by NEXT_IME and DISABLE_CAPS_LOCK.
891 const ui::EventType previous_event_type = previous_accelerator_.type();
892 const ui::KeyboardCode previous_key_code = previous_accelerator_.key_code();
894 // You *MUST* return true when some action is performed. Otherwise, this
895 // function might be called *twice*, via BrowserView::PreHandleKeyboardEvent
896 // and BrowserView::HandleKeyboardEvent, for a single accelerator press.
898 // If your accelerator invokes more than one line of code, please either
899 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
900 // below) or pull it into a HandleFoo() function above.
901 switch (action) {
902 case ACCESSIBLE_FOCUS_NEXT:
903 return HandleAccessibleFocusCycle(false);
904 case ACCESSIBLE_FOCUS_PREVIOUS:
905 return HandleAccessibleFocusCycle(true);
906 case CYCLE_BACKWARD_MRU:
907 return HandleCycleBackwardMRU(accelerator);
908 case CYCLE_FORWARD_MRU:
909 return HandleCycleForwardMRU(accelerator);
910 case TOGGLE_OVERVIEW:
911 return ToggleOverview(accelerator);
912 #if defined(OS_CHROMEOS)
913 case ADD_REMOVE_DISPLAY:
914 return HandleAddRemoveDisplay();
915 case TOGGLE_MIRROR_MODE:
916 return HandleToggleMirrorMode();
917 case LOCK_SCREEN:
918 return HandleLock(key_code);
919 case OPEN_FILE_MANAGER:
920 return HandleFileManager();
921 case OPEN_CROSH:
922 return HandleCrosh();
923 case SILENCE_SPOKEN_FEEDBACK:
924 HandleSilenceSpokenFeedback();
925 break;
926 case SWAP_PRIMARY_DISPLAY:
927 return HandleSwapPrimaryDisplay();
928 case SWITCH_TO_NEXT_USER:
929 return HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
930 case SWITCH_TO_PREVIOUS_USER:
931 return HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
932 case TOGGLE_SPOKEN_FEEDBACK:
933 return HandleToggleSpokenFeedback();
934 case TOGGLE_TOUCH_VIEW_TESTING:
935 return HandleToggleTouchViewTesting();
936 case TOGGLE_WIFI:
937 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
938 return true;
939 case TOUCH_HUD_CLEAR:
940 return HandleTouchHudClear();
941 case TOUCH_HUD_MODE_CHANGE:
942 return HandleTouchHudModeChange();
943 case TOUCH_HUD_PROJECTION_TOGGLE:
944 return HandleTouchHudProjectToggle();
945 case DISABLE_GPU_WATCHDOG:
946 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
947 return true;
948 case DISABLE_CAPS_LOCK:
949 return HandleDisableCapsLock(
950 key_code, previous_event_type, previous_key_code);
951 case TOGGLE_CAPS_LOCK:
952 return HandleToggleCapsLock(
953 key_code, previous_event_type, previous_key_code);
954 #endif // OS_CHROMEOS
955 case OPEN_FEEDBACK_PAGE:
956 return HandleOpenFeedbackPage();
957 case EXIT:
958 // UMA metrics are recorded in the handler.
959 exit_warning_handler_.HandleAccelerator();
960 return true;
961 case NEW_INCOGNITO_WINDOW:
962 return HandleNewIncognitoWindow();
963 case NEW_TAB:
964 return HandleNewTab(key_code);
965 case NEW_WINDOW:
966 return HandleNewWindow();
967 case RESTORE_TAB:
968 return HandleRestoreTab();
969 case TAKE_SCREENSHOT:
970 return HandleTakeScreenshot(screenshot_delegate_.get());
971 case TAKE_PARTIAL_SCREENSHOT:
972 return HandleTakePartialScreenshot(screenshot_delegate_.get());
973 case TOGGLE_APP_LIST:
974 return HandleToggleAppList(
975 key_code, previous_event_type, previous_key_code, accelerator);
976 case BRIGHTNESS_DOWN:
977 if (brightness_control_delegate_)
978 return brightness_control_delegate_->HandleBrightnessDown(accelerator);
979 break;
980 case BRIGHTNESS_UP:
981 if (brightness_control_delegate_)
982 return brightness_control_delegate_->HandleBrightnessUp(accelerator);
983 break;
984 case KEYBOARD_BRIGHTNESS_DOWN:
985 if (keyboard_brightness_control_delegate_)
986 return keyboard_brightness_control_delegate_->
987 HandleKeyboardBrightnessDown(accelerator);
988 break;
989 case KEYBOARD_BRIGHTNESS_UP:
990 if (keyboard_brightness_control_delegate_)
991 return keyboard_brightness_control_delegate_->
992 HandleKeyboardBrightnessUp(accelerator);
993 break;
994 case VOLUME_MUTE: {
995 ash::VolumeControlDelegate* volume_delegate =
996 shell->system_tray_delegate()->GetVolumeControlDelegate();
997 return volume_delegate && volume_delegate->HandleVolumeMute(accelerator);
999 case VOLUME_DOWN: {
1000 ash::VolumeControlDelegate* volume_delegate =
1001 shell->system_tray_delegate()->GetVolumeControlDelegate();
1002 return volume_delegate && volume_delegate->HandleVolumeDown(accelerator);
1004 case VOLUME_UP: {
1005 ash::VolumeControlDelegate* volume_delegate =
1006 shell->system_tray_delegate()->GetVolumeControlDelegate();
1007 return volume_delegate && volume_delegate->HandleVolumeUp(accelerator);
1009 case FOCUS_SHELF:
1010 return HandleFocusShelf();
1011 case FOCUS_NEXT_PANE:
1012 return HandleRotatePaneFocus(Shell::FORWARD);
1013 case FOCUS_PREVIOUS_PANE:
1014 return HandleRotatePaneFocus(Shell::BACKWARD);
1015 case SHOW_KEYBOARD_OVERLAY:
1016 return HandleShowKeyboardOverlay();
1017 case SHOW_SYSTEM_TRAY_BUBBLE:
1018 return HandleShowSystemTrayBubble();
1019 case SHOW_MESSAGE_CENTER_BUBBLE:
1020 HandleShowMessageCenterBubble();
1021 break;
1022 case SHOW_TASK_MANAGER:
1023 return HandleShowTaskManager();
1024 case NEXT_IME:
1025 HandleNextIme(
1026 ime_control_delegate_.get(), previous_event_type, previous_key_code);
1027 // NEXT_IME is bound to Alt-Shift key up event. To be consistent with
1028 // Windows behavior, do not consume the key event here.
1029 return false;
1030 case PREVIOUS_IME:
1031 return HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1032 case PRINT_UI_HIERARCHIES:
1033 return HandlePrintUIHierarchies();
1034 case SWITCH_IME:
1035 return HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1036 case LAUNCH_APP_0:
1037 return HandleLaunchAppN(0);
1038 case LAUNCH_APP_1:
1039 return HandleLaunchAppN(1);
1040 case LAUNCH_APP_2:
1041 return HandleLaunchAppN(2);
1042 case LAUNCH_APP_3:
1043 return HandleLaunchAppN(3);
1044 case LAUNCH_APP_4:
1045 return HandleLaunchAppN(4);
1046 case LAUNCH_APP_5:
1047 return HandleLaunchAppN(5);
1048 case LAUNCH_APP_6:
1049 return HandleLaunchAppN(6);
1050 case LAUNCH_APP_7:
1051 return HandleLaunchAppN(7);
1052 case LAUNCH_LAST_APP:
1053 return HandleLaunchLastApp();
1054 case WINDOW_SNAP_LEFT:
1055 case WINDOW_SNAP_RIGHT:
1056 return HandleWindowSnap(action);
1057 case WINDOW_MINIMIZE:
1058 return HandleWindowMinimize();
1059 case TOGGLE_FULLSCREEN:
1060 return HandleToggleFullscreen(key_code);
1061 case TOGGLE_MAXIMIZED:
1062 accelerators::ToggleMaximized();
1063 return true;
1064 case WINDOW_POSITION_CENTER:
1065 return HandlePositionCenter();
1066 case SCALE_UI_UP:
1067 return HandleScaleUI(true /* up */);
1068 case SCALE_UI_DOWN:
1069 return HandleScaleUI(false /* down */);
1070 case SCALE_UI_RESET:
1071 return HandleScaleReset();
1072 case ROTATE_WINDOW:
1073 return HandleRotateActiveWindow();
1074 case ROTATE_SCREEN:
1075 return HandleRotateScreen();
1076 case TOGGLE_DESKTOP_BACKGROUND_MODE:
1077 return debug::CycleDesktopBackgroundMode();
1078 case TOGGLE_ROOT_WINDOW_FULL_SCREEN:
1079 return HandleToggleRootWindowFullScreen();
1080 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
1081 Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor();
1082 return true;
1083 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
1084 ash::debug::ToggleShowDebugBorders();
1085 return true;
1086 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
1087 ash::debug::ToggleShowFpsCounter();
1088 return true;
1089 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
1090 ash::debug::ToggleShowPaintRects();
1091 return true;
1092 case MAGNIFY_SCREEN_ZOOM_IN:
1093 return HandleMagnifyScreen(1);
1094 case MAGNIFY_SCREEN_ZOOM_OUT:
1095 return HandleMagnifyScreen(-1);
1096 case MEDIA_NEXT_TRACK:
1097 return HandleMediaNextTrack();
1098 case MEDIA_PLAY_PAUSE:
1099 return HandleMediaPlayPause();
1100 case MEDIA_PREV_TRACK:
1101 return HandleMediaPrevTrack();
1102 case POWER_PRESSED: // fallthrough
1103 case POWER_RELEASED:
1104 #if defined(OS_CHROMEOS)
1105 if (!base::SysInfo::IsRunningOnChromeOS()) {
1106 // There is no powerd in linux desktop, so call the
1107 // PowerButtonController here.
1108 Shell::GetInstance()->power_button_controller()->
1109 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1111 #endif
1112 // We don't do anything with these at present on the device,
1113 // (power button events are reported to us from powerm via
1114 // D-BUS), but we consume them to prevent them from getting
1115 // passed to apps -- see http://crbug.com/146609.
1116 return true;
1117 case LOCK_PRESSED:
1118 case LOCK_RELEASED:
1119 Shell::GetInstance()->power_button_controller()->
1120 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1121 return true;
1122 case PRINT_LAYER_HIERARCHY:
1123 return HandlePrintLayerHierarchy();
1124 case PRINT_VIEW_HIERARCHY:
1125 return HandlePrintViewHierarchy();
1126 case PRINT_WINDOW_HIERARCHY:
1127 return HandlePrintWindowHierarchy();
1128 default:
1129 NOTREACHED() << "Unhandled action " << action;
1131 return false;
1134 AcceleratorController::AcceleratorProcessingRestriction
1135 AcceleratorController::GetCurrentAcceleratorRestriction() {
1136 return GetAcceleratorProcessingRestriction(-1);
1139 AcceleratorController::AcceleratorProcessingRestriction
1140 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1141 ash::Shell* shell = ash::Shell::GetInstance();
1142 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1143 actions_allowed_at_login_screen_.find(action) ==
1144 actions_allowed_at_login_screen_.end()) {
1145 return RESTRICTION_PREVENT_PROCESSING;
1147 if (shell->session_state_delegate()->IsScreenLocked() &&
1148 actions_allowed_at_lock_screen_.find(action) ==
1149 actions_allowed_at_lock_screen_.end()) {
1150 return RESTRICTION_PREVENT_PROCESSING;
1152 if (shell->IsSystemModalWindowOpen() &&
1153 actions_allowed_at_modal_window_.find(action) ==
1154 actions_allowed_at_modal_window_.end()) {
1155 // Note we prevent the shortcut from propagating so it will not
1156 // be passed to the modal window. This is important for things like
1157 // Alt+Tab that would cause an undesired effect in the modal window by
1158 // cycling through its window elements.
1159 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1161 if (shell->delegate()->IsRunningInForcedAppMode() &&
1162 actions_allowed_in_app_mode_.find(action) ==
1163 actions_allowed_in_app_mode_.end()) {
1164 return RESTRICTION_PREVENT_PROCESSING;
1166 if (MruWindowTracker::BuildWindowList(false).empty() &&
1167 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1168 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1169 A11Y_ALERT_WINDOW_NEEDED);
1170 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1172 return RESTRICTION_NONE;
1175 void AcceleratorController::SetBrightnessControlDelegate(
1176 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
1177 brightness_control_delegate_ = brightness_control_delegate.Pass();
1180 void AcceleratorController::SetImeControlDelegate(
1181 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
1182 ime_control_delegate_ = ime_control_delegate.Pass();
1185 void AcceleratorController::SetScreenshotDelegate(
1186 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
1187 screenshot_delegate_ = screenshot_delegate.Pass();
1190 ////////////////////////////////////////////////////////////////////////////////
1191 // AcceleratorController, ui::AcceleratorTarget implementation:
1193 bool AcceleratorController::AcceleratorPressed(
1194 const ui::Accelerator& accelerator) {
1195 std::map<ui::Accelerator, int>::const_iterator it =
1196 accelerators_.find(accelerator);
1197 DCHECK(it != accelerators_.end());
1198 return PerformAction(static_cast<AcceleratorAction>(it->second), accelerator);
1201 void AcceleratorController::RegisterAccelerators(
1202 const AcceleratorData accelerators[],
1203 size_t accelerators_length) {
1204 for (size_t i = 0; i < accelerators_length; ++i) {
1205 ui::Accelerator accelerator(accelerators[i].keycode,
1206 accelerators[i].modifiers);
1207 accelerator.set_type(accelerators[i].trigger_on_press ?
1208 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
1209 Register(accelerator, this);
1210 accelerators_.insert(
1211 std::make_pair(accelerator, accelerators[i].action));
1215 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1216 scoped_ptr<KeyboardBrightnessControlDelegate>
1217 keyboard_brightness_control_delegate) {
1218 keyboard_brightness_control_delegate_ =
1219 keyboard_brightness_control_delegate.Pass();
1222 bool AcceleratorController::CanHandleAccelerators() const {
1223 return true;
1226 } // namespace ash