mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 11:16:51 +02:00
[AOT] Low level keyboard hook (#18643)
* low level keyboard hook for always on top * fix for message loop * fix spellcheck * refactoring and cleanup * spellcheck
This commit is contained in:
committed by
GitHub
parent
2159e2722e
commit
301f26aca1
@@ -9,6 +9,7 @@
|
||||
#include <common/utils/process_path.h>
|
||||
|
||||
#include <WinHookEventIDs.h>
|
||||
#include <interop/shared_constants.h>
|
||||
|
||||
namespace NonLocalizable
|
||||
{
|
||||
@@ -23,9 +24,10 @@ bool isExcluded(HWND window)
|
||||
return find_app_name_in_path(processPath, AlwaysOnTopSettings::settings().excludedApps);
|
||||
}
|
||||
|
||||
AlwaysOnTop::AlwaysOnTop() :
|
||||
AlwaysOnTop::AlwaysOnTop(bool useLLKH) :
|
||||
SettingsObserver({SettingId::FrameEnabled, SettingId::Hotkey, SettingId::ExcludeApps}),
|
||||
m_hinstance(reinterpret_cast<HINSTANCE>(&__ImageBase))
|
||||
m_hinstance(reinterpret_cast<HINSTANCE>(&__ImageBase)),
|
||||
m_useCentralizedLLKH(useLLKH)
|
||||
{
|
||||
s_instance = this;
|
||||
DPIAware::EnableDPIAwarenessForThisProcess();
|
||||
@@ -38,6 +40,8 @@ AlwaysOnTop::AlwaysOnTop() :
|
||||
AlwaysOnTopSettings::instance().LoadSettings();
|
||||
|
||||
RegisterHotkey();
|
||||
RegisterLLKH();
|
||||
|
||||
SubscribeToEvents();
|
||||
StartTrackingTopmostWindows();
|
||||
}
|
||||
@@ -50,6 +54,13 @@ AlwaysOnTop::AlwaysOnTop() :
|
||||
|
||||
AlwaysOnTop::~AlwaysOnTop()
|
||||
{
|
||||
if (m_hPinEvent)
|
||||
{
|
||||
SetEvent(m_hPinEvent);
|
||||
m_thread.join();
|
||||
CloseHandle(m_hPinEvent);
|
||||
}
|
||||
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
@@ -240,10 +251,57 @@ bool AlwaysOnTop::AssignBorder(HWND window)
|
||||
|
||||
void AlwaysOnTop::RegisterHotkey() const
|
||||
{
|
||||
if (m_useCentralizedLLKH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UnregisterHotKey(m_window, static_cast<int>(HotkeyId::Pin));
|
||||
RegisterHotKey(m_window, static_cast<int>(HotkeyId::Pin), AlwaysOnTopSettings::settings().hotkey.get_modifiers(), AlwaysOnTopSettings::settings().hotkey.get_code());
|
||||
}
|
||||
|
||||
void AlwaysOnTop::RegisterLLKH()
|
||||
{
|
||||
if (!m_useCentralizedLLKH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_hPinEvent = CreateEventW(nullptr, false, false, CommonSharedConstants::ALWAYS_ON_TOP_PIN_EVENT);
|
||||
|
||||
if (!m_hPinEvent)
|
||||
{
|
||||
Logger::warn(L"Failed to create pinEvent. {}", get_last_error_or_default(GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
m_thread = std::thread([this]() {
|
||||
MSG msg;
|
||||
while (1)
|
||||
{
|
||||
DWORD dwEvt = MsgWaitForMultipleObjects(1, &m_hPinEvent, false, INFINITE, QS_ALLINPUT);
|
||||
switch (dwEvt)
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (HWND fw{ GetForegroundWindow() })
|
||||
{
|
||||
ProcessCommand(fw);
|
||||
}
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AlwaysOnTop::SubscribeToEvents()
|
||||
{
|
||||
// subscribe to windows events
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
class AlwaysOnTop : public SettingsObserver
|
||||
{
|
||||
public:
|
||||
AlwaysOnTop();
|
||||
AlwaysOnTop(bool useLLKH);
|
||||
~AlwaysOnTop();
|
||||
|
||||
protected:
|
||||
@@ -47,12 +47,16 @@ private:
|
||||
HWND m_window{ nullptr };
|
||||
HINSTANCE m_hinstance;
|
||||
std::map<HWND, std::unique_ptr<WindowBorder>> m_topmostWindows{};
|
||||
HANDLE m_hPinEvent;
|
||||
std::thread m_thread;
|
||||
const bool m_useCentralizedLLKH;
|
||||
|
||||
LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
||||
void HandleWinHookEvent(WinHookEvent* data) noexcept;
|
||||
|
||||
bool InitMainWindow();
|
||||
void RegisterHotkey() const;
|
||||
void RegisterLLKH();
|
||||
void SubscribeToEvents();
|
||||
|
||||
void ProcessCommand(HWND window);
|
||||
|
||||
@@ -52,7 +52,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
||||
|
||||
Trace::RegisterProvider();
|
||||
|
||||
AlwaysOnTop app;
|
||||
AlwaysOnTop app(!pid.empty());
|
||||
|
||||
run_message_loop();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user