pre_target_accelerator_handler.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2014 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. #include "ash/accelerators/pre_target_accelerator_handler.h"
  5. #include "ash/accelerators/accelerator_controller_impl.h"
  6. #include "ash/shell.h"
  7. #include "ash/wm/window_state.h"
  8. #include "base/containers/contains.h"
  9. #include "base/feature_list.h"
  10. #include "media/base/media_switches.h"
  11. #include "ui/aura/window.h"
  12. #include "ui/base/accelerators/accelerator.h"
  13. #include "ui/events/event.h"
  14. #include "ui/wm/core/window_util.h"
  15. namespace ash {
  16. namespace {
  17. // Returns true if |key_code| is a key usually handled directly by the shell.
  18. bool IsSystemKey(ui::KeyboardCode key_code) {
  19. switch (key_code) {
  20. case ui::VKEY_ASSISTANT:
  21. case ui::VKEY_ZOOM: // Fullscreen button.
  22. case ui::VKEY_MEDIA_LAUNCH_APP1: // Overview button.
  23. case ui::VKEY_BRIGHTNESS_DOWN:
  24. case ui::VKEY_BRIGHTNESS_UP:
  25. case ui::VKEY_KBD_BRIGHTNESS_DOWN:
  26. case ui::VKEY_KBD_BRIGHTNESS_UP:
  27. case ui::VKEY_VOLUME_MUTE:
  28. case ui::VKEY_VOLUME_DOWN:
  29. case ui::VKEY_VOLUME_UP:
  30. case ui::VKEY_POWER:
  31. case ui::VKEY_SLEEP:
  32. case ui::VKEY_PRIVACY_SCREEN_TOGGLE:
  33. case ui::VKEY_SETTINGS:
  34. return true;
  35. case ui::VKEY_MEDIA_NEXT_TRACK:
  36. case ui::VKEY_MEDIA_PAUSE:
  37. case ui::VKEY_MEDIA_PLAY:
  38. case ui::VKEY_MEDIA_PLAY_PAUSE:
  39. case ui::VKEY_MEDIA_PREV_TRACK:
  40. case ui::VKEY_MEDIA_STOP:
  41. case ui::VKEY_OEM_103: // KEYCODE_MEDIA_REWIND
  42. case ui::VKEY_OEM_104: // KEYCODE_MEDIA_FAST_FORWARD
  43. return base::FeatureList::IsEnabled(media::kHardwareMediaKeyHandling);
  44. default:
  45. return false;
  46. }
  47. }
  48. } // namespace
  49. PreTargetAcceleratorHandler::PreTargetAcceleratorHandler() = default;
  50. PreTargetAcceleratorHandler::~PreTargetAcceleratorHandler() = default;
  51. bool PreTargetAcceleratorHandler::ProcessAccelerator(
  52. const ui::KeyEvent& key_event,
  53. const ui::Accelerator& accelerator) {
  54. aura::Window* target = static_cast<aura::Window*>(key_event.target());
  55. // Callers should never supply null.
  56. DCHECK(target);
  57. // Special hardware keys like brightness and volume are handled in
  58. // special way. However, some windows can override this behavior
  59. // (e.g. Chrome v1 apps by default and Chrome v2 apps with
  60. // permission) by setting a window property.
  61. if (IsSystemKey(key_event.key_code()) &&
  62. !CanConsumeSystemKeys(target, key_event)) {
  63. // System keys are always consumed regardless of whether they trigger an
  64. // accelerator to prevent windows from seeing unexpected key up events.
  65. Shell::Get()->accelerator_controller()->Process(accelerator);
  66. return true;
  67. }
  68. if (!ShouldProcessAcceleratorNow(target, key_event, accelerator))
  69. return false;
  70. return Shell::Get()->accelerator_controller()->Process(accelerator);
  71. }
  72. bool PreTargetAcceleratorHandler::CanConsumeSystemKeys(
  73. aura::Window* target,
  74. const ui::KeyEvent& event) {
  75. // Uses the top level window so if the target is a web contents window the
  76. // containing parent window will be checked for the property.
  77. aura::Window* top_level = ::wm::GetToplevelWindow(target);
  78. return top_level && WindowState::Get(top_level)->CanConsumeSystemKeys();
  79. }
  80. bool PreTargetAcceleratorHandler::ShouldProcessAcceleratorNow(
  81. aura::Window* target,
  82. const ui::KeyEvent& event,
  83. const ui::Accelerator& accelerator) {
  84. // Callers should never supply null.
  85. DCHECK(target);
  86. // On ChromeOS, If the accelerator is Search+<key(s)> then it must never be
  87. // intercepted by apps or windows.
  88. if (accelerator.IsCmdDown())
  89. return true;
  90. if (base::Contains(Shell::GetAllRootWindows(), target))
  91. return true;
  92. AcceleratorControllerImpl* accelerator_controller =
  93. Shell::Get()->accelerator_controller();
  94. // Reserved accelerators (such as Power button) always have a priority.
  95. if (accelerator_controller->IsReserved(accelerator))
  96. return true;
  97. // A full screen window has a right to handle all key events including the
  98. // reserved ones.
  99. aura::Window* top_level = ::wm::GetToplevelWindow(target);
  100. if (top_level && WindowState::Get(top_level)->IsFullscreen()) {
  101. // On ChromeOS, fullscreen windows are either browser or apps, which
  102. // send key events to a web content first, then will process keys
  103. // if the web content didn't consume them.
  104. return false;
  105. }
  106. // Handle preferred accelerators (such as ALT-TAB) before sending
  107. // to the target.
  108. return accelerator_controller->IsPreferred(accelerator);
  109. }
  110. } // namespace ash