1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ash/accelerators/accelerator_controller.h" 6 7 #include <algorithm> 8 #include <cmath> 9 #include <string> 10 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" 73 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) 80 81 namespace ash { 82 namespace { 83 84 using base::UserMetricsAction; 85 86 bool DebugShortcutsEnabled() { 87 #if defined(NDEBUG) 88 return CommandLine::ForCurrentProcess()->HasSwitch( 89 switches::kAshDebugShortcuts); 90 #else 91 return true; 92 #endif 93 } 94 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")); 100 } 101 102 if (!Shell::GetInstance()->accessibility_delegate()-> 103 IsSpokenFeedbackEnabled()) { 104 return false; 105 } 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; 121 122 focus_manager->AdvanceFocus(reverse); 123 return true; 124 } 125 126 bool HandleCycleBackwardMRU(const ui::Accelerator& accelerator) { 127 if (accelerator.key_code() == ui::VKEY_TAB) 128 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab")); 129 130 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow( 131 WindowCycleController::BACKWARD); 132 return true; 133 } 134 135 bool HandleCycleForwardMRU(const ui::Accelerator& accelerator) { 136 if (accelerator.key_code() == ui::VKEY_TAB) 137 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab")); 138 139 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow( 140 WindowCycleController::FORWARD); 141 return true; 142 } 143 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; 148 } 149 150 bool HandleFocusLauncher() { 151 Shell* shell = Shell::GetInstance(); 152 base::RecordAction(base::UserMetricsAction("Accel_Focus_Launcher")); 153 return shell->focus_cycler()->FocusWidget( 154 Shelf::ForPrimaryDisplay()->shelf_widget()); 155 } 156 157 bool HandleLaunchAppN(int n) { 158 base::RecordAction(UserMetricsAction("Accel_Launch_App")); 159 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n); 160 return true; 161 } 162 163 bool HandleLaunchLastApp() { 164 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App")); 165 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1); 166 return true; 167 } 168 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); 178 179 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index)); 180 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); 188 } 189 190 return true; 191 } 192 193 bool HandleMediaNextTrack() { 194 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack(); 195 return true; 196 } 197 198 bool HandleMediaPlayPause() { 199 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause(); 200 return true; 201 } 202 203 bool HandleMediaPrevTrack() { 204 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack(); 205 return true; 206 } 207 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; 216 } 217 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; 223 } 224 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; 230 } 231 232 bool 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 false; 251 } 252 base::RecordAction(UserMetricsAction("Accel_Next_Ime")); 253 if (ime_control_delegate) 254 return ime_control_delegate->HandleNextIme(); 255 return false; 256 } 257 258 bool HandleOpenFeedbackPage() { 259 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page")); 260 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage(); 261 return true; 262 } 263 264 bool HandlePositionCenter() { 265 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center")); 266 aura::Window* window = wm::GetActiveWindow(); 267 // Docked windows do not support centering and ignore accelerator. 268 if (window && !wm::GetWindowState(window)->IsDocked()) { 269 wm::CenterWindow(window); 270 return true; 271 } 272 return false; 273 } 274 275 bool HandlePreviousIme(ImeControlDelegate* ime_control_delegate, 276 const ui::Accelerator& accelerator) { 277 base::RecordAction(UserMetricsAction("Accel_Previous_Ime")); 278 if (ime_control_delegate) 279 return ime_control_delegate->HandlePreviousIme(accelerator); 280 return false; 281 } 282 283 bool HandleRestoreTab() { 284 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab")); 285 Shell::GetInstance()->new_window_delegate()->RestoreTab(); 286 return true; 287 } 288 289 bool HandleRotatePaneFocus(Shell::Direction direction) { 290 Shell* shell = Shell::GetInstance(); 291 switch (direction) { 292 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE. 293 case Shell::FORWARD: { 294 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane")); 295 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD); 296 break; 297 } 298 case Shell::BACKWARD: { 299 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane")); 300 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD); 301 break; 302 } 303 } 304 return true; 305 } 306 307 // Rotate the active window. 308 bool HandleRotateActiveWindow() { 309 base::RecordAction(UserMetricsAction("Accel_Rotate_Window")); 310 aura::Window* active_window = wm::GetActiveWindow(); 311 if (active_window) { 312 // The rotation animation bases its target transform on the current 313 // rotation and position. Since there could be an animation in progress 314 // right now, queue this animation so when it starts it picks up a neutral 315 // rotation and position. Use replace so we only enqueue one at a time. 316 active_window->layer()->GetAnimator()-> 317 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); 318 active_window->layer()->GetAnimator()->StartAnimation( 319 new ui::LayerAnimationSequence( 320 new ash::ScreenRotation(360, active_window->layer()))); 321 } 322 return true; 323 } 324 325 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) { 326 switch (current) { 327 case gfx::Display::ROTATE_0: 328 return gfx::Display::ROTATE_90; 329 case gfx::Display::ROTATE_90: 330 return gfx::Display::ROTATE_180; 331 case gfx::Display::ROTATE_180: 332 return gfx::Display::ROTATE_270; 333 case gfx::Display::ROTATE_270: 334 return gfx::Display::ROTATE_0; 335 } 336 NOTREACHED() << "Unknown rotation:" << current; 337 return gfx::Display::ROTATE_0; 338 } 339 340 // Rotates the screen. 341 bool HandleRotateScreen() { 342 base::RecordAction(UserMetricsAction("Accel_Rotate_Window")); 343 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint(); 344 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point); 345 const DisplayInfo& display_info = 346 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id()); 347 Shell::GetInstance()->display_manager()->SetDisplayRotation( 348 display.id(), GetNextRotation(display_info.rotation())); 349 return true; 350 } 351 352 bool HandleScaleReset() { 353 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 354 int64 display_id = display_manager->GetDisplayIdForUIScaling(); 355 if (display_id == gfx::Display::kInvalidDisplayID) 356 return false; 357 358 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset")); 359 360 display_manager->SetDisplayUIScale(display_id, 1.0f); 361 return true; 362 } 363 364 bool HandleScaleUI(bool up) { 365 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 366 int64 display_id = display_manager->GetDisplayIdForUIScaling(); 367 if (display_id == gfx::Display::kInvalidDisplayID) 368 return false; 369 370 if (up) { 371 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up")); 372 } else { 373 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down")); 374 } 375 376 const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id); 377 float next_scale = DisplayManager::GetNextUIScale(display_info, up); 378 display_manager->SetDisplayUIScale(display_id, next_scale); 379 return true; 380 } 381 382 #if defined(OS_CHROMEOS) 383 bool HandleSwapPrimaryDisplay() { 384 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display")); 385 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay(); 386 return true; 387 } 388 #endif 389 390 bool HandleShowKeyboardOverlay() { 391 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay")); 392 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay(); 393 394 return true; 395 } 396 397 void HandleShowMessageCenterBubble() { 398 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble")); 399 RootWindowController* controller = 400 RootWindowController::ForTargetRootWindow(); 401 StatusAreaWidget* status_area_widget = 402 controller->shelf()->status_area_widget(); 403 if (status_area_widget) { 404 WebNotificationTray* notification_tray = 405 status_area_widget->web_notification_tray(); 406 if (notification_tray->visible()) 407 notification_tray->ShowMessageCenterBubble(); 408 } 409 } 410 411 bool HandleShowSystemTrayBubble() { 412 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble")); 413 RootWindowController* controller = 414 RootWindowController::ForTargetRootWindow(); 415 if (!controller->GetSystemTray()->HasSystemBubble()) { 416 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW); 417 return true; 418 } 419 return false; 420 } 421 422 bool HandleShowTaskManager() { 423 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager")); 424 Shell::GetInstance()->new_window_delegate()->ShowTaskManager(); 425 return true; 426 } 427 428 #if defined(OS_CHROMEOS) 429 void HandleSilenceSpokenFeedback() { 430 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback")); 431 432 AccessibilityDelegate* delegate = 433 Shell::GetInstance()->accessibility_delegate(); 434 if (!delegate->IsSpokenFeedbackEnabled()) 435 return; 436 delegate->SilenceSpokenFeedback(); 437 } 438 #endif 439 440 bool HandleSwitchIme(ImeControlDelegate* ime_control_delegate, 441 const ui::Accelerator& accelerator) { 442 base::RecordAction(UserMetricsAction("Accel_Switch_Ime")); 443 if (ime_control_delegate) 444 return ime_control_delegate->HandleSwitchIme(accelerator); 445 return false; 446 } 447 448 bool HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) { 449 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot")); 450 if (screenshot_delegate) { 451 ash::PartialScreenshotView::StartPartialScreenshot( 452 screenshot_delegate); 453 } 454 // Return true to prevent propagation of the key event because 455 // this key combination is reserved for partial screenshot. 456 return true; 457 } 458 459 bool HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) { 460 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot")); 461 if (screenshot_delegate && 462 screenshot_delegate->CanTakeScreenshot()) { 463 screenshot_delegate->HandleTakeScreenshotForAllRootWindows(); 464 } 465 // Return true to prevent propagation of the key event. 466 return true; 467 } 468 469 bool HandleToggleAppList(ui::KeyboardCode key_code, 470 ui::EventType previous_event_type, 471 ui::KeyboardCode previous_key_code, 472 const ui::Accelerator& accelerator) { 473 // If something else was pressed between the Search key (LWIN) 474 // being pressed and released, then ignore the release of the 475 // Search key. 476 if (key_code == ui::VKEY_LWIN && 477 (previous_event_type == ui::ET_KEY_RELEASED || 478 previous_key_code != ui::VKEY_LWIN)) 479 return false; 480 if (key_code == ui::VKEY_LWIN) 481 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin")); 482 // When spoken feedback is enabled, we should neither toggle the list nor 483 // consume the key since Search+Shift is one of the shortcuts the a11y 484 // feature uses. crbug.com/132296 485 DCHECK_EQ(ui::VKEY_LWIN, accelerator.key_code()); 486 if (Shell::GetInstance()->accessibility_delegate()-> 487 IsSpokenFeedbackEnabled()) 488 return false; 489 ash::Shell::GetInstance()->ToggleAppList(NULL); 490 return true; 491 } 492 493 bool HandleToggleFullscreen(ui::KeyboardCode key_code) { 494 if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) { 495 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4")); 496 } 497 accelerators::ToggleFullscreen(); 498 return true; 499 } 500 501 bool HandleToggleRootWindowFullScreen() { 502 Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen(); 503 return true; 504 } 505 506 bool HandleWindowSnap(int action) { 507 wm::WindowState* window_state = wm::GetActiveWindowState(); 508 // Disable window snapping shortcut key for full screen window due to 509 // http://crbug.com/135487. 510 if (!window_state || 511 window_state->window()->type() != ui::wm::WINDOW_TYPE_NORMAL || 512 window_state->IsFullscreen() || 513 !window_state->CanSnap()) { 514 return false; 515 } 516 517 if (action == WINDOW_SNAP_LEFT) { 518 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left")); 519 } else { 520 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right")); 521 } 522 const wm::WMEvent event(action == WINDOW_SNAP_LEFT ? 523 wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT); 524 window_state->OnWMEvent(&event); 525 return true; 526 } 527 528 bool HandleWindowMinimize() { 529 base::RecordAction( 530 base::UserMetricsAction("Accel_Toggle_Minimized_Minus")); 531 return accelerators::ToggleMinimized(); 532 } 533 534 #if defined(OS_CHROMEOS) 535 bool HandleAddRemoveDisplay() { 536 base::RecordAction(UserMetricsAction("Accel_Add_Remove_Display")); 537 Shell::GetInstance()->display_manager()->AddRemoveDisplay(); 538 return true; 539 } 540 541 bool HandleCrosh() { 542 base::RecordAction(UserMetricsAction("Accel_Open_Crosh")); 543 544 Shell::GetInstance()->new_window_delegate()->OpenCrosh(); 545 return true; 546 } 547 548 bool HandleFileManager() { 549 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager")); 550 551 Shell::GetInstance()->new_window_delegate()->OpenFileManager(); 552 return true; 553 } 554 555 bool HandleLock(ui::KeyboardCode key_code) { 556 base::RecordAction(UserMetricsAction("Accel_LockScreen_L")); 557 Shell::GetInstance()->session_state_delegate()->LockScreen(); 558 return true; 559 } 560 561 bool HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) { 562 if (!Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) 563 return false; 564 ash::SessionStateDelegate* delegate = 565 ash::Shell::GetInstance()->session_state_delegate(); 566 if (delegate->NumberOfLoggedInUsers() <= 1) 567 return false; 568 MultiProfileUMA::RecordSwitchActiveUser( 569 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR); 570 switch (cycle_user) { 571 case SessionStateDelegate::CYCLE_TO_NEXT_USER: 572 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User")); 573 break; 574 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER: 575 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User")); 576 break; 577 } 578 delegate->CycleActiveUser(cycle_user); 579 return true; 580 } 581 582 bool HandleToggleMirrorMode() { 583 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode")); 584 Shell::GetInstance()->display_controller()->ToggleMirrorMode(); 585 return true; 586 } 587 588 bool HandleToggleSpokenFeedback() { 589 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback")); 590 591 Shell::GetInstance()->accessibility_delegate()-> 592 ToggleSpokenFeedback(A11Y_NOTIFICATION_SHOW); 593 return true; 594 } 595 596 bool HandleToggleTouchViewTesting() { 597 // TODO(skuhne): This is only temporary! Remove this! 598 if (CommandLine::ForCurrentProcess()->HasSwitch( 599 switches::kAshEnableTouchViewTesting)) { 600 MaximizeModeController* controller = Shell::GetInstance()-> 601 maximize_mode_controller(); 602 controller->EnableMaximizeModeWindowManager( 603 !controller->IsMaximizeModeWindowManagerEnabled()); 604 return true; 605 } 606 return false; 607 } 608 609 bool HandleTouchHudClear() { 610 RootWindowController* controller = 611 RootWindowController::ForTargetRootWindow(); 612 if (controller->touch_hud_debug()) { 613 controller->touch_hud_debug()->Clear(); 614 return true; 615 } 616 return false; 617 } 618 619 bool HandleTouchHudModeChange() { 620 RootWindowController* controller = 621 RootWindowController::ForTargetRootWindow(); 622 if (controller->touch_hud_debug()) { 623 controller->touch_hud_debug()->ChangeToNextMode(); 624 return true; 625 } 626 return false; 627 } 628 629 bool HandleTouchHudProjectToggle() { 630 base::RecordAction(UserMetricsAction("Accel_Touch_Hud_Clear")); 631 bool enabled = Shell::GetInstance()->is_touch_hud_projection_enabled(); 632 Shell::GetInstance()->SetTouchHudProjectionEnabled(!enabled); 633 return true; 634 } 635 636 bool HandleDisableCapsLock(ui::KeyboardCode key_code, 637 ui::EventType previous_event_type, 638 ui::KeyboardCode previous_key_code) { 639 if (previous_event_type == ui::ET_KEY_RELEASED || 640 (previous_key_code != ui::VKEY_LSHIFT && 641 previous_key_code != ui::VKEY_SHIFT && 642 previous_key_code != ui::VKEY_RSHIFT)) { 643 // If something else was pressed between the Shift key being pressed 644 // and released, then ignore the release of the Shift key. 645 return false; 646 } 647 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock")); 648 chromeos::input_method::InputMethodManager* ime = 649 chromeos::input_method::InputMethodManager::Get(); 650 chromeos::input_method::ImeKeyboard* keyboard = 651 ime ? ime->GetImeKeyboard() : NULL; 652 if (keyboard && keyboard->CapsLockIsEnabled()) { 653 keyboard->SetCapsLockEnabled(false); 654 return true; 655 } 656 return false; 657 } 658 659 bool HandleToggleCapsLock(ui::KeyboardCode key_code, 660 ui::EventType previous_event_type, 661 ui::KeyboardCode previous_key_code) { 662 if (key_code == ui::VKEY_LWIN) { 663 // If something else was pressed between the Search key (LWIN) 664 // being pressed and released, then ignore the release of the 665 // Search key. 666 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495 667 if (previous_event_type == ui::ET_KEY_RELEASED || 668 previous_key_code != ui::VKEY_LWIN) 669 return false; 670 } 671 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock")); 672 chromeos::input_method::InputMethodManager* ime = 673 chromeos::input_method::InputMethodManager::Get(); 674 chromeos::input_method::ImeKeyboard* keyboard = 675 ime ? ime->GetImeKeyboard() : NULL; 676 if (keyboard) 677 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled()); 678 return true; 679 } 680 681 #endif // defined(OS_CHROMEOS) 682 683 // Debug print methods. 684 685 bool HandlePrintLayerHierarchy() { 686 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 687 for (size_t i = 0; i < root_windows.size(); ++i) { 688 ui::PrintLayerHierarchy( 689 root_windows[i]->layer(), 690 root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot()); 691 } 692 return true; 693 } 694 695 bool HandlePrintViewHierarchy() { 696 aura::Window* active_window = ash::wm::GetActiveWindow(); 697 if (!active_window) 698 return true; 699 views::Widget* browser_widget = 700 views::Widget::GetWidgetForNativeWindow(active_window); 701 if (!browser_widget) 702 return true; 703 views::PrintViewHierarchy(browser_widget->GetRootView()); 704 return true; 705 } 706 707 void PrintWindowHierarchy(aura::Window* window, 708 int indent, 709 std::ostringstream* out) { 710 std::string indent_str(indent, ' '); 711 std::string name(window->name()); 712 if (name.empty()) 713 name = "\"\""; 714 *out << indent_str << name << " (" << window << ")" 715 << " type=" << window->type() 716 << (wm::IsActiveWindow(window) ? " [active] " : " ") 717 << (window->IsVisible() ? " visible " : " ") 718 << window->bounds().ToString() 719 << '\n'; 720 721 for (size_t i = 0; i < window->children().size(); ++i) 722 PrintWindowHierarchy(window->children()[i], indent + 3, out); 723 } 724 725 bool HandlePrintWindowHierarchy() { 726 Shell::RootWindowControllerList controllers = 727 Shell::GetAllRootWindowControllers(); 728 for (size_t i = 0; i < controllers.size(); ++i) { 729 std::ostringstream out; 730 out << "RootWindow " << i << ":\n"; 731 PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out); 732 // Error so logs can be collected from end-users. 733 LOG(ERROR) << out.str(); 734 } 735 return true; 736 } 737 738 bool HandlePrintUIHierarchies() { 739 // This is a separate command so the user only has to hit one key to generate 740 // all the logs. Developers use the individual dumps repeatedly, so keep 741 // those as separate commands to avoid spamming their logs. 742 HandlePrintLayerHierarchy(); 743 HandlePrintWindowHierarchy(); 744 HandlePrintViewHierarchy(); 745 return true; 746 } 747 748 class AutoSet { 749 public: 750 AutoSet(ui::Accelerator* scoped, ui::Accelerator new_value) 751 : scoped_(scoped), new_value_(new_value) {} 752 ~AutoSet() { *scoped_ = new_value_; } 753 754 private: 755 ui::Accelerator* scoped_; 756 const ui::Accelerator new_value_; 757 758 DISALLOW_COPY_AND_ASSIGN(AutoSet); 759 }; 760 761 } // namespace 762 763 //////////////////////////////////////////////////////////////////////////////// 764 // AcceleratorController, public: 765 766 AcceleratorController::AcceleratorController() 767 : accelerator_manager_(new ui::AcceleratorManager) { 768 Init(); 769 } 770 771 AcceleratorController::~AcceleratorController() { 772 } 773 774 void AcceleratorController::Init() { 775 previous_accelerator_.set_type(ui::ET_UNKNOWN); 776 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) { 777 actions_allowed_at_login_screen_.insert( 778 kActionsAllowedAtLoginOrLockScreen[i]); 779 actions_allowed_at_lock_screen_.insert( 780 kActionsAllowedAtLoginOrLockScreen[i]); 781 } 782 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i) 783 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]); 784 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i) 785 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]); 786 for (size_t i = 0; i < kReservedActionsLength; ++i) 787 reserved_actions_.insert(kReservedActions[i]); 788 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i) 789 nonrepeatable_actions_.insert(kNonrepeatableActions[i]); 790 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i) 791 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]); 792 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) 793 actions_needing_window_.insert(kActionsNeedingWindow[i]); 794 795 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength); 796 797 #if !defined(NDEBUG) 798 RegisterAccelerators(kDesktopAcceleratorData, kDesktopAcceleratorDataLength); 799 #endif 800 801 if (DebugShortcutsEnabled()) { 802 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength); 803 for (size_t i = 0; i < kReservedDebugActionsLength; ++i) 804 reserved_actions_.insert(kReservedDebugActions[i]); 805 } 806 807 #if defined(OS_CHROMEOS) 808 keyboard_brightness_control_delegate_.reset( 809 new KeyboardBrightnessController()); 810 #endif 811 } 812 813 void AcceleratorController::Register(const ui::Accelerator& accelerator, 814 ui::AcceleratorTarget* target) { 815 accelerator_manager_->Register(accelerator, 816 ui::AcceleratorManager::kNormalPriority, 817 target); 818 } 819 820 void AcceleratorController::Unregister(const ui::Accelerator& accelerator, 821 ui::AcceleratorTarget* target) { 822 accelerator_manager_->Unregister(accelerator, target); 823 } 824 825 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) { 826 accelerator_manager_->UnregisterAll(target); 827 } 828 829 bool AcceleratorController::Process(const ui::Accelerator& accelerator) { 830 AutoSet auto_set(&previous_accelerator_, accelerator); 831 832 if (ime_control_delegate_) { 833 return accelerator_manager_->Process( 834 ime_control_delegate_->RemapAccelerator(accelerator)); 835 } 836 return accelerator_manager_->Process(accelerator); 837 } 838 839 bool AcceleratorController::IsRegistered( 840 const ui::Accelerator& accelerator) const { 841 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL; 842 } 843 844 bool AcceleratorController::IsReservedAccelerator( 845 const ui::Accelerator& accelerator) const { 846 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ? 847 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator; 848 849 std::map<ui::Accelerator, int>::const_iterator iter = 850 accelerators_.find(remapped_accelerator); 851 if (iter == accelerators_.end()) 852 return false; // not an accelerator. 853 854 return reserved_actions_.find(iter->second) != reserved_actions_.end(); 855 } 856 857 bool AcceleratorController::PerformAction(int action, 858 const ui::Accelerator& accelerator) { 859 ash::Shell* shell = ash::Shell::GetInstance(); 860 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() && 861 actions_allowed_at_login_screen_.find(action) == 862 actions_allowed_at_login_screen_.end()) { 863 return false; 864 } 865 if (shell->session_state_delegate()->IsScreenLocked() && 866 actions_allowed_at_lock_screen_.find(action) == 867 actions_allowed_at_lock_screen_.end()) { 868 return false; 869 } 870 if (shell->IsSystemModalWindowOpen() && 871 actions_allowed_at_modal_window_.find(action) == 872 actions_allowed_at_modal_window_.end()) { 873 // Note: we return true. This indicates the shortcut is handled 874 // and will not be passed to the modal window. This is important 875 // for things like Alt+Tab that would cause an undesired effect 876 // in the modal window by cycling through its window elements. 877 return true; 878 } 879 if (shell->delegate()->IsRunningInForcedAppMode() && 880 actions_allowed_in_app_mode_.find(action) == 881 actions_allowed_in_app_mode_.end()) { 882 return false; 883 } 884 if (MruWindowTracker::BuildWindowList(false).empty() && 885 actions_needing_window_.find(action) != actions_needing_window_.end()) { 886 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert( 887 A11Y_ALERT_WINDOW_NEEDED); 888 return true; 889 } 890 891 const ui::KeyboardCode key_code = accelerator.key_code(); 892 // PerformAction() is performed from gesture controllers and passes 893 // empty Accelerator() instance as the second argument. Such events 894 // should never be suspended. 895 const bool gesture_event = key_code == ui::VKEY_UNKNOWN; 896 // Ignore accelerators invoked as repeated (while holding a key for a long 897 // time, if their handling is nonrepeatable. 898 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() && 899 accelerator.IsRepeat() && !gesture_event) { 900 return true; 901 } 902 // Type of the previous accelerator. Used by NEXT_IME and DISABLE_CAPS_LOCK. 903 const ui::EventType previous_event_type = previous_accelerator_.type(); 904 const ui::KeyboardCode previous_key_code = previous_accelerator_.key_code(); 905 906 // You *MUST* return true when some action is performed. Otherwise, this 907 // function might be called *twice*, via BrowserView::PreHandleKeyboardEvent 908 // and BrowserView::HandleKeyboardEvent, for a single accelerator press. 909 // 910 // If your accelerator invokes more than one line of code, please either 911 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE 912 // below) or pull it into a HandleFoo() function above. 913 switch (action) { 914 case ACCESSIBLE_FOCUS_NEXT: 915 return HandleAccessibleFocusCycle(false); 916 case ACCESSIBLE_FOCUS_PREVIOUS: 917 return HandleAccessibleFocusCycle(true); 918 case CYCLE_BACKWARD_MRU: 919 return HandleCycleBackwardMRU(accelerator); 920 case CYCLE_FORWARD_MRU: 921 return HandleCycleForwardMRU(accelerator); 922 case TOGGLE_OVERVIEW: 923 return ToggleOverview(accelerator); 924 #if defined(OS_CHROMEOS) 925 case ADD_REMOVE_DISPLAY: 926 return HandleAddRemoveDisplay(); 927 case TOGGLE_MIRROR_MODE: 928 return HandleToggleMirrorMode(); 929 case LOCK_SCREEN: 930 return HandleLock(key_code); 931 case OPEN_FILE_MANAGER: 932 return HandleFileManager(); 933 case OPEN_CROSH: 934 return HandleCrosh(); 935 case SILENCE_SPOKEN_FEEDBACK: 936 HandleSilenceSpokenFeedback(); 937 break; 938 case SWAP_PRIMARY_DISPLAY: 939 return HandleSwapPrimaryDisplay(); 940 case SWITCH_TO_NEXT_USER: 941 return HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER); 942 case SWITCH_TO_PREVIOUS_USER: 943 return HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER); 944 case TOGGLE_SPOKEN_FEEDBACK: 945 return HandleToggleSpokenFeedback(); 946 case TOGGLE_TOUCH_VIEW_TESTING: 947 return HandleToggleTouchViewTesting(); 948 case TOGGLE_WIFI: 949 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi(); 950 return true; 951 case TOUCH_HUD_CLEAR: 952 return HandleTouchHudClear(); 953 case TOUCH_HUD_MODE_CHANGE: 954 return HandleTouchHudModeChange(); 955 case TOUCH_HUD_PROJECTION_TOGGLE: 956 return HandleTouchHudProjectToggle(); 957 case DISABLE_GPU_WATCHDOG: 958 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog(); 959 return true; 960 case DISABLE_CAPS_LOCK: 961 return HandleDisableCapsLock( 962 key_code, previous_event_type, previous_key_code); 963 case TOGGLE_CAPS_LOCK: 964 return HandleToggleCapsLock( 965 key_code, previous_event_type, previous_key_code); 966 #endif // OS_CHROMEOS 967 case OPEN_FEEDBACK_PAGE: 968 return HandleOpenFeedbackPage(); 969 case EXIT: 970 // UMA metrics are recorded in the handler. 971 exit_warning_handler_.HandleAccelerator(); 972 return true; 973 case NEW_INCOGNITO_WINDOW: 974 return HandleNewIncognitoWindow(); 975 case NEW_TAB: 976 return HandleNewTab(key_code); 977 case NEW_WINDOW: 978 return HandleNewWindow(); 979 case RESTORE_TAB: 980 return HandleRestoreTab(); 981 case TAKE_SCREENSHOT: 982 return HandleTakeScreenshot(screenshot_delegate_.get()); 983 case TAKE_PARTIAL_SCREENSHOT: 984 return HandleTakePartialScreenshot(screenshot_delegate_.get()); 985 case TOGGLE_APP_LIST: 986 return HandleToggleAppList( 987 key_code, previous_event_type, previous_key_code, accelerator); 988 case BRIGHTNESS_DOWN: 989 if (brightness_control_delegate_) 990 return brightness_control_delegate_->HandleBrightnessDown(accelerator); 991 break; 992 case BRIGHTNESS_UP: 993 if (brightness_control_delegate_) 994 return brightness_control_delegate_->HandleBrightnessUp(accelerator); 995 break; 996 case KEYBOARD_BRIGHTNESS_DOWN: 997 if (keyboard_brightness_control_delegate_) 998 return keyboard_brightness_control_delegate_-> 999 HandleKeyboardBrightnessDown(accelerator); 1000 break; 1001 case KEYBOARD_BRIGHTNESS_UP: 1002 if (keyboard_brightness_control_delegate_) 1003 return keyboard_brightness_control_delegate_-> 1004 HandleKeyboardBrightnessUp(accelerator); 1005 break; 1006 case VOLUME_MUTE: { 1007 ash::VolumeControlDelegate* volume_delegate = 1008 shell->system_tray_delegate()->GetVolumeControlDelegate(); 1009 return volume_delegate && volume_delegate->HandleVolumeMute(accelerator); 1010 } 1011 case VOLUME_DOWN: { 1012 ash::VolumeControlDelegate* volume_delegate = 1013 shell->system_tray_delegate()->GetVolumeControlDelegate(); 1014 return volume_delegate && volume_delegate->HandleVolumeDown(accelerator); 1015 } 1016 case VOLUME_UP: { 1017 ash::VolumeControlDelegate* volume_delegate = 1018 shell->system_tray_delegate()->GetVolumeControlDelegate(); 1019 return volume_delegate && volume_delegate->HandleVolumeUp(accelerator); 1020 } 1021 case FOCUS_LAUNCHER: 1022 return HandleFocusLauncher(); 1023 case FOCUS_NEXT_PANE: 1024 return HandleRotatePaneFocus(Shell::FORWARD); 1025 case FOCUS_PREVIOUS_PANE: 1026 return HandleRotatePaneFocus(Shell::BACKWARD); 1027 case SHOW_KEYBOARD_OVERLAY: 1028 return HandleShowKeyboardOverlay(); 1029 case SHOW_SYSTEM_TRAY_BUBBLE: 1030 return HandleShowSystemTrayBubble(); 1031 case SHOW_MESSAGE_CENTER_BUBBLE: 1032 HandleShowMessageCenterBubble(); 1033 break; 1034 case SHOW_TASK_MANAGER: 1035 return HandleShowTaskManager(); 1036 case NEXT_IME: 1037 return HandleNextIme( 1038 ime_control_delegate_.get(), previous_event_type, previous_key_code); 1039 case PREVIOUS_IME: 1040 return HandlePreviousIme(ime_control_delegate_.get(), accelerator); 1041 case PRINT_UI_HIERARCHIES: 1042 return HandlePrintUIHierarchies(); 1043 case SWITCH_IME: 1044 return HandleSwitchIme(ime_control_delegate_.get(), accelerator); 1045 case LAUNCH_APP_0: 1046 return HandleLaunchAppN(0); 1047 case LAUNCH_APP_1: 1048 return HandleLaunchAppN(1); 1049 case LAUNCH_APP_2: 1050 return HandleLaunchAppN(2); 1051 case LAUNCH_APP_3: 1052 return HandleLaunchAppN(3); 1053 case LAUNCH_APP_4: 1054 return HandleLaunchAppN(4); 1055 case LAUNCH_APP_5: 1056 return HandleLaunchAppN(5); 1057 case LAUNCH_APP_6: 1058 return HandleLaunchAppN(6); 1059 case LAUNCH_APP_7: 1060 return HandleLaunchAppN(7); 1061 case LAUNCH_LAST_APP: 1062 return HandleLaunchLastApp(); 1063 case WINDOW_SNAP_LEFT: 1064 case WINDOW_SNAP_RIGHT: 1065 return HandleWindowSnap(action); 1066 case WINDOW_MINIMIZE: 1067 return HandleWindowMinimize(); 1068 case TOGGLE_FULLSCREEN: 1069 return HandleToggleFullscreen(key_code); 1070 case TOGGLE_MAXIMIZED: 1071 accelerators::ToggleMaximized(); 1072 return true; 1073 case WINDOW_POSITION_CENTER: 1074 return HandlePositionCenter(); 1075 case SCALE_UI_UP: 1076 return HandleScaleUI(true /* up */); 1077 case SCALE_UI_DOWN: 1078 return HandleScaleUI(false /* down */); 1079 case SCALE_UI_RESET: 1080 return HandleScaleReset(); 1081 case ROTATE_WINDOW: 1082 return HandleRotateActiveWindow(); 1083 case ROTATE_SCREEN: 1084 return HandleRotateScreen(); 1085 case TOGGLE_DESKTOP_BACKGROUND_MODE: 1086 return debug::CycleDesktopBackgroundMode(); 1087 case TOGGLE_ROOT_WINDOW_FULL_SCREEN: 1088 return HandleToggleRootWindowFullScreen(); 1089 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR: 1090 Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor(); 1091 return true; 1092 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: 1093 ash::debug::ToggleShowDebugBorders(); 1094 return true; 1095 case DEBUG_TOGGLE_SHOW_FPS_COUNTER: 1096 ash::debug::ToggleShowFpsCounter(); 1097 return true; 1098 case DEBUG_TOGGLE_SHOW_PAINT_RECTS: 1099 ash::debug::ToggleShowPaintRects(); 1100 return true; 1101 case MAGNIFY_SCREEN_ZOOM_IN: 1102 return HandleMagnifyScreen(1); 1103 case MAGNIFY_SCREEN_ZOOM_OUT: 1104 return HandleMagnifyScreen(-1); 1105 case MEDIA_NEXT_TRACK: 1106 return HandleMediaNextTrack(); 1107 case MEDIA_PLAY_PAUSE: 1108 return HandleMediaPlayPause(); 1109 case MEDIA_PREV_TRACK: 1110 return HandleMediaPrevTrack(); 1111 case POWER_PRESSED: // fallthrough 1112 case POWER_RELEASED: 1113 #if defined(OS_CHROMEOS) 1114 if (!base::SysInfo::IsRunningOnChromeOS()) { 1115 // There is no powerd in linux desktop, so call the 1116 // PowerButtonController here. 1117 Shell::GetInstance()->power_button_controller()-> 1118 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks()); 1119 } 1120 #endif 1121 // We don't do anything with these at present on the device, 1122 // (power button events are reported to us from powerm via 1123 // D-BUS), but we consume them to prevent them from getting 1124 // passed to apps -- see http://crbug.com/146609. 1125 return true; 1126 case LOCK_PRESSED: 1127 case LOCK_RELEASED: 1128 Shell::GetInstance()->power_button_controller()-> 1129 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks()); 1130 return true; 1131 case PRINT_LAYER_HIERARCHY: 1132 return HandlePrintLayerHierarchy(); 1133 case PRINT_VIEW_HIERARCHY: 1134 return HandlePrintViewHierarchy(); 1135 case PRINT_WINDOW_HIERARCHY: 1136 return HandlePrintWindowHierarchy(); 1137 default: 1138 NOTREACHED() << "Unhandled action " << action; 1139 } 1140 return false; 1141 } 1142 1143 void AcceleratorController::SetBrightnessControlDelegate( 1144 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) { 1145 brightness_control_delegate_ = brightness_control_delegate.Pass(); 1146 } 1147 1148 void AcceleratorController::SetImeControlDelegate( 1149 scoped_ptr<ImeControlDelegate> ime_control_delegate) { 1150 ime_control_delegate_ = ime_control_delegate.Pass(); 1151 } 1152 1153 void AcceleratorController::SetScreenshotDelegate( 1154 scoped_ptr<ScreenshotDelegate> screenshot_delegate) { 1155 screenshot_delegate_ = screenshot_delegate.Pass(); 1156 } 1157 1158 //////////////////////////////////////////////////////////////////////////////// 1159 // AcceleratorController, ui::AcceleratorTarget implementation: 1160 1161 bool AcceleratorController::AcceleratorPressed( 1162 const ui::Accelerator& accelerator) { 1163 std::map<ui::Accelerator, int>::const_iterator it = 1164 accelerators_.find(accelerator); 1165 DCHECK(it != accelerators_.end()); 1166 return PerformAction(static_cast<AcceleratorAction>(it->second), accelerator); 1167 } 1168 1169 void AcceleratorController::RegisterAccelerators( 1170 const AcceleratorData accelerators[], 1171 size_t accelerators_length) { 1172 for (size_t i = 0; i < accelerators_length; ++i) { 1173 ui::Accelerator accelerator(accelerators[i].keycode, 1174 accelerators[i].modifiers); 1175 accelerator.set_type(accelerators[i].trigger_on_press ? 1176 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED); 1177 Register(accelerator, this); 1178 accelerators_.insert( 1179 std::make_pair(accelerator, accelerators[i].action)); 1180 } 1181 } 1182 1183 void AcceleratorController::SetKeyboardBrightnessControlDelegate( 1184 scoped_ptr<KeyboardBrightnessControlDelegate> 1185 keyboard_brightness_control_delegate) { 1186 keyboard_brightness_control_delegate_ = 1187 keyboard_brightness_control_delegate.Pass(); 1188 } 1189 1190 bool AcceleratorController::CanHandleAccelerators() const { 1191 return true; 1192 } 1193 1194 } // namespace ash 1195