Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / accelerators / accelerator_filter.cc
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_filter.h"
6
7 #include "ash/accelerators/accelerator_controller.h"
8 #include "ash/shell.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"
15
16 namespace ash {
17 namespace {
18
19 const int kModifierFlagMask = (ui::EF_SHIFT_DOWN |
20                                ui::EF_CONTROL_DOWN |
21                                ui::EF_ALT_DOWN);
22
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)
26   switch (key_code) {
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:
36       return true;
37     default:
38       return false;
39   }
40 #endif  // defined(OS_CHROMEOS)
41   return false;
42 }
43
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.
49     return false;
50   aura::Window* top_level = ::wm::GetToplevelWindow(target);
51   return top_level && wm::GetWindowState(top_level)->can_consume_system_keys();
52 }
53
54 // Returns true if the |accelerator| should be processed now, inside Ash's env
55 // event filter.
56 bool ShouldProcessAcceleratorsNow(const ui::Accelerator& accelerator,
57                                   aura::Window* target) {
58   if (!target)
59     return true;
60
61   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
62   if (std::find(root_windows.begin(), root_windows.end(), target) !=
63       root_windows.end())
64     return true;
65
66   // A full screen window should be able to handle all key events including the
67   // reserved ones.
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.
74     return false;
75   }
76
77   if (Shell::GetInstance()->GetAppListTargetVisibility())
78     return true;
79
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(
83       accelerator);
84 }
85
86 }  // namespace
87
88 ////////////////////////////////////////////////////////////////////////////////
89 // AcceleratorFilter, public:
90
91 AcceleratorFilter::AcceleratorFilter() {
92 }
93
94 AcceleratorFilter::~AcceleratorFilter() {
95 }
96
97 ////////////////////////////////////////////////////////////////////////////////
98 // AcceleratorFilter, EventFilter implementation:
99
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)
103     return;
104   if (event->is_char())
105     return;
106
107   ui::Accelerator accelerator(event->key_code(),
108                               event->flags() & kModifierFlagMask);
109   accelerator.set_type(type);
110
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);
116
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();
126     return;
127   }
128   if (!ShouldProcessAcceleratorsNow(accelerator, target))
129     return;
130   if (accelerator_controller->Process(accelerator))
131     event->StopPropagation();
132 }
133
134 }  // namespace ash