accelerator_controller.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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 81namespace ash { 82namespace { 83 84using base::UserMetricsAction; 85 86bool DebugShortcutsEnabled() { 87#if defined(NDEBUG) 88 return CommandLine::ForCurrentProcess()->HasSwitch( 89 switches::kAshDebugShortcuts); 90#else 91 return true; 92#endif 93} 94 95bool 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 126bool 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 135bool 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 144bool 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 150bool 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 157bool HandleLaunchAppN(int n) { 158 base::RecordAction(UserMetricsAction("Accel_Launch_App")); 159 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n); 160 return true; 161} 162 163bool HandleLaunchLastApp() { 164 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App")); 165 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1); 166 return true; 167} 168 169// Magnify the screen 170bool 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 193bool HandleMediaNextTrack() { 194 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack(); 195 return true; 196} 197 198bool HandleMediaPlayPause() { 199 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause(); 200 return true; 201} 202 203bool HandleMediaPrevTrack() { 204 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack(); 205 return true; 206} 207 208bool 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 218bool 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 225bool 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 232bool 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 258bool HandleOpenFeedbackPage() { 259 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page")); 260 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage(); 261 return true; 262} 263 264bool 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 275bool 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 283bool HandleRestoreTab() { 284 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab")); 285 Shell::GetInstance()->new_window_delegate()->RestoreTab(); 286 return true; 287} 288 289bool 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. 308bool 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 325gfx::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. 341bool 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 352bool 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 364bool 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) 383bool HandleSwapPrimaryDisplay() { 384 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display")); 385 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay(); 386 return true; 387} 388#endif 389 390bool HandleShowKeyboardOverlay() { 391 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay")); 392 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay(); 393 394 return true; 395} 396 397void 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 411bool 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 422bool 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) 429void 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 440bool 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 448bool 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 459bool 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 469bool 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 493bool 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 501bool HandleToggleRootWindowFullScreen() { 502 Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen(); 503 return true; 504} 505 506bool 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 528bool HandleWindowMinimize() { 529 base::RecordAction( 530 base::UserMetricsAction("Accel_Toggle_Minimized_Minus")); 531 return accelerators::ToggleMinimized(); 532} 533 534#if defined(OS_CHROMEOS) 535bool HandleAddRemoveDisplay() { 536 base::RecordAction(UserMetricsAction("Accel_Add_Remove_Display")); 537 Shell::GetInstance()->display_manager()->AddRemoveDisplay(); 538 return true; 539} 540 541bool HandleCrosh() { 542 base::RecordAction(UserMetricsAction("Accel_Open_Crosh")); 543 544 Shell::GetInstance()->new_window_delegate()->OpenCrosh(); 545 return true; 546} 547 548bool HandleFileManager() { 549 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager")); 550 551 Shell::GetInstance()->new_window_delegate()->OpenFileManager(); 552 return true; 553} 554 555bool HandleLock(ui::KeyboardCode key_code) { 556 base::RecordAction(UserMetricsAction("Accel_LockScreen_L")); 557 Shell::GetInstance()->session_state_delegate()->LockScreen(); 558 return true; 559} 560 561bool 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 582bool HandleToggleMirrorMode() { 583 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode")); 584 Shell::GetInstance()->display_controller()->ToggleMirrorMode(); 585 return true; 586} 587 588bool 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 596bool 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 609bool 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 619bool 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 629bool 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 636bool 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 659bool 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 685bool 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 695bool 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 707void 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 725bool 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 738bool 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 748class 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 766AcceleratorController::AcceleratorController() 767 : accelerator_manager_(new ui::AcceleratorManager) { 768 Init(); 769} 770 771AcceleratorController::~AcceleratorController() { 772} 773 774void 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 813void AcceleratorController::Register(const ui::Accelerator& accelerator, 814 ui::AcceleratorTarget* target) { 815 accelerator_manager_->Register(accelerator, 816 ui::AcceleratorManager::kNormalPriority, 817 target); 818} 819 820void AcceleratorController::Unregister(const ui::Accelerator& accelerator, 821 ui::AcceleratorTarget* target) { 822 accelerator_manager_->Unregister(accelerator, target); 823} 824 825void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) { 826 accelerator_manager_->UnregisterAll(target); 827} 828 829bool 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 839bool AcceleratorController::IsRegistered( 840 const ui::Accelerator& accelerator) const { 841 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL; 842} 843 844bool 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 857bool 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 1143void AcceleratorController::SetBrightnessControlDelegate( 1144 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) { 1145 brightness_control_delegate_ = brightness_control_delegate.Pass(); 1146} 1147 1148void AcceleratorController::SetImeControlDelegate( 1149 scoped_ptr<ImeControlDelegate> ime_control_delegate) { 1150 ime_control_delegate_ = ime_control_delegate.Pass(); 1151} 1152 1153void AcceleratorController::SetScreenshotDelegate( 1154 scoped_ptr<ScreenshotDelegate> screenshot_delegate) { 1155 screenshot_delegate_ = screenshot_delegate.Pass(); 1156} 1157 1158//////////////////////////////////////////////////////////////////////////////// 1159// AcceleratorController, ui::AcceleratorTarget implementation: 1160 1161bool 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 1169void 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 1183void AcceleratorController::SetKeyboardBrightnessControlDelegate( 1184 scoped_ptr<KeyboardBrightnessControlDelegate> 1185 keyboard_brightness_control_delegate) { 1186 keyboard_brightness_control_delegate_ = 1187 keyboard_brightness_control_delegate.Pass(); 1188} 1189 1190bool AcceleratorController::CanHandleAccelerators() const { 1191 return true; 1192} 1193 1194} // namespace ash 1195