-
Notifications
You must be signed in to change notification settings - Fork 6.8k
/
Copy pathshortcut_guide.cpp
169 lines (149 loc) · 4.92 KB
/
shortcut_guide.cpp
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "pch.h"
#include "shortcut_guide.h"
#include "target_state.h"
#include "trace.h"
#include <common/settings_objects.h>
extern "C" IMAGE_DOS_HEADER __ImageBase;
OverlayWindow* instance = nullptr;
OverlayWindow::OverlayWindow() {
init_settings();
}
const wchar_t * OverlayWindow::get_name() {
return L"Shortcut Guide";
}
const wchar_t ** OverlayWindow::get_events() {
static const wchar_t* events[2] = { ll_keyboard, 0 };
return events;
}
bool OverlayWindow::get_config(wchar_t* buffer, int *buffer_size) {
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
PowerToysSettings::Settings settings(hinstance, get_name());
settings.set_description(L"Shows a help overlay with Windows shortcuts when the Windows key is pressed.");
settings.set_overview_link(L"https://github.com/microsoft/PowerToys/blob/master/src/modules/shortcut_guide/README.md");
settings.set_icon_key(L"pt-shortcut-guide");
settings.add_int_spinner(
pressTime.name,
pressTime.resourceId,
pressTime.value,
100,
10000,
100
);
settings.add_int_spinner(
overlayOpacity.name,
overlayOpacity.resourceId,
overlayOpacity.value,
0,
100,
1
);
return settings.serialize_to_buffer(buffer, buffer_size);
}
void OverlayWindow::set_config(const wchar_t * config) {
try {
PowerToysSettings::PowerToyValues _values =
PowerToysSettings::PowerToyValues::from_json_string(config);
if (_values.is_int_value(pressTime.name)) {
int press_delay_time = _values.get_int_value(pressTime.name);
pressTime.value = press_delay_time;
if (target_state) {
target_state->set_delay(press_delay_time);
}
}
if (_values.is_int_value(overlayOpacity.name)) {
int overlay_opacity = _values.get_int_value(overlayOpacity.name);
overlayOpacity.value = overlay_opacity;
if (winkey_popup) {
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f);
}
}
_values.save_to_settings_file();
}
catch (std::exception&) {
// Improper JSON.
}
}
void OverlayWindow::enable() {
if (!_enabled) {
winkey_popup = new D2DOverlayWindow();
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value)/100.0f);
target_state = new TargetState(pressTime.value);
winkey_popup->initialize();
desktop = GetDesktopWindow();
shell = GetShellWindow();
}
_enabled = true;
}
void OverlayWindow::disable() {
if (_enabled) {
winkey_popup->hide();
target_state->exit();
delete target_state;
delete winkey_popup;
target_state = nullptr;
winkey_popup = nullptr;
}
_enabled = false;
}
bool OverlayWindow::is_enabled() {
return _enabled;
}
intptr_t OverlayWindow::signal_event(const wchar_t * name, intptr_t data) {
if (_enabled && wcscmp(name, ll_keyboard) == 0) {
auto& event = *(reinterpret_cast<LowlevelKeyboardEvent*>(data));
if (event.wParam == WM_KEYDOWN ||
event.wParam == WM_SYSKEYDOWN ||
event.wParam == WM_KEYUP ||
event.wParam == WM_SYSKEYUP) {
bool supress = target_state->signal_event(event.lParam->vkCode,
event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN);
return supress ? 1 : 0;
}
}
return 0;
}
void OverlayWindow::on_held() {
auto active_window = GetForegroundWindow();
active_window = GetAncestor(active_window, GA_ROOT);
if (active_window == desktop || active_window == shell) {
active_window = nullptr;
}
auto window_styles = active_window ? GetWindowLong(active_window, GWL_STYLE) : 0;
if ((window_styles & WS_CHILD) || (window_styles & WS_DISABLED)) {
active_window = nullptr;
}
char class_name[256] = "";
GetClassNameA(active_window, class_name, 256);
if (strcmp(class_name, "SysListView32") == 0 ||
strcmp(class_name, "WorkerW") == 0 ||
strcmp(class_name, "Shell_TrayWnd") == 0 ||
strcmp(class_name, "Shell_SecondaryTrayWnd") == 0) {
active_window = nullptr;
}
winkey_popup->show(active_window);
}
void OverlayWindow::on_held_press(DWORD vkCode) {
winkey_popup->animate(vkCode);
}
void OverlayWindow::was_hidden() {
target_state->was_hiden();
}
void OverlayWindow::destroy() {
delete this;
instance = nullptr;
}
void OverlayWindow::init_settings() {
try {
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name());
if (settings.is_int_value(pressTime.name)) {
pressTime.value = settings.get_int_value(pressTime.name);
}
if (settings.is_int_value(overlayOpacity.name)) {
overlayOpacity.value = settings.get_int_value(overlayOpacity.name);
}
}
catch (std::exception&) {
// Error while loading from the settings file. Just let default values stay as they are.
}
}