FancyZones: subscribe only to handled WinHook events (#2584)

* FancyZones: subscribe only to handled WinHook events

* formatting fix
This commit is contained in:
Andrey Nekrasov
2020-05-01 17:13:52 +03:00
committed by GitHub
parent fd32dad7eb
commit 9bde15d4ac

View File

@@ -50,7 +50,7 @@ public:
// Return JSON with the configuration options. // Return JSON with the configuration options.
// These are the settings shown on the settings page along with their current values. // These are the settings shown on the settings page along with their current values.
virtual bool get_config(_Out_ PWSTR buffer, _Out_ int *buffer_size) override virtual bool get_config(_Out_ PWSTR buffer, _Out_ int* buffer_size) override
{ {
return m_settings->GetConfig(buffer, buffer_size); return m_settings->GetConfig(buffer, buffer_size);
} }
@@ -83,11 +83,26 @@ public:
MessageBoxW(NULL, L"Cannot install keyboard listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR); MessageBoxW(NULL, L"Cannot install keyboard listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR);
} }
s_winEventHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, nullptr, WinHookProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); std::array<DWORD, 6> events_to_subscribe = {
if (!s_winEventHook) EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND,
EVENT_OBJECT_NAMECHANGE,
EVENT_OBJECT_UNCLOAKED,
EVENT_OBJECT_SHOW,
EVENT_OBJECT_CREATE
};
for (const auto event : events_to_subscribe)
{
auto hook = SetWinEventHook(event, event, nullptr, WinHookProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
if (hook)
{
m_staticWinEventHooks.emplace_back(hook);
}
else
{ {
MessageBoxW(NULL, L"Cannot install Windows event listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR); MessageBoxW(NULL, L"Cannot install Windows event listener.", L"PowerToys - FancyZones", MB_OK | MB_ICONERROR);
} }
}
if (m_app) if (m_app)
{ {
@@ -114,8 +129,8 @@ public:
return 0; return 0;
} }
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override { } virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
virtual void signal_system_menu_action(const wchar_t* name) override { } virtual void signal_system_menu_action(const wchar_t* name) override {}
// Destroy the powertoy and free memory // Destroy the powertoy and free memory
virtual void destroy() override virtual void destroy() override
@@ -135,7 +150,8 @@ public:
private: private:
void Disable(bool const traceEvent) void Disable(bool const traceEvent)
{ {
if (m_app) { if (m_app)
{
if (traceEvent) if (traceEvent)
{ {
Trace::FancyZones::EnableFancyZones(false); Trace::FancyZones::EnableFancyZones(false);
@@ -152,11 +168,17 @@ private:
} }
} }
if (s_winEventHook) m_staticWinEventHooks.erase(std::remove_if(begin(m_staticWinEventHooks),
end(m_staticWinEventHooks),
[](const HWINEVENTHOOK hook) {
return UnhookWinEvent(hook);
}),
end(m_staticWinEventHooks));
if (m_objectLocationWinEventHook)
{ {
if (UnhookWinEvent(s_winEventHook)) if (UnhookWinEvent(m_objectLocationWinEventHook))
{ {
s_winEventHook = nullptr; m_objectLocationWinEventHook = nullptr;
} }
} }
} }
@@ -174,7 +196,9 @@ private:
static inline FancyZonesModule* s_instance; static inline FancyZonesModule* s_instance;
static inline HHOOK s_llKeyboardHook; static inline HHOOK s_llKeyboardHook;
static inline HWINEVENTHOOK s_winEventHook;
std::vector<HWINEVENTHOOK> m_staticWinEventHooks;
HWINEVENTHOOK m_objectLocationWinEventHook;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{ {
@@ -191,8 +215,13 @@ private:
return CallNextHookEx(NULL, nCode, wParam, lParam); return CallNextHookEx(NULL, nCode, wParam, lParam);
} }
static void CALLBACK WinHookProc(HWINEVENTHOOK winEventHook, DWORD event, HWND window, LONG object, static void CALLBACK WinHookProc(HWINEVENTHOOK winEventHook,
LONG child, DWORD eventThread, DWORD eventTime) DWORD event,
HWND window,
LONG object,
LONG child,
DWORD eventThread,
DWORD eventTime)
{ {
WinHookEvent data{ event, window, object, child, eventThread, eventTime }; WinHookEvent data{ event, window, object, child, eventThread, eventTime };
if (s_instance) if (s_instance)
@@ -221,11 +250,25 @@ void FancyZonesModule::HandleWinHookEvent(WinHookEvent* data) noexcept
case EVENT_SYSTEM_MOVESIZESTART: case EVENT_SYSTEM_MOVESIZESTART:
{ {
MoveSizeStart(data->hwnd, ptScreen); MoveSizeStart(data->hwnd, ptScreen);
if (!m_objectLocationWinEventHook)
{
m_objectLocationWinEventHook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE,
EVENT_OBJECT_LOCATIONCHANGE,
nullptr,
WinHookProc,
0,
0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
}
} }
break; break;
case EVENT_SYSTEM_MOVESIZEEND: case EVENT_SYSTEM_MOVESIZEEND:
{ {
if (UnhookWinEvent(m_objectLocationWinEventHook))
{
m_objectLocationWinEventHook = nullptr;
}
MoveSizeEnd(data->hwnd, ptScreen); MoveSizeEnd(data->hwnd, ptScreen);
} }
break; break;