From 49b56d9b52bdfedd6ad1404bd0b20e884d2b574b Mon Sep 17 00:00:00 2001 From: Andrey Nekrasov Date: Fri, 31 Jul 2020 14:06:13 +0300 Subject: [PATCH] PowerToys interface: remove powertoys events and system_menu_helper functionality (#5323) --- doc/devdocs/modules/interface.md | 106 ------------ doc/devdocs/shared-hooks.md | 85 ---------- src/common/LowlevelKeyboardEvent.h | 9 + src/common/WinHookEvent.h | 14 ++ src/common/common.vcxproj | 2 + src/common/common.vcxproj.filters | 6 + src/common/keyboard_layout_impl.h | 1 - .../colorPicker/ColorPicker/dllmain.cpp | 40 ++--- src/modules/fancyzones/dll/dllmain.cpp | 19 +-- src/modules/fancyzones/lib/FancyZones.cpp | 12 +- src/modules/fancyzones/lib/FancyZones.h | 48 ++++-- src/modules/imageresizer/dll/dllmain.cpp | 18 -- .../interface/lowlevel_keyboard_event_data.h | 45 ----- .../interface/powertoy_module_interface.h | 70 +++----- src/modules/interface/powertoy_system_menu.h | 22 --- src/modules/interface/win_hook_event_data.h | 50 ------ src/modules/keyboardmanager/common/KeyDelay.h | 2 +- .../common/KeyboardManagerState.h | 2 +- .../keyboardmanager/common/Shortcut.cpp | 1 - .../dll/KeyboardEventHandlers.h | 3 +- src/modules/keyboardmanager/dll/dllmain.cpp | 22 --- .../keyboardmanager/test/MockedInput.h | 3 +- .../launcher/Microsoft.Launcher/dllmain.cpp | 43 ----- src/modules/powerrename/dll/dllmain.cpp | 16 -- .../previewpane/powerpreview/powerpreview.cpp | 15 -- .../previewpane/powerpreview/powerpreview.h | 12 +- src/modules/shortcut_guide/shortcut_guide.cpp | 10 -- src/modules/shortcut_guide/shortcut_guide.h | 11 +- src/runner/lowlevel_keyboard_event.cpp | 53 ------ src/runner/lowlevel_keyboard_event.h | 5 - src/runner/main.cpp | 2 - src/runner/powertoy_module.cpp | 13 -- src/runner/powertoy_module.h | 4 - src/runner/powertoys_events.cpp | 105 ------------ src/runner/powertoys_events.h | 29 ---- src/runner/runner.vcxproj | 8 - src/runner/runner.vcxproj.filters | 27 --- src/runner/system_menu_helper.cpp | 160 ------------------ src/runner/system_menu_helper.h | 43 ----- src/runner/win_hook_event.cpp | 90 ---------- src/runner/win_hook_event.h | 6 - .../ModuleTemplate/dllmain.cpp | 47 ----- 42 files changed, 116 insertions(+), 1163 deletions(-) delete mode 100644 doc/devdocs/shared-hooks.md create mode 100644 src/common/LowlevelKeyboardEvent.h create mode 100644 src/common/WinHookEvent.h delete mode 100644 src/modules/interface/lowlevel_keyboard_event_data.h delete mode 100644 src/modules/interface/powertoy_system_menu.h delete mode 100644 src/modules/interface/win_hook_event_data.h delete mode 100644 src/runner/lowlevel_keyboard_event.cpp delete mode 100644 src/runner/lowlevel_keyboard_event.h delete mode 100644 src/runner/powertoys_events.cpp delete mode 100644 src/runner/powertoys_events.h delete mode 100644 src/runner/system_menu_helper.cpp delete mode 100644 src/runner/system_menu_helper.h delete mode 100644 src/runner/win_hook_event.cpp delete mode 100644 src/runner/win_hook_event.h diff --git a/doc/devdocs/modules/interface.md b/doc/devdocs/modules/interface.md index d8928b56dd..44a846cf5c 100644 --- a/doc/devdocs/modules/interface.md +++ b/doc/devdocs/modules/interface.md @@ -11,9 +11,6 @@ public: virtual void enable() = 0; virtual void disable() = 0; virtual bool is_enabled() = 0; - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) = 0; - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) = 0; - virtual void signal_system_menu_action(const wchar_t* name) = 0; virtual void destroy() = 0; }; @@ -28,7 +25,6 @@ The PowerToys runner will, for each PowerToy DLL: On the received object, the runner will call: - [`get_name()`](#get_name) to get the name of the PowerToy, - - [`get_events()`](#get_events) to get the list of the events the PowerToy wants to subscribe to, - [`enable()`](#enable) to initialize the PowerToy. While running, the runner might call the following methods between create_powertoy() @@ -37,9 +33,6 @@ and destroy(): - [`get_config()`](#get_config) to get the available configuration settings, - [`set_config()`](#set_config) to set settings after they have been edited in the Settings editor, - [`call_custom_action()`](#call_custom_action) when the user selects a custom action in the Settings editor, - - [`signal_event()`](#signal_event) to send an event the PowerToy registered to. - - [`register_system_menu_helper()`](#register_system_menu_helper) to pass object, responsible for handling customized system menus, to module. - - [`signal_system_menu_action()`](#signal_system_menu_action) to send an event when action is taken on system menu item. When terminating, the runner will: - call [`disable()`](#disable), @@ -75,18 +68,6 @@ virtual const wchar_t* get_name() Returns the name of the PowerToy, it will be cached by the runner. -## get_events - -```cpp -virtual const wchar_t** get_events() -``` - -Returns a null-terminated table of the names of the events the PowerToy wants to subscribe to. Available events: - * ll_keyboard - * win_hook_event - -A nullptr can be returned to signal that the PowerToy does not want to subscribe to any event. - ## get_config ``` @@ -140,38 +121,6 @@ Disables the PowerToy, should free as much memory as possible. Returns the PowerToy state. -## signal_event - -```cpp - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) = 0; -``` - -Handle event. Only the events the PowerToy subscribed to will be signaled. -The data argument and return value meaning are event-specific: - * ll_keyboard: see [`lowlevel_keyboard_event_data.h`](./lowlevel_keyboard_event_data.h). - * win_hook_event: see [`win_hook_event_data.h`](./win_hook_event_data.h) - -Please note that some of the events are currently being signalled from a separate thread. - -## register_system_menu_helper - -```cpp - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) = 0; -``` - -Register helper class to handle all system menu items related actions. Creation, deletion -and all other actions taken on system menu item will be handled by provided class. -Module will be informed when action is taken on any item created on request of the module. - -## signal_system_menu_action - -```cpp - virtual void signal_system_menu_action(const wchar_t* name) = 0; -``` - -Runner invokes this API when action is taken on item created on request from the module. -Item name is passed as an argument, so that module can distinguish between different menu items. - ## destroy ```cpp @@ -179,62 +128,7 @@ Item name is passed as an argument, so that module can distinguish between diffe ``` Destroy the PowerToy and free all memory. -## Powertoys system menu helper interface - -Interface for helper class responsible for handling all system menu related actions. -```cpp -class PowertoySystemMenuIface { -public: - struct ItemInfo { - std::wstring name{}; - bool enable{ false }; - bool checkBox{ false }; - }; - virtual void SetConfiguration(PowertoyModuleIface* module, const std::vector& config) = 0; - virtual void ProcessSelectedItem(PowertoyModuleIface* module, HWND window, const wchar_t* itemName) = 0; -}; -``` - -## ItemInfo - -```cpp - struct ItemInfo { - std::wstring name{}; - bool enable{ false }; - bool checkBox{ false }; - }; -``` - -Structure containing all relevant information for system menu item: name (and hotkey if available), item -status at creation (enabled/disabled) and whether check box will appear next to item name when action is taken. - -## SetConfiguration - -```cpp - virtual void SetConfiguration(PowertoyModuleIface* module, const std::vector& config) = 0; -``` - -Module should use this interface to inform system menu helper class which custom system menu items to create. - -## ProcessSelectedItem - -```cpp - virtual void ProcessSelectedItem(PowertoyModuleIface* module, HWND window, const wchar_t* itemName) = 0; -``` - -Process action taken on specific system menu item. - # Code organization ### [`powertoy_module_interface.h`](/src/modules/interface/powertoy_module_interface.h) Contains the PowerToys interface definition. - -### [`powertoy_system_menu.h`](/src/modules/interface/powertoy_system_module.h) -Contains the PowerToys system menu helper interface definition. - -### [`lowlevel_keyboard_event_data.h`](/src/modules/interface/lowlevel_keyboard_event_data.h) -Contains the `LowlevelKeyboardEvent` structure that's passed to `signal_event` for `ll_keyboard` events. - -### [`win_hook_event_data.h`](/src/modules/interface/win_hook_event_data.h) -Contains the `WinHookEvent` structure that's passed to `signal_event` for `win_hook_event` events. - diff --git a/doc/devdocs/shared-hooks.md b/doc/devdocs/shared-hooks.md deleted file mode 100644 index cdb103b37f..0000000000 --- a/doc/devdocs/shared-hooks.md +++ /dev/null @@ -1,85 +0,0 @@ -# Shared hooks - -To minimize the performance impact on the machine only `runner` installs global hooks, passing the events to registered callbacks in each PowerToy module. - -When a PowerToy module is loaded, the `runner` calls the [`get_events()`](/src/modules/interface/powertoy_module_interface.h#L40) method to get a NULL-terminated array of NULL-terminated strings with the names of the events that the PowerToy wants to subscribe to. A `const wchar_t*` string is provided for each of the event names. - -Events are signalled by the `runner` calling the [`signal_event(name, data)`](/src/modules/interface/powertoy_module_interface.h#L53) method of the PowerToy module. The `name` parameter contains the NULL-terminated name of the event. The `data` parameter and the method return value are specific for each event. - -Currently supported hooks: - * `"ll_keyboard"` - [Low Level Keyboard Hook](#low-level-keyboard-hook) - * `"win_hook_event"` - [Windows Event Hook](#windows-event-hook) - -## Low Level Keyboard Hook - -This event is signaled whenever the user presses or releases a key on the keyboard. To subscribe to this event, add `"ll_keyboard"` to the table returned by the `get_events()` method. - -The PowerToys runner installs low-level keyboard hook using `SetWindowsHookEx(WH_KEYBOARD_LL, ...)`. See [this MSDN page](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644985(v%3Dvs.85)) for details. - -When a keyboard event is signaled and `ncCode` equals `HC_ACTION`, the `wParam` and `lParam` event parameters are passed to all subscribed clients in the [`LowlevelKeyboardEvent`](/src/modules/interface/lowlevel_keyboard_event_data.h#L38-L41) struct. - -The `intptr_t data` event argument is a pointer to the `LowlevelKeyboardEvent` struct. - -A non-zero return value from any of the subscribed PowerToys will cause the runner hook proc to return 1, thus swallowing the keyboard event. - -Example usage, that makes Windows ignore the L key: - -```c++ -virtual const wchar_t** get_events() override { - static const wchar_t* events[2] = { ll_keyboard, - nullptr }; - return events; -} - -virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override { - if (wcscmp(name, ll_keyboard) == 0) { - auto& event = *(reinterpret_cast(data)); - // The L key has vkCode of 0x4C, see: - // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes - if (event.wParam == WM_KEYDOWN && event.lParam->vkCode == 0x4C) { - return 1; - } else { - return 0; - } - } else { - return 0; - } -} -``` - -## Windows Event Hook - -This event is signaled for [a range of events](https://docs.microsoft.com/pl-pl/windows/win32/winauto/event-constants). To subscribe to this event, add `"win_hook_event"` to the table returned by the `get_events()` method. See [this MSDN doc](https://docs.microsoft.com/pl-pl/windows/win32/api/winuser/nf-winuser-setwineventhook) for details. - -The `intptr_t data` event argument is a pointer to the [`WinHookEvent`](/src/modules/interface/win_hook_event_data.h#L43-L50) struct. - -The return value of the event handler is ignored. - -Example usage, that detects a window being resized: - -```c++ -virtual const wchar_t** get_events() override { - static const wchar_t* events[2] = { win_hook_event, - nullptr }; - return events; -} - -virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override { - if (wcscmp(name, win_hook_event) == 0) { - auto& event = *(reinterpret_cast(data)); - switch (event.event) { - case EVENT_SYSTEM_MOVESIZESTART: - size_start(event.hwnd); - break; - case EVENT_SYSTEM_MOVESIZEEND: - size_end(event.hwnd); - break; - default: - break; - } - } - return 0; -} -``` - -Taking too long to process the events has negative impact on the whole system performance. To address this, the events are signaled from a different thread, not from the event hook callback itself. diff --git a/src/common/LowlevelKeyboardEvent.h b/src/common/LowlevelKeyboardEvent.h new file mode 100644 index 0000000000..ecffc719dd --- /dev/null +++ b/src/common/LowlevelKeyboardEvent.h @@ -0,0 +1,9 @@ +#pragma once +#define WIN32_LEAN_AND_MEAN +#include + +struct LowlevelKeyboardEvent +{ + KBDLLHOOKSTRUCT* lParam; + WPARAM wParam; +}; \ No newline at end of file diff --git a/src/common/WinHookEvent.h b/src/common/WinHookEvent.h new file mode 100644 index 0000000000..ad54bf994f --- /dev/null +++ b/src/common/WinHookEvent.h @@ -0,0 +1,14 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include + +struct WinHookEvent +{ + DWORD event; + HWND hwnd; + LONG idObject; + LONG idChild; + DWORD idEventThread; + DWORD dwmsEventTime; +}; \ No newline at end of file diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 84d6ac912a..d105489885 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -128,6 +128,7 @@ + @@ -153,6 +154,7 @@ + diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index 91427520e7..be998578a0 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters @@ -129,6 +129,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/src/common/keyboard_layout_impl.h b/src/common/keyboard_layout_impl.h index 1138f1f7da..9a1b07f2a8 100644 --- a/src/common/keyboard_layout_impl.h +++ b/src/common/keyboard_layout_impl.h @@ -1,6 +1,5 @@ #pragma once #include "keyboard_layout.h" -#include "..\modules\interface\lowlevel_keyboard_event_data.h" #include #include #include diff --git a/src/modules/colorPicker/ColorPicker/dllmain.cpp b/src/modules/colorPicker/ColorPicker/dllmain.cpp index bcd7e15d81..818837836a 100644 --- a/src/modules/colorPicker/ColorPicker/dllmain.cpp +++ b/src/modules/colorPicker/ColorPicker/dllmain.cpp @@ -9,10 +9,9 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) +BOOL APIENTRY DllMain(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { switch (ul_reason_for_call) { @@ -27,7 +26,8 @@ BOOL APIENTRY DllMain( HMODULE hModule, return TRUE; } -struct ModuleSettings{ +struct ModuleSettings +{ } g_settings; class ColorPicker : public PowertoyModuleIface @@ -39,8 +39,9 @@ private: HANDLE m_hProcess; - // Time to wait for process to close after sending WM_CLOSE signal + // Time to wait for process to close after sending WM_CLOSE signal static const int MAX_WAIT_MILLISEC = 10000; + public: ColorPicker() { @@ -67,13 +68,6 @@ public: return app_name.c_str(); } - virtual const wchar_t** get_events() override - { - static const wchar_t* events[] = { nullptr }; - - return events; - } - virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); @@ -111,8 +105,8 @@ public: } } - virtual void enable(){ - + virtual void enable() + { // use only with new settings? if (UseNewSettings()) { @@ -134,12 +128,13 @@ public: } }; - virtual void disable() { + virtual void disable() + { if (m_enabled) { terminateProcess(); } - + m_enabled = false; } @@ -148,11 +143,6 @@ public: return m_enabled; } - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - return 0; - } - static BOOL CALLBACK requestMainWindowClose(HWND nextWindow, LPARAM closePid) { DWORD windowPid; @@ -174,15 +164,9 @@ public: TerminateProcess(m_hProcess, 1); } } - - /* Register helper class to handle system menu items related actions. */ - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) {} - /* Handle action on system menu item. */ - virtual void signal_system_menu_action(const wchar_t* name) {} }; extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() { return new ColorPicker(); } - diff --git a/src/modules/fancyzones/dll/dllmain.cpp b/src/modules/fancyzones/dll/dllmain.cpp index e755eee703..fd40759faf 100644 --- a/src/modules/fancyzones/dll/dllmain.cpp +++ b/src/modules/fancyzones/dll/dllmain.cpp @@ -2,9 +2,8 @@ #include #include #include +#include #include -#include -#include #include #include @@ -44,13 +43,6 @@ public: return app_name.c_str(); } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty list. - virtual PCWSTR* get_events() override - { - return nullptr; - } - // Return JSON with the configuration options. // 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 @@ -134,15 +126,6 @@ public: return (m_app != nullptr); } - // PowertoyModuleIface method, unused - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - return 0; - } - - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - virtual void signal_system_menu_action(const wchar_t* name) override {} - // Destroy the powertoy and free memory virtual void destroy() override { diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index 3e86ab2800..2c48a60163 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -16,7 +16,6 @@ #include "VirtualDesktopUtils.h" #include "MonitorWorkAreaHandler.h" -#include #include #include @@ -365,7 +364,8 @@ bool FancyZones::ShouldProcessNewWindow(HWND window) noexcept } std::vector FancyZones::GetZoneIndexSetFromWorkAreaHistory( - HWND window, winrt::com_ptr workArea) noexcept + HWND window, + winrt::com_ptr workArea) noexcept { const auto activeZoneSet = workArea->ActiveZoneSet(); if (activeZoneSet) @@ -458,9 +458,9 @@ RECT FitOnScreen(const RECT& windowRect, const RECT& originMonitorRect, const RE H = min(H, RectHeight(destMonitorRect) - CUSTOM_POSITIONING_LEFT_TOP_PADDING); } - return { .left = left, - .top = top, - .right = left + W, + return { .left = left, + .top = top, + .right = left + W, .bottom = top + H }; } @@ -506,7 +506,7 @@ FancyZones::WindowCreated(HWND window) noexcept // creation of new window. We need to check if window being processed is on currently active desktop. return; } - const bool moveToAppLastZone = m_settings->GetSettings()->appLastZone_moveWindows; + const bool moveToAppLastZone = m_settings->GetSettings()->appLastZone_moveWindows; const bool openOnActiveMonitor = m_settings->GetSettings()->openWindowOnActiveMonitor; if ((moveToAppLastZone || openOnActiveMonitor) && ShouldProcessNewWindow(window)) { diff --git a/src/modules/fancyzones/lib/FancyZones.h b/src/modules/fancyzones/lib/FancyZones.h index 5dc8fdbebc..5d6e455b2b 100644 --- a/src/modules/fancyzones/lib/FancyZones.h +++ b/src/modules/fancyzones/lib/FancyZones.h @@ -1,5 +1,7 @@ #pragma once +#include + interface IZoneWindow; interface IFancyZonesSettings; interface IZoneSet; @@ -11,11 +13,13 @@ interface __declspec(uuid("{50D3F0F5-736E-4186-BDF4-3D6BEE150C3A}")) IFancyZones /** * Start and initialize FancyZones. */ - IFACEMETHOD_(void, Run)() = 0; + IFACEMETHOD_(void, Run) + () = 0; /** * Stop FancyZones and do the clean up. */ - IFACEMETHOD_(void, Destroy)() = 0; + IFACEMETHOD_(void, Destroy) + () = 0; }; /** @@ -26,13 +30,15 @@ interface __declspec(uuid("{2CB37E8F-87E6-4AEC-B4B2-E0FDC873343F}")) IFancyZones /** * Inform FancyZones that user has switched between virtual desktops. */ - IFACEMETHOD_(void, VirtualDesktopChanged)() = 0; + IFACEMETHOD_(void, VirtualDesktopChanged) + () = 0; /** * Callback from WinEventHook to FancyZones * * @param data Handle of window being moved or resized. */ - IFACEMETHOD_(void, HandleWinHookEvent)(const WinHookEvent* data) = 0; + IFACEMETHOD_(void, HandleWinHookEvent) + (const WinHookEvent* data) = 0; /** * Process keyboard event. * @@ -40,15 +46,18 @@ interface __declspec(uuid("{2CB37E8F-87E6-4AEC-B4B2-E0FDC873343F}")) IFancyZones * @returns Boolean indicating if this event should be passed on further to other applications * in event chain, or should it be suppressed. */ - IFACEMETHOD_(bool, OnKeyDown)(PKBDLLHOOKSTRUCT info) = 0; + IFACEMETHOD_(bool, OnKeyDown) + (PKBDLLHOOKSTRUCT info) = 0; /** * Toggle FancyZones editor application. */ - IFACEMETHOD_(void, ToggleEditor)() = 0; + IFACEMETHOD_(void, ToggleEditor) + () = 0; /** * Callback triggered when user changes FancyZones settings. */ - IFACEMETHOD_(void, SettingsChanged)() = 0; + IFACEMETHOD_(void, SettingsChanged) + () = 0; }; /** @@ -59,31 +68,38 @@ interface __declspec(uuid("{5C8D99D6-34B2-4F4A-A8E5-7483F6869775}")) IZoneWindow /** * Assign window to appropriate zone inside new zone layout. */ - IFACEMETHOD_(void, MoveWindowsOnActiveZoneSetChange)() = 0; - /** + IFACEMETHOD_(void, MoveWindowsOnActiveZoneSetChange) + () = 0; + /** * @returns Basic zone color. */ - IFACEMETHOD_(COLORREF, GetZoneColor)() = 0; - /** + IFACEMETHOD_(COLORREF, GetZoneColor) + () = 0; + /** * @returns Zone border color. */ - IFACEMETHOD_(COLORREF, GetZoneBorderColor)() = 0; + IFACEMETHOD_(COLORREF, GetZoneBorderColor) + () = 0; /** * @returns Color used to highlight zone while giving zone layout hints. */ - IFACEMETHOD_(COLORREF, GetZoneHighlightColor)() = 0; + IFACEMETHOD_(COLORREF, GetZoneHighlightColor) + () = 0; /** * @returns Integer in range [0, 100] indicating opacity of highlighted zone (while giving zone layout hints). */ - IFACEMETHOD_(int, GetZoneHighlightOpacity)() = 0; + IFACEMETHOD_(int, GetZoneHighlightOpacity) + () = 0; /** * @returns Boolean indicating if dragged window should be transparent. */ - IFACEMETHOD_(bool, isMakeDraggedWindowTransparentActive) () = 0; + IFACEMETHOD_(bool, isMakeDraggedWindowTransparentActive) + () = 0; /** * @returns Boolean indicating if move/size operation is currently active. */ - IFACEMETHOD_(bool, InMoveSize) () = 0; + IFACEMETHOD_(bool, InMoveSize) + () = 0; }; winrt::com_ptr MakeFancyZones(HINSTANCE hinstance, const winrt::com_ptr& settings) noexcept; diff --git a/src/modules/imageresizer/dll/dllmain.cpp b/src/modules/imageresizer/dll/dllmain.cpp index 479e87ccdd..8d3a761291 100644 --- a/src/modules/imageresizer/dll/dllmain.cpp +++ b/src/modules/imageresizer/dll/dllmain.cpp @@ -53,15 +53,6 @@ public: return app_name.c_str(); } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty - // list. - virtual const wchar_t** get_events() override - { - static const wchar_t* events[] = { nullptr }; - return events; - } - // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -104,15 +95,6 @@ public: { return m_enabled; } - - // Handle incoming event, data is event-specific - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - return 0; - } - - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - virtual void signal_system_menu_action(const wchar_t* name) override {} }; extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() diff --git a/src/modules/interface/lowlevel_keyboard_event_data.h b/src/modules/interface/lowlevel_keyboard_event_data.h deleted file mode 100644 index bd10a61997..0000000000 --- a/src/modules/interface/lowlevel_keyboard_event_data.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include - -/* - ll_keyboard - Lowlevel Keyboard Hook - - The PowerToys runner installs low-level keyboard hook using - SetWindowsHookEx(WH_KEYBOARD_LL, ...) - See https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644985(v%3Dvs.85) - for details. - - When a keyboard event is signaled and ncCode equals HC_ACTION, the wParam - and lParam event parameters are passed to all subscribed clients in - the LowlevelKeyboardEvent struct. - - The intptr_t data event argument is a pointer to the LowlevelKeyboardEvent struct. - - A non-zero return value from any of the subscribed PowerToys will cause - the runner hook proc to return 1, thus swallowing the keyboard event. - - Example usage, that makes Windows ignore the L key: - - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override { - if (wcscmp(name, ll_keyboard) == 0) { - auto& event = *(reinterpret_cast(data)); - // The L key has vkCode of 0x4C - if (event.wParam == WM_KEYDOWN && event.lParam->vkCode == 0x4C) { - return 1; - } else { - return 0; - } - } else { - return 0; - } - } -*/ - -namespace { - const wchar_t* ll_keyboard = L"ll_keyboard"; -} - -struct LowlevelKeyboardEvent { - KBDLLHOOKSTRUCT* lParam; - WPARAM wParam; -}; diff --git a/src/modules/interface/powertoy_module_interface.h b/src/modules/interface/powertoy_module_interface.h index 7e90217a44..5732a9b254 100644 --- a/src/modules/interface/powertoy_module_interface.h +++ b/src/modules/interface/powertoy_module_interface.h @@ -12,7 +12,6 @@ On the received object, the runner will call: - get_name() to get the name of the PowerToy, - - get_events() to get the list of the events the PowerToy wants to subscribe to, - enable() to initialize the PowerToy. While running, the runner might call the following methods between create_powertoy() @@ -21,58 +20,35 @@ - get_config() to get the available configuration settings, - set_config() to set various settings, - call_custom_action() when the user selects clicks a custom action in settings, - - signal_event() to send an event the PowerToy registered to. When terminating, the runner will: - call destroy() which should free all the memory and delete the PowerToy object, - unload the DLL. */ -class PowertoySystemMenuIface; - -class PowertoyModuleIface { +class PowertoyModuleIface +{ public: - /* Returns the name of the PowerToy, this will be cached by the runner. */ - virtual const wchar_t* get_name() = 0; - /* Returns a null-terminated table of the names of the events the PowerToy wants to - subscribe to. Available events: - * ll_keyboard - * win_hook_event - - A nullptr can be returned to signal that the PowerToy does not want to subscribe - to any event. - */ - virtual const wchar_t** get_events() = 0; - /* Fills a buffer with the available configuration settings. - * If 'buffer' is a null ptr or the buffer size is not large enough - * sets the required buffer size in 'buffer_size' and return false. - * Returns true if successful. - */ - virtual bool get_config(wchar_t* buffer, int *buffer_size) = 0; - /* Sets the configuration values. */ - virtual void set_config(const wchar_t* config) = 0; - /* Call custom action from settings screen. */ - virtual void call_custom_action(const wchar_t* action) {}; - /* Enables the PowerToy. */ - virtual void enable() = 0; - /* Disables the PowerToy, should free as much memory as possible. */ - virtual void disable() = 0; - /* Should return if the PowerToys is enabled or disabled. */ - virtual bool is_enabled() = 0; - /* Handle event. Only the events the PowerToy subscribed to will be signaled. - The data argument and return value meaning are event-specific: - * ll_keyboard: see lowlevel_keyboard_event_data.h. - * win_hook_event: see win_hook_event_data.h - */ - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) = 0; - - /* Register helper class to handle system menu items related actions. */ - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) = 0; - /* Handle action on system menu item. */ - virtual void signal_system_menu_action(const wchar_t* name) = 0; - - /* Destroy the PowerToy and free all memory. */ - virtual void destroy() = 0; + /* Returns the name of the PowerToy, this will be cached by the runner. */ + virtual const wchar_t* get_name() = 0; + /* Fills a buffer with the available configuration settings. + * If 'buffer' is a null ptr or the buffer size is not large enough + * sets the required buffer size in 'buffer_size' and return false. + * Returns true if successful. + */ + virtual bool get_config(wchar_t* buffer, int* buffer_size) = 0; + /* Sets the configuration values. */ + virtual void set_config(const wchar_t* config) = 0; + /* Call custom action from settings screen. */ + virtual void call_custom_action(const wchar_t* action){}; + /* Enables the PowerToy. */ + virtual void enable() = 0; + /* Disables the PowerToy, should free as much memory as possible. */ + virtual void disable() = 0; + /* Should return if the PowerToys is enabled or disabled. */ + virtual bool is_enabled() = 0; + /* Destroy the PowerToy and free all memory. */ + virtual void destroy() = 0; }; /* @@ -90,4 +66,4 @@ public: In case of errors return nullptr. */ -typedef PowertoyModuleIface* (__cdecl *powertoy_create_func)(); +typedef PowertoyModuleIface*(__cdecl* powertoy_create_func)(); diff --git a/src/modules/interface/powertoy_system_menu.h b/src/modules/interface/powertoy_system_menu.h deleted file mode 100644 index 1d020da026..0000000000 --- a/src/modules/interface/powertoy_system_menu.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -class PowertoyModuleIface; - -class PowertoySystemMenuIface { -public: - struct ItemInfo { - std::wstring name{}; - bool enable{ false }; - bool checkBox{ false }; - }; - /* - * Set configuration of system menu items for specific powertoy module. Configuration - * parameters include item name (and hotkey), item status at creation (enabled/disabled) - * and whether check box will appear next to item name when action is taken. - */ - virtual void SetConfiguration(PowertoyModuleIface* module, const std::vector& config) = 0; - /* Process action on specific system menu item. */ - virtual void ProcessSelectedItem(PowertoyModuleIface* module, HWND window, const wchar_t* itemName) = 0; -}; diff --git a/src/modules/interface/win_hook_event_data.h b/src/modules/interface/win_hook_event_data.h deleted file mode 100644 index 4790f7d009..0000000000 --- a/src/modules/interface/win_hook_event_data.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include - -/* - win_hook_event - Windows Event Hook - - The PowerToys runner installs event hook functions for a range of events. See - https://docs.microsoft.com/pl-pl/windows/win32/api/winuser/nf-winuser-setwineventhook - for details. - - The intptr_t data event argument is a pointer to the WinHookEvent struct. - - The return value of the event handler is ignored. - - Example usage, that detects a window being resized: - - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override { - if (wcscmp(name, win_hook_event) == 0) { - auto& event = *(reinterpret_cast(data)); - switch (event.event) { - case EVENT_SYSTEM_MOVESIZESTART: - size_start(event.hwnd); - break; - case EVENT_SYSTEM_MOVESIZEEND: - size_end(event.hwnd); - break; - default: - break; - } - } - return 0; - } - - Taking too long to process the events has negative impact on the whole system - performance. To address this, the events are signaled from a different - thread, not from the event hook callback itself. -*/ - -namespace { - const wchar_t* win_hook_event = L"win_hook_event"; -} - -struct WinHookEvent { - DWORD event; - HWND hwnd; - LONG idObject; - LONG idChild; - DWORD idEventThread; - DWORD dwmsEventTime; -}; diff --git a/src/modules/keyboardmanager/common/KeyDelay.h b/src/modules/keyboardmanager/common/KeyDelay.h index 74774ce80f..e76de2e29c 100644 --- a/src/modules/keyboardmanager/common/KeyDelay.h +++ b/src/modules/keyboardmanager/common/KeyDelay.h @@ -3,8 +3,8 @@ #include #include #include -#include +#include // Available states for the KeyDelay state machine. enum class KeyDelayState { diff --git a/src/modules/keyboardmanager/common/KeyboardManagerState.h b/src/modules/keyboardmanager/common/KeyboardManagerState.h index ab31f81e21..4caba6e6a9 100644 --- a/src/modules/keyboardmanager/common/KeyboardManagerState.h +++ b/src/modules/keyboardmanager/common/KeyboardManagerState.h @@ -2,8 +2,8 @@ #include #include "KeyboardManagerConstants.h" #include "../common/keyboard_layout.h" +#include "../common/LowlevelKeyboardEvent.h" #include -#include #include #include "Shortcut.h" #include "RemapShortcut.h" diff --git a/src/modules/keyboardmanager/common/Shortcut.cpp b/src/modules/keyboardmanager/common/Shortcut.cpp index 279ed94bf4..9413da6313 100644 --- a/src/modules/keyboardmanager/common/Shortcut.cpp +++ b/src/modules/keyboardmanager/common/Shortcut.cpp @@ -2,7 +2,6 @@ #include "Shortcut.h" #include "../common/keyboard_layout.h" #include "../common/shared_constants.h" -#include #include "Helpers.h" #include "InputInterface.h" diff --git a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.h b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.h index 0a9f61509b..0708c64a4e 100644 --- a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.h +++ b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.h @@ -1,9 +1,10 @@ #pragma once -#include #include #include #include "keyboardmanager/common/KeyboardManagerConstants.h" +#include + class InputInterface; class KeyboardManagerState; class Shortcut; diff --git a/src/modules/keyboardmanager/dll/dllmain.cpp b/src/modules/keyboardmanager/dll/dllmain.cpp index badddbd894..4bbb4c8820 100644 --- a/src/modules/keyboardmanager/dll/dllmain.cpp +++ b/src/modules/keyboardmanager/dll/dllmain.cpp @@ -1,7 +1,5 @@ #include "pch.h" #include -#include -#include #include #include #include "resource.h" @@ -235,16 +233,6 @@ public: return app_name.c_str(); } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty - // list. - virtual const wchar_t** get_events() override - { - static const wchar_t* events[] = { ll_keyboard, nullptr }; - - return events; - } - // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -339,16 +327,6 @@ public: return m_enabled; } - // Handle incoming event, data is event-specific - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - return 0; - } - - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - - virtual void signal_system_menu_action(const wchar_t* name) override {} - // Hook procedure definition static LRESULT CALLBACK hook_proc(int nCode, WPARAM wParam, LPARAM lParam) { diff --git a/src/modules/keyboardmanager/test/MockedInput.h b/src/modules/keyboardmanager/test/MockedInput.h index 6a5e3d8e79..054a9b5687 100644 --- a/src/modules/keyboardmanager/test/MockedInput.h +++ b/src/modules/keyboardmanager/test/MockedInput.h @@ -2,7 +2,8 @@ #include #include #include -#include + +#include // Class for mocked keyboard input class MockedInput : diff --git a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp index 61428cae2f..52a2667a41 100644 --- a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp +++ b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp @@ -1,7 +1,5 @@ #include "pch.h" #include -#include -#include #include #include #include "trace.h" @@ -80,23 +78,6 @@ public: return app_name.c_str(); } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty - // list. - virtual const wchar_t** get_events() override - { - static const wchar_t* events[] = { nullptr }; - // Available events: - // - ll_keyboard - // - win_hook_event - // - // static const wchar_t* events[] = { ll_keyboard, - // win_hook_event, - // nullptr }; - - return events; - } - // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -232,25 +213,6 @@ public: return m_enabled; } - // Handle incoming event, data is event-specific - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - if (wcscmp(name, ll_keyboard) == 0) - { - auto& event = *(reinterpret_cast(data)); - // Return 1 if the keypress is to be suppressed (not forwarded to Windows), - // otherwise return 0. - return 0; - } - else if (wcscmp(name, win_hook_event) == 0) - { - auto& event = *(reinterpret_cast(data)); - // Return value is ignored - return 0; - } - return 0; - } - // Callback to send WM_CLOSE signal to each top level window. static BOOL CALLBACK requestMainWindowClose(HWND nextWindow, LPARAM closePid) { @@ -274,11 +236,6 @@ public: TerminateProcess(m_hProcess, 1); } } - - /* Register helper class to handle system menu items related actions. */ - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) {} - /* Handle action on system menu item. */ - virtual void signal_system_menu_action(const wchar_t* name) {} }; // Load the settings file. diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index 1cbf1f00a9..577eef9606 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -183,13 +183,6 @@ public: return m_enabled; } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty list. - virtual PCWSTR* get_events() override - { - return nullptr; - } - // Return JSON with the configuration options. // 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 @@ -266,15 +259,6 @@ public: { } - // Handle incoming event, data is event-specific - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - return 0; - } - - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - virtual void signal_system_menu_action(const wchar_t* name) override {} - // Destroy the powertoy and free memory virtual void destroy() override { diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index d84a4c525e..113418fa8a 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -1,6 +1,4 @@ #include "pch.h" -#include -#include #include #include #include "powerpreview.h" @@ -49,11 +47,6 @@ const wchar_t* PowerPreviewModule::get_name() return m_moduleName.c_str(); } -const wchar_t** PowerPreviewModule::get_events() -{ - return nullptr; -} - // Return JSON with the configuration options. bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size) { @@ -89,7 +82,6 @@ bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_siz thumbnailProvider->GetToggleSettingState()); } - return settings.serialize_to_buffer(buffer, buffer_size); } @@ -182,12 +174,6 @@ bool PowerPreviewModule::is_enabled() return this->m_enabled; } -// Handle incoming event, data is event-specific -intptr_t PowerPreviewModule::signal_event(const wchar_t* name, intptr_t data) -{ - return 0; -} - // Load the settings file. void PowerPreviewModule::init_settings() { @@ -207,7 +193,6 @@ void PowerPreviewModule::init_settings() { thumbnailProvider->LoadState(settings); } - } catch (std::exception const& e) { diff --git a/src/modules/previewpane/powerpreview/powerpreview.h b/src/modules/previewpane/powerpreview/powerpreview.h index fef8dfe3bf..e0920712bc 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.h +++ b/src/modules/previewpane/powerpreview/powerpreview.h @@ -16,7 +16,7 @@ private: // The PowerToy state. bool m_enabled = false; std::wstring m_moduleName; - std::vector m_previewHandlers; + std::vector m_previewHandlers; std::vector m_thumbnailProviders; public: @@ -39,8 +39,7 @@ public: GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION), L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}", L"Markdown Preview Handler", - new RegistryWrapper()) - }), + new RegistryWrapper()) }), m_thumbnailProviders( { // TODO: MOVE THIS SVG Thumbnail Provider settings object. new FileExplorerPreviewSettings( @@ -49,22 +48,17 @@ public: GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), L"{36B27788-A8BB-4698-A756-DF9F11F64F84}", L"SVG Thumbnail Provider", - new RegistryWrapper()) - }) + new RegistryWrapper()) }) { init_settings(); }; virtual void destroy(); virtual const wchar_t* get_name(); - virtual const wchar_t** get_events(); virtual bool get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size); virtual void set_config(const wchar_t* config); virtual void enable(); virtual void disable(); virtual bool is_enabled(); virtual void init_settings(); - virtual intptr_t signal_event(const wchar_t* name, intptr_t data); - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - virtual void signal_system_menu_action(const wchar_t* name) override {} }; \ No newline at end of file diff --git a/src/modules/shortcut_guide/shortcut_guide.cpp b/src/modules/shortcut_guide/shortcut_guide.cpp index f7bf519b92..32a47ef37a 100644 --- a/src/modules/shortcut_guide/shortcut_guide.cpp +++ b/src/modules/shortcut_guide/shortcut_guide.cpp @@ -42,11 +42,6 @@ const wchar_t* OverlayWindow::get_name() return app_name.c_str(); } -const wchar_t** OverlayWindow::get_events() -{ - return nullptr; -} - bool OverlayWindow::get_config(wchar_t* buffer, int* buffer_size) { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); @@ -213,11 +208,6 @@ bool OverlayWindow::is_enabled() return _enabled; } -intptr_t OverlayWindow::signal_event(const wchar_t* name, intptr_t data) -{ - return 0; -} - intptr_t OverlayWindow::signal_event(LowlevelKeyboardEvent* event) { if (!_enabled) diff --git a/src/modules/shortcut_guide/shortcut_guide.h b/src/modules/shortcut_guide/shortcut_guide.h index 5d207ab13a..4adeed0687 100644 --- a/src/modules/shortcut_guide/shortcut_guide.h +++ b/src/modules/shortcut_guide/shortcut_guide.h @@ -1,10 +1,11 @@ #pragma once #include -#include #include "overlay_window.h" #include "resource.h" +#include + // We support only one instance of the overlay extern class OverlayWindow* instance; @@ -16,7 +17,6 @@ public: OverlayWindow(); virtual const wchar_t* get_name() override; - virtual const wchar_t** get_events() override; virtual bool get_config(wchar_t* buffer, int* buffer_size) override; virtual void set_config(const wchar_t* config) override; @@ -24,18 +24,11 @@ public: virtual void disable() 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 void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} - virtual void signal_system_menu_action(const wchar_t* name) override {} - void on_held(); void on_held_press(DWORD vkCode); void quick_hide(); void was_hidden(); - // Method called from LowLevelKeyboardProc intptr_t signal_event(LowlevelKeyboardEvent* event); virtual void destroy() override; diff --git a/src/runner/lowlevel_keyboard_event.cpp b/src/runner/lowlevel_keyboard_event.cpp deleted file mode 100644 index 13a5a6ad98..0000000000 --- a/src/runner/lowlevel_keyboard_event.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "pch.h" -#include "lowlevel_keyboard_event.h" -#include "powertoys_events.h" -#include - -namespace -{ - HHOOK hook_handle = nullptr; - HHOOK hook_handle_copy = nullptr; // make sure we do use nullptr in CallNextHookEx call - LRESULT CALLBACK hook_proc(int nCode, WPARAM wParam, LPARAM lParam) - { - LowlevelKeyboardEvent event; - if (nCode == HC_ACTION) - { - event.lParam = reinterpret_cast(lParam); - event.wParam = wParam; - if (powertoys_events().signal_event(ll_keyboard, reinterpret_cast(&event)) != 0) - { - return 1; - } - } - return CallNextHookEx(hook_handle_copy, nCode, wParam, lParam); - } -} - -void start_lowlevel_keyboard_hook() -{ -#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED) - if (IsDebuggerPresent()) - { - return; - } -#endif - - if (!hook_handle) - { - hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, GetModuleHandle(NULL), NULL); - hook_handle_copy = hook_handle; - if (!hook_handle) - { - throw std::runtime_error("Cannot install keyboard listener"); - } - } -} - -void stop_lowlevel_keyboard_hook() -{ - if (hook_handle) - { - UnhookWindowsHookEx(hook_handle); - hook_handle = nullptr; - } -} diff --git a/src/runner/lowlevel_keyboard_event.h b/src/runner/lowlevel_keyboard_event.h deleted file mode 100644 index 8cac70893b..0000000000 --- a/src/runner/lowlevel_keyboard_event.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include - -void start_lowlevel_keyboard_hook(); -void stop_lowlevel_keyboard_hook(); diff --git a/src/runner/main.cpp b/src/runner/main.cpp index 254c1dbc6c..d7ba0b923b 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -400,8 +400,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { // Singletons initialization order needs to be preserved, first events and // then modules to guarantee the reverse destruction order. - SystemMenuHelperInstance(); - powertoys_events(); modules(); auto general_settings = load_general_settings(); diff --git a/src/runner/powertoy_module.cpp b/src/runner/powertoy_module.cpp index 988fc08516..2b81f405c9 100644 --- a/src/runner/powertoy_module.cpp +++ b/src/runner/powertoy_module.cpp @@ -22,7 +22,6 @@ PowertoyModule load_powertoy(const std::wstring_view filename) FreeLibrary(handle); winrt::throw_last_error(); } - module->register_system_menu_helper(&SystemMenuHelperInstance()); return PowertoyModule(module, handle); } @@ -43,16 +42,4 @@ PowertoyModule::PowertoyModule(PowertoyModuleIface* module, HMODULE handle) : { throw std::runtime_error("Module not initialized"); } - auto want_signals = module->get_events(); - if (want_signals) - { - for (; *want_signals; ++want_signals) - { - powertoys_events().register_receiver(*want_signals, module); - } - } - if (SystemMenuHelperInstance().HasCustomConfig(module)) - { - powertoys_events().register_system_menu_action(module); - } } diff --git a/src/runner/powertoy_module.h b/src/runner/powertoy_module.h index 7be349a231..36986d5053 100644 --- a/src/runner/powertoy_module.h +++ b/src/runner/powertoy_module.h @@ -1,6 +1,4 @@ #pragma once -#include "powertoys_events.h" -#include "system_menu_helper.h" #include #include #include @@ -16,8 +14,6 @@ struct PowertoyModuleDeleter { if (module) { - powertoys_events().unregister_system_menu_action(module); - powertoys_events().unregister_receiver(module); module->destroy(); } } diff --git a/src/runner/powertoys_events.cpp b/src/runner/powertoys_events.cpp deleted file mode 100644 index a557c4832d..0000000000 --- a/src/runner/powertoys_events.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "pch.h" -#include "powertoys_events.h" -#include "lowlevel_keyboard_event.h" -#include "win_hook_event.h" -#include "system_menu_helper.h" - -void first_subscribed(const std::wstring& event) -{ - if (event == ll_keyboard) - start_lowlevel_keyboard_hook(); - else if (event == win_hook_event) - start_win_hook_event(); -} - -void last_unsubscribed(const std::wstring& event) -{ - if (event == ll_keyboard) - stop_lowlevel_keyboard_hook(); - else if (event == win_hook_event) - stop_win_hook_event(); -} - -PowertoysEvents& powertoys_events() -{ - static PowertoysEvents powertoys_events; - return powertoys_events; -} - -void PowertoysEvents::register_receiver(const std::wstring& event, PowertoyModuleIface* module) -{ - std::unique_lock lock(mutex); - auto& subscribers = receivers[event]; - if (subscribers.empty()) - { - first_subscribed(event); - } - subscribers.push_back(module); -} - -void PowertoysEvents::unregister_receiver(PowertoyModuleIface* module) -{ - std::unique_lock lock(mutex); - for (auto& [event, subscribers] : receivers) - { - subscribers.erase(remove(begin(subscribers), end(subscribers), module), end(subscribers)); - if (subscribers.empty()) - { - last_unsubscribed(event); - } - } -} - -void PowertoysEvents::register_system_menu_action(PowertoyModuleIface* module) -{ - std::unique_lock lock(mutex); - system_menu_receivers.insert(module); -} - -void PowertoysEvents::unregister_system_menu_action(PowertoyModuleIface* module) -{ - std::unique_lock lock(mutex); - auto it = system_menu_receivers.find(module); - if (it != system_menu_receivers.end()) - { - SystemMenuHelperInstance().Reset(module); - system_menu_receivers.erase(it); - } -} - -void PowertoysEvents::handle_system_menu_action(const WinHookEvent& data) -{ - if (data.event == EVENT_SYSTEM_MENUSTART) - { - for (auto& module : system_menu_receivers) - { - SystemMenuHelperInstance().Customize(module, data.hwnd); - } - } - else if (data.event == EVENT_OBJECT_INVOKED) - { - if (PowertoyModuleIface * module{ SystemMenuHelperInstance().ModuleFromItemId(data.idChild) }) - { - std::wstring itemName = SystemMenuHelperInstance().ItemNameFromItemId(data.idChild); - // Process event on specified system menu item by responsible module. - module->signal_system_menu_action(itemName.c_str()); - // Process event on specified system menu item by system menu helper (check/uncheck if needed). - SystemMenuHelperInstance().ProcessSelectedItem(module, GetForegroundWindow(), itemName.c_str()); - } - } -} - -intptr_t PowertoysEvents::signal_event(const std::wstring& event, intptr_t data) -{ - intptr_t rvalue = 0; - std::shared_lock lock(mutex); - if (auto it = receivers.find(event); it != end(receivers)) - { - for (auto& module : it->second) - { - if (module) - rvalue |= module->signal_event(event.c_str(), data); - } - } - return rvalue; -} \ No newline at end of file diff --git a/src/runner/powertoys_events.h b/src/runner/powertoys_events.h deleted file mode 100644 index 2d5342fa62..0000000000 --- a/src/runner/powertoys_events.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -class PowertoysEvents -{ -public: - void register_receiver(const std::wstring& event, PowertoyModuleIface* module); - void unregister_receiver(PowertoyModuleIface* module); - - void register_system_menu_action(PowertoyModuleIface* module); - void unregister_system_menu_action(PowertoyModuleIface* module); - void handle_system_menu_action(const WinHookEvent& data); - - intptr_t signal_event(const std::wstring& event, intptr_t data); - -private: - std::shared_mutex mutex; - std::unordered_map> receivers; - std::unordered_set system_menu_receivers; -}; - -PowertoysEvents& powertoys_events(); - -void first_subscribed(const std::wstring& event); -void last_unsubscribed(const std::wstring& event); diff --git a/src/runner/runner.vcxproj b/src/runner/runner.vcxproj index 602636db8b..ca04780857 100644 --- a/src/runner/runner.vcxproj +++ b/src/runner/runner.vcxproj @@ -111,41 +111,33 @@ - Create - - - - - - - diff --git a/src/runner/runner.vcxproj.filters b/src/runner/runner.vcxproj.filters index 8f757da205..7354c01cd0 100644 --- a/src/runner/runner.vcxproj.filters +++ b/src/runner/runner.vcxproj.filters @@ -6,9 +6,6 @@ Utils - - Events - Utils @@ -27,15 +24,6 @@ Utils - - Utils - - - Events - - - Utils - Utils @@ -54,9 +42,6 @@ Utils - - Events - Utils @@ -75,15 +60,6 @@ Utils - - Utils - - - Events - - - Utils - Utils @@ -107,9 +83,6 @@ {1123565f-43ba-4eb8-a6f5-2d5f8f3ae6af} - - {d409b25e-c0f1-4913-bb32-da4a21339c76} - {74d0b535-16ee-46cc-9adf-dc4668bbcfda} diff --git a/src/runner/system_menu_helper.cpp b/src/runner/system_menu_helper.cpp deleted file mode 100644 index c8da06860f..0000000000 --- a/src/runner/system_menu_helper.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include "pch.h" -#include "system_menu_helper.h" - -#include - -namespace -{ - constexpr int KSeparatorPos = 1; - constexpr int KNewItemPos = 2; - - unsigned int GenerateItemId() - { - static unsigned int generator = 0x70777479; - return ++generator; - } -} - -SystemMenuHelper& SystemMenuHelperInstance() -{ - static SystemMenuHelper instance; - return instance; -} - -void SystemMenuHelper::SetConfiguration(PowertoyModuleIface* module, const std::vector& config) -{ - Reset(module); - Configurations[module] = config; - for (auto& [window, modules] : ProcessedModules) - { - // Unregister module. After system menu is opened again, new configuration will be applied. - modules.erase(std::remove(std::begin(modules), std::end(modules), module), std::end(modules)); - } -} - -void SystemMenuHelper::ProcessSelectedItem(PowertoyModuleIface* module, HWND window, const wchar_t* itemName) -{ - for (const auto& item : Configurations[module]) - { - if (itemName == item.name && item.checkBox) - { - // Handle check/uncheck action only if specified by module configuration. - for (const auto& [id, data] : IdMappings) - { - if (data.second == itemName) - { - HMENU systemMenu = GetSystemMenu(window, false); - int state = (GetMenuState(systemMenu, id, MF_BYCOMMAND) == MF_CHECKED) ? MF_UNCHECKED : MF_CHECKED; - CheckMenuItem(systemMenu, id, MF_BYCOMMAND | state); - break; - } - } - break; - } - } -} - -bool SystemMenuHelper::Customize(PowertoyModuleIface* module, HWND window) -{ - auto& modules = ProcessedModules[window]; - for (const auto& m : modules) - { - if (module == m) - { - return false; - } - } - AddSeparator(module, window); - for (const auto& info : Configurations[module]) - { - AddItem(module, window, info.name, info.enable); - } - modules.push_back(module); - return true; -} - -void SystemMenuHelper::Reset(PowertoyModuleIface* module) -{ - for (auto& [window, modules] : ProcessedModules) - { - if (HMENU systemMenu{ GetSystemMenu(window, false) }) - { - for (auto& [id, data] : IdMappings) - { - if (data.first == module) - { - DeleteMenu(systemMenu, id, MF_BYCOMMAND); - } - } - } - } -} - -bool SystemMenuHelper::HasCustomConfig(PowertoyModuleIface* module) -{ - return Configurations.find(module) != Configurations.end(); -} - -bool SystemMenuHelper::AddItem(PowertoyModuleIface* module, HWND window, const std::wstring& name, const bool enable) -{ - if (HMENU systemMenu{ GetSystemMenu(window, false) }) - { - MENUITEMINFO item; - item.cbSize = sizeof(item); - item.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE; - item.fState = MF_UNCHECKED | MF_DISABLED; // Item is disabled by default. - item.wID = GenerateItemId(); - item.dwTypeData = const_cast(name.c_str()); - item.cch = (UINT)name.size() + 1; - - if (InsertMenuItem(systemMenu, GetMenuItemCount(systemMenu) - KNewItemPos, true, &item)) - { - IdMappings[item.wID] = { module, name }; - if (enable) - { - EnableMenuItem(systemMenu, item.wID, MF_BYCOMMAND | MF_ENABLED); - } - return true; - } - } - return false; -} - -bool SystemMenuHelper::AddSeparator(PowertoyModuleIface* module, HWND window) -{ - if (HMENU systemMenu{ GetSystemMenu(window, false) }) - { - MENUITEMINFO separator; - separator.cbSize = sizeof(separator); - separator.fMask = MIIM_ID | MIIM_FTYPE; - separator.fType = MFT_SEPARATOR; - separator.wID = GenerateItemId(); - - if (InsertMenuItem(systemMenu, GetMenuItemCount(systemMenu) - KSeparatorPos, true, &separator)) - { - IdMappings[separator.wID] = { module, L"separator_dummy_name" }; - return true; - } - } - return false; -} - -PowertoyModuleIface* SystemMenuHelper::ModuleFromItemId(const int& id) -{ - auto it = IdMappings.find(id); - if (it != IdMappings.end()) - { - return it->second.first; - } - return nullptr; -} - -const std::wstring SystemMenuHelper::ItemNameFromItemId(const int& id) -{ - auto itemIt = IdMappings.find(id); - if (itemIt != IdMappings.end()) - { - return itemIt->second.second; - } - return std::wstring{}; -} diff --git a/src/runner/system_menu_helper.h b/src/runner/system_menu_helper.h deleted file mode 100644 index e2c125a4b5..0000000000 --- a/src/runner/system_menu_helper.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#pragma once - -#include -#include -#include -#include -#include - -class PowertoyModuleIface; - -class SystemMenuHelper : public PowertoySystemMenuIface -{ -public: - // PowertoySystemMenuIface - virtual void SetConfiguration(PowertoyModuleIface* module, const std::vector& config) override; - virtual void ProcessSelectedItem(PowertoyModuleIface* module, HWND window, const wchar_t* itemName) override; - - bool Customize(PowertoyModuleIface* module, HWND window); - void Reset(PowertoyModuleIface* module); - - bool HasCustomConfig(PowertoyModuleIface* module); - - PowertoyModuleIface* ModuleFromItemId(const int& id); - const std::wstring ItemNameFromItemId(const int& id); - -private: - bool AddItem(PowertoyModuleIface* module, HWND window, const std::wstring& name, const bool enable); - bool AddSeparator(PowertoyModuleIface* module, HWND window); - - // Store processed modules per window to avoid handling it multiple times. - std::unordered_map> ProcessedModules{}; - - // Keep mappings form item id to the module who created it and item name for faster processing later. - std::unordered_map> IdMappings{}; - - // Store configurations provided by module. - // This will be used to create custom system menu items and to handle updates. - std::unordered_map> Configurations{}; -}; - -SystemMenuHelper& SystemMenuHelperInstance(); diff --git a/src/runner/win_hook_event.cpp b/src/runner/win_hook_event.cpp deleted file mode 100644 index 7924027127..0000000000 --- a/src/runner/win_hook_event.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "pch.h" -#include "win_hook_event.h" -#include "powertoy_module.h" -#include -#include -#include - -static std::mutex mutex; -static std::deque hook_events; -static std::condition_variable dispatch_cv; - -void intercept_system_menu_action(intptr_t); - -static void CALLBACK win_hook_event_proc(HWINEVENTHOOK winEventHook, - DWORD event, - HWND window, - LONG object, - LONG child, - DWORD eventThread, - DWORD eventTime) -{ - std::unique_lock lock(mutex); - hook_events.push_back({ event, - window, - object, - child, - eventThread, - eventTime }); - lock.unlock(); - dispatch_cv.notify_one(); -} - -static bool running = false; -static std::thread dispatch_thread; -static void dispatch_thread_proc() -{ - std::unique_lock lock(mutex); - while (running) - { - dispatch_cv.wait(lock, [] { return !running || !hook_events.empty(); }); - if (!running) - return; - while (!hook_events.empty()) - { - auto event = hook_events.front(); - hook_events.pop_front(); - lock.unlock(); - intptr_t data = reinterpret_cast(&event); - intercept_system_menu_action(data); - powertoys_events().signal_event(win_hook_event, data); - lock.lock(); - } - } -} - -static HWINEVENTHOOK hook_handle; - -void start_win_hook_event() -{ - std::lock_guard lock(mutex); - if (running) - return; - running = true; - dispatch_thread = std::thread(dispatch_thread_proc); - hook_handle = SetWinEventHook(EVENT_MIN, EVENT_MAX, nullptr, win_hook_event_proc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); -} - -void stop_win_hook_event() -{ - std::unique_lock lock(mutex); - if (!running) - return; - running = false; - UnhookWinEvent(hook_handle); - lock.unlock(); - dispatch_cv.notify_one(); - dispatch_thread.join(); - lock.lock(); - hook_events.clear(); - hook_events.shrink_to_fit(); -} - -void intercept_system_menu_action(intptr_t data) -{ - WinHookEvent* evt = reinterpret_cast(data); - if (evt->event == EVENT_SYSTEM_MENUSTART || evt->event == EVENT_OBJECT_INVOKED) - { - powertoys_events().handle_system_menu_action(*evt); - } -} diff --git a/src/runner/win_hook_event.h b/src/runner/win_hook_event.h deleted file mode 100644 index 24bff1a0be..0000000000 --- a/src/runner/win_hook_event.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include - -void start_win_hook_event(); -void stop_win_hook_event(); diff --git a/tools/project_template/ModuleTemplate/dllmain.cpp b/tools/project_template/ModuleTemplate/dllmain.cpp index 03020f3b57..7d9c47286c 100644 --- a/tools/project_template/ModuleTemplate/dllmain.cpp +++ b/tools/project_template/ModuleTemplate/dllmain.cpp @@ -1,7 +1,5 @@ #include "pch.h" #include -#include -#include #include #include "trace.h" @@ -74,23 +72,6 @@ public: return MODULE_NAME; } - // Return array of the names of all events that this powertoy listens for, with - // nullptr as the last element of the array. Nullptr can also be returned for empty - // list. - virtual const wchar_t** get_events() override - { - static const wchar_t* events[] = { nullptr }; - // Available events: - // - ll_keyboard - // - win_hook_event - // - // static const wchar_t* events[] = { ll_keyboard, - // win_hook_event, - // nullptr }; - - return events; - } - // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -228,34 +209,6 @@ public: { return m_enabled; } - - // Handle incoming event, data is event-specific - virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override - { - if (wcscmp(name, ll_keyboard) == 0) - { - auto& event = *(reinterpret_cast(data)); - // Return 1 if the keypress is to be suppressed (not forwarded to Windows), - // otherwise return 0. - return 0; - } - else if (wcscmp(name, win_hook_event) == 0) - { - auto& event = *(reinterpret_cast(data)); - // Return value is ignored - return 0; - } - return 0; - } - - // This methods are part of an experimental features not fully supported yet - virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override - { - } - - virtual void signal_system_menu_action(const wchar_t* name) override - { - } }; // Load the settings file.