1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/accelerators/accelerator_filter.h"
7 #include "ash/accelerators/accelerator_controller.h"
9 #include "ash/wm/window_state.h"
10 #include "ui/aura/window_event_dispatcher.h"
11 #include "ui/base/accelerators/accelerator.h"
12 #include "ui/base/accelerators/accelerator_manager.h"
13 #include "ui/events/event.h"
14 #include "ui/wm/core/window_util.h"
19 const int kModifierFlagMask = (ui::EF_SHIFT_DOWN |
23 // Returns true if |key_code| is a key usually handled directly by the shell.
24 bool IsSystemKey(ui::KeyboardCode key_code) {
25 #if defined(OS_CHROMEOS)
27 case ui::VKEY_MEDIA_LAUNCH_APP2: // Fullscreen button.
28 case ui::VKEY_MEDIA_LAUNCH_APP1: // Overview button.
29 case ui::VKEY_BRIGHTNESS_DOWN:
30 case ui::VKEY_BRIGHTNESS_UP:
31 case ui::VKEY_KBD_BRIGHTNESS_DOWN:
32 case ui::VKEY_KBD_BRIGHTNESS_UP:
33 case ui::VKEY_VOLUME_MUTE:
34 case ui::VKEY_VOLUME_DOWN:
35 case ui::VKEY_VOLUME_UP:
40 #endif // defined(OS_CHROMEOS)
44 // Returns true if the window should be allowed a chance to handle system keys.
45 // Uses the top level window so if the target is a web contents window the
46 // containing parent window will be checked for the property.
47 bool CanConsumeSystemKeys(aura::Window* target) {
48 if (!target) // Can be NULL in tests.
50 aura::Window* top_level = ::wm::GetToplevelWindow(target);
51 return top_level && wm::GetWindowState(top_level)->can_consume_system_keys();
54 // Returns true if the |accelerator| should be processed now, inside Ash's env
56 bool ShouldProcessAcceleratorsNow(const ui::Accelerator& accelerator,
57 aura::Window* target) {
61 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
62 if (std::find(root_windows.begin(), root_windows.end(), target) !=
66 // A full screen window should be able to handle all key events including the
68 if (wm::GetWindowState(target)->IsFullscreen()) {
69 // TODO(yusukes): On Chrome OS, only browser and flash windows can be full
70 // screen. Launching an app in "open full-screen" mode is not supported yet.
71 // That makes the IsWindowFullscreen() check above almost meaningless
72 // because a browser and flash window do handle Ash accelerators anyway
73 // before they're passed to a page or flash content.
77 if (Shell::GetInstance()->GetAppListTargetVisibility())
80 // Unless |target| is in the full screen state, handle reserved accelerators
81 // such as Alt+Tab now.
82 return Shell::GetInstance()->accelerator_controller()->IsReservedAccelerator(
88 ////////////////////////////////////////////////////////////////////////////////
89 // AcceleratorFilter, public:
91 AcceleratorFilter::AcceleratorFilter() {
94 AcceleratorFilter::~AcceleratorFilter() {
97 ////////////////////////////////////////////////////////////////////////////////
98 // AcceleratorFilter, EventFilter implementation:
100 void AcceleratorFilter::OnKeyEvent(ui::KeyEvent* event) {
101 const ui::EventType type = event->type();
102 if (type != ui::ET_KEY_PRESSED && type != ui::ET_KEY_RELEASED)
104 if (event->is_char())
107 ui::Accelerator accelerator(event->key_code(),
108 event->flags() & kModifierFlagMask);
109 accelerator.set_type(type);
111 // Fill out context object so AcceleratorController will know what
112 // was the previous accelerator or if the current accelerator is repeated.
113 AcceleratorController* accelerator_controller =
114 Shell::GetInstance()->accelerator_controller();
115 accelerator_controller->context()->UpdateContext(accelerator);
117 aura::Window* target = static_cast<aura::Window*>(event->target());
118 // Handle special hardware keys like brightness and volume. However, some
119 // windows can override this behavior (e.g. Chrome v1 apps by default and
120 // Chrome v2 apps with permission) by setting a window property.
121 if (IsSystemKey(event->key_code()) && !CanConsumeSystemKeys(target)) {
122 accelerator_controller->Process(accelerator);
123 // These keys are always consumed regardless of whether they trigger an
124 // accelerator to prevent windows from seeing unexpected key up events.
125 event->StopPropagation();
128 if (!ShouldProcessAcceleratorsNow(accelerator, target))
130 if (accelerator_controller->Process(accelerator))
131 event->StopPropagation();