OLD | NEW |
| (Empty) |
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 | |
5 #include "ash/common/accelerators/accelerator_router.h" | |
6 | |
7 #include "ash/common/accelerators/accelerator_controller.h" | |
8 #include "ash/common/wm/window_state.h" | |
9 #include "ash/common/wm_shell.h" | |
10 #include "ash/common/wm_window.h" | |
11 #include "base/metrics/histogram_macros.h" | |
12 #include "base/stl_util.h" | |
13 #include "ui/base/accelerators/accelerator.h" | |
14 #include "ui/events/event.h" | |
15 | |
16 namespace ash { | |
17 | |
18 namespace { | |
19 | |
20 // Returns true if |key_code| is a key usually handled directly by the shell. | |
21 bool IsSystemKey(ui::KeyboardCode key_code) { | |
22 switch (key_code) { | |
23 case ui::VKEY_MEDIA_LAUNCH_APP2: // Fullscreen button. | |
24 case ui::VKEY_MEDIA_LAUNCH_APP1: // Overview button. | |
25 case ui::VKEY_BRIGHTNESS_DOWN: | |
26 case ui::VKEY_BRIGHTNESS_UP: | |
27 case ui::VKEY_KBD_BRIGHTNESS_DOWN: | |
28 case ui::VKEY_KBD_BRIGHTNESS_UP: | |
29 case ui::VKEY_VOLUME_MUTE: | |
30 case ui::VKEY_VOLUME_DOWN: | |
31 case ui::VKEY_VOLUME_UP: | |
32 case ui::VKEY_POWER: | |
33 return true; | |
34 default: | |
35 return false; | |
36 } | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 AcceleratorRouter::AcceleratorRouter() {} | |
42 | |
43 AcceleratorRouter::~AcceleratorRouter() {} | |
44 | |
45 bool AcceleratorRouter::ProcessAccelerator(WmWindow* target, | |
46 const ui::KeyEvent& key_event, | |
47 const ui::Accelerator& accelerator) { | |
48 // Callers should never supply null. | |
49 DCHECK(target); | |
50 RecordSearchKeyStats(accelerator); | |
51 // Special hardware keys like brightness and volume are handled in | |
52 // special way. However, some windows can override this behavior | |
53 // (e.g. Chrome v1 apps by default and Chrome v2 apps with | |
54 // permission) by setting a window property. | |
55 if (IsSystemKey(key_event.key_code()) && | |
56 !CanConsumeSystemKeys(target, key_event)) { | |
57 // System keys are always consumed regardless of whether they trigger an | |
58 // accelerator to prevent windows from seeing unexpected key up events. | |
59 WmShell::Get()->accelerator_controller()->Process(accelerator); | |
60 return true; | |
61 } | |
62 if (!ShouldProcessAcceleratorNow(target, key_event, accelerator)) | |
63 return false; | |
64 return WmShell::Get()->accelerator_controller()->Process(accelerator); | |
65 } | |
66 | |
67 void AcceleratorRouter::RecordSearchKeyStats( | |
68 const ui::Accelerator& accelerator) { | |
69 if (accelerator.IsCmdDown()) { | |
70 if (search_key_state_ == RELEASED) { | |
71 search_key_state_ = PRESSED; | |
72 search_key_pressed_timestamp_ = base::TimeTicks::Now(); | |
73 } | |
74 | |
75 if (accelerator.key_code() != ui::KeyboardCode::VKEY_COMMAND && | |
76 search_key_state_ == PRESSED) { | |
77 search_key_state_ = RECORDED; | |
78 UMA_HISTOGRAM_TIMES( | |
79 "Keyboard.Shortcuts.CrosSearchKeyDelay", | |
80 base::TimeTicks::Now() - search_key_pressed_timestamp_); | |
81 } | |
82 } else { | |
83 search_key_state_ = RELEASED; | |
84 } | |
85 } | |
86 | |
87 bool AcceleratorRouter::CanConsumeSystemKeys(WmWindow* target, | |
88 const ui::KeyEvent& event) { | |
89 // Uses the top level window so if the target is a web contents window the | |
90 // containing parent window will be checked for the property. | |
91 WmWindow* top_level = target->GetToplevelWindowForFocus(); | |
92 return top_level && top_level->GetWindowState()->can_consume_system_keys(); | |
93 } | |
94 | |
95 bool AcceleratorRouter::ShouldProcessAcceleratorNow( | |
96 WmWindow* target, | |
97 const ui::KeyEvent& event, | |
98 const ui::Accelerator& accelerator) { | |
99 // Callers should never supply null. | |
100 DCHECK(target); | |
101 // On ChromeOS, If the accelerator is Search+<key(s)> then it must never be | |
102 // intercepted by apps or windows. | |
103 if (accelerator.IsCmdDown()) | |
104 return true; | |
105 | |
106 if (base::ContainsValue(WmShell::Get()->GetAllRootWindows(), target)) | |
107 return true; | |
108 | |
109 AcceleratorController* accelerator_controller = | |
110 WmShell::Get()->accelerator_controller(); | |
111 | |
112 // Reserved accelerators (such as Power button) always have a prority. | |
113 if (accelerator_controller->IsReserved(accelerator)) | |
114 return true; | |
115 | |
116 // A full screen window has a right to handle all key events including the | |
117 // reserved ones. | |
118 WmWindow* top_level = target->GetToplevelWindowForFocus(); | |
119 if (top_level && top_level->GetWindowState()->IsFullscreen()) { | |
120 // On ChromeOS, fullscreen windows are either browser or apps, which | |
121 // send key events to a web content first, then will process keys | |
122 // if the web content didn't consume them. | |
123 return false; | |
124 } | |
125 | |
126 // Handle preferred accelerators (such as ALT-TAB) before sending | |
127 // to the target. | |
128 if (accelerator_controller->IsPreferred(accelerator)) | |
129 return true; | |
130 | |
131 return WmShell::Get()->GetAppListTargetVisibility(); | |
132 } | |
133 | |
134 } // namespace ash | |
OLD | NEW |