"Unhooked" the Shortcut guide module from the PT event dispatcher (#2318)

* "Unhooked" the Shortcut guide module from the PT event dispatcher

* Fixup: warning/undefined behavior/terrible bug

* SetWindowsHookEx and UnhookWindowsHookEx now fail silently

* Updated a comment in shortcut_guide.h

* Renamed a method, added an error message
This commit is contained in:
Ivan Stošić 2020-04-30 11:05:18 +02:00 committed by GitHub
parent 2d23952181
commit 2db98715cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 15 deletions

View File

@ -11,6 +11,24 @@ extern "C" IMAGE_DOS_HEADER __ImageBase;
OverlayWindow* instance = nullptr; OverlayWindow* instance = nullptr;
namespace
{
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LowlevelKeyboardEvent event;
if (nCode == HC_ACTION)
{
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
event.wParam = wParam;
if (instance->signal_event(&event) != 0)
{
return 1;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
}
OverlayWindow::OverlayWindow() OverlayWindow::OverlayWindow()
{ {
app_name = GET_RESOURCE_STRING(IDS_SHORTCUT_GUIDE); app_name = GET_RESOURCE_STRING(IDS_SHORTCUT_GUIDE);
@ -24,8 +42,7 @@ const wchar_t* OverlayWindow::get_name()
const wchar_t** OverlayWindow::get_events() const wchar_t** OverlayWindow::get_events()
{ {
static const wchar_t* events[2] = { ll_keyboard, 0 }; return nullptr;
return events;
} }
bool OverlayWindow::get_config(wchar_t* buffer, int* buffer_size) bool OverlayWindow::get_config(wchar_t* buffer, int* buffer_size)
@ -117,6 +134,11 @@ void OverlayWindow::enable()
winkey_popup->set_theme(theme.value); winkey_popup->set_theme(theme.value);
target_state = std::make_unique<TargetState>(pressTime.value); target_state = std::make_unique<TargetState>(pressTime.value);
winkey_popup->initialize(); winkey_popup->initialize();
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!hook_handle)
{
MessageBoxW(NULL, L"Cannot install keyboard listener.", L"PowerToys - Shortcut Guide", MB_OK | MB_ICONERROR);
}
} }
_enabled = true; _enabled = true;
} }
@ -134,6 +156,14 @@ void OverlayWindow::disable(bool trace_event)
target_state->exit(); target_state->exit();
target_state.reset(); target_state.reset();
winkey_popup.reset(); winkey_popup.reset();
if (hook_handle)
{
bool success = UnhookWindowsHookEx(hook_handle);
if (success)
{
hook_handle = nullptr;
}
}
} }
} }
@ -149,22 +179,31 @@ bool OverlayWindow::is_enabled()
intptr_t OverlayWindow::signal_event(const wchar_t* name, intptr_t data) 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; return 0;
} }
intptr_t OverlayWindow::signal_event(LowlevelKeyboardEvent* event)
{
if (!_enabled)
{
return 0;
}
if (event->wParam == WM_KEYDOWN ||
event->wParam == WM_SYSKEYDOWN ||
event->wParam == WM_KEYUP ||
event->wParam == WM_SYSKEYUP)
{
bool suppress = target_state->signal_event(event->lParam->vkCode,
event->wParam == WM_KEYDOWN || event->wParam == WM_SYSKEYDOWN);
return suppress ? 1 : 0;
}
else
{
return 0;
}
}
void OverlayWindow::on_held() void OverlayWindow::on_held()
{ {
auto filter = get_shortcutguide_filtered_window(); auto filter = get_shortcutguide_filtered_window();

View File

@ -22,6 +22,8 @@ public:
virtual void enable() override; virtual void enable() override;
virtual void disable() override; virtual void disable() override;
virtual bool is_enabled() override; virtual bool is_enabled() override;
// PowerToys interface method, not used
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override; virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override;
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
@ -32,6 +34,9 @@ public:
void quick_hide(); void quick_hide();
void was_hidden(); void was_hidden();
// Method called from LowLevelKeyboardProc
intptr_t signal_event(LowlevelKeyboardEvent* event);
virtual void destroy() override; virtual void destroy() override;
private: private:
@ -39,6 +44,7 @@ private:
std::unique_ptr<TargetState> target_state; std::unique_ptr<TargetState> target_state;
std::unique_ptr<D2DOverlayWindow> winkey_popup; std::unique_ptr<D2DOverlayWindow> winkey_popup;
bool _enabled = false; bool _enabled = false;
HHOOK hook_handle;
void init_settings(); void init_settings();
void disable(bool trace_event); void disable(bool trace_event);