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