Fix some bugs and add debug menu

This commit is contained in:
Noraa Junker
2026-02-20 17:16:27 +01:00
parent 03017e4703
commit 989c2eab23
14 changed files with 379 additions and 20 deletions

View File

@@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Windows.System;
@@ -12,7 +14,11 @@ namespace RunnerV2.Helpers
{
internal static class CentralizedKeyboardHookManager
{
private static readonly UIntPtr _ignoreKeyEventFlag = 0x5555;
private static readonly UIntPtr _ignoreKeyEventFlag = 0x5556;
public static bool DebugConsole { get => _debugConsole; set => _debugConsole = value; }
private static volatile bool _debugConsole;
public static OrderedDictionary<string, List<(HotkeySettings HotkeySettings, Action Action)>> KeyboardHooks { get; } = [];
@@ -20,6 +26,11 @@ namespace RunnerV2.Helpers
private static void OnKeyDown(int key)
{
if (_debugConsole)
{
Console.WriteLine($"Key down: {(VirtualKey)key}, Ctrl: {_ctrlState}, Alt: {_altState}, Shift: {_shiftState}, Win: {_winState}");
}
if ((VirtualKey)key == VirtualKey.RightMenu && _ctrlState)
{
_ctrlAltState = true;
@@ -63,10 +74,19 @@ namespace RunnerV2.Helpers
}
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyDown);
if (_debugConsole)
{
Console.WriteLine($"Key down send: {(VirtualKey)key}, Ctrl: {_ctrlState}, Alt: {_altState}, Shift: {_shiftState}, Win: {_winState}");
}
}
private static void OnKeyUp(int key)
{
if (_debugConsole)
{
Console.WriteLine($"Key up: {(VirtualKey)key}, Ctrl: {_ctrlState}, Alt: {_altState}, Shift: {_shiftState}, Win: {_winState}");
}
switch ((VirtualKey)key)
{
case VirtualKey.Control:
@@ -100,6 +120,10 @@ namespace RunnerV2.Helpers
}
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
if (_debugConsole)
{
Console.WriteLine($"Key up send: {(VirtualKey)key}, Ctrl: {_ctrlState}, Alt: {_altState}, Shift: {_shiftState}, Win: {_winState}");
}
}
private static bool _ctrlState;
@@ -206,10 +230,6 @@ namespace RunnerV2.Helpers
0x24 => true, // VK_HOME
0x21 => true, // VK_PRIOR (Page Up)
0x22 => true, // VK_NEXT (Page Down)
0x25 => true, // VK_LEFT
0x26 => true, // VK_UP
0x27 => true, // VK_RIGHT
0x28 => true, // VK_DOWN
0x90 => true, // VK_NUMLOCK
_ => false,
};

View File

@@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using ManagedCommon;
@@ -57,7 +58,7 @@ namespace RunnerV2.Helpers
{
try
{
return !_process.HasExited;
return _process.StartInfo.FileName == string.Empty ? false : !_process.HasExited;
}
catch (Exception)
{

View File

@@ -30,6 +30,8 @@ namespace RunnerV2.Helpers
/// </summary>
internal static class SettingsHelper
{
public static bool Debugging { get; set; }
private static readonly SettingsUtils _settingsUtils = SettingsUtils.Default;
private static Process? _process;
private static TwoWayPipeMessageIPCManaged? _ipc;
@@ -102,6 +104,11 @@ namespace RunnerV2.Helpers
public static void OnSettingsMessageReceived(string message)
{
if (Debugging)
{
Console.WriteLine("Received message from settings: " + message);
}
JsonDocument messageDocument = JsonDocument.Parse(message);
foreach (var property in messageDocument.RootElement.EnumerateObject())
@@ -111,7 +118,6 @@ namespace RunnerV2.Helpers
case "action":
foreach (var moduleName in property.Value.EnumerateObject())
{
_settingsUtils.SaveSettings(moduleName.Value.ToString(), moduleName.Name);
if (moduleName.Name == "general")
{
switch (moduleName.Value.GetProperty("action_name").GetString())
@@ -250,6 +256,7 @@ namespace RunnerV2.Helpers
if (Runner.LoadedModules.Find(m => m.Name == powertoysSettingsPart.Name) is IPowerToysModuleSettingsChangedSubscriber module && module is IPowerToysModule ptModule && ptModule.Enabled)
{
Logger.InitializeLogger("\\" + ptModule.Name + "\\ModuleInterface\\Logs");
SettingsUtils.Default.SaveSettings(powertoysSettingsPart.Value.ToString(), powertoysSettingsPart.Name);
module.OnSettingsChanged();
Logger.InitializeLogger("\\RunnerLogs");
}

View File

@@ -5,13 +5,16 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;
using PowerToys.Interop;
using RunnerV2.Models;
using RunnerV2.properties;
using static RunnerV2.NativeMethods;
@@ -94,6 +97,18 @@ namespace RunnerV2.Helpers
ReportBug,
Close,
QuickAccess,
DebugKeyboardShortcuts,
DebugSettingsIpc,
DebugWriteUncaughtExceptionsToConsole,
DebugSendCustomMessage,
DebugActivateModule,
DebugDeactivateModule,
DebugAllEnableModule,
DebugAllDisableModule,
DebugSendCustomAction,
DebugListAllCustomActions,
DebugListAllShortcuts,
DebugFullModuleReport,
}
private static bool _doubleClickTimerRunning;
@@ -113,6 +128,29 @@ namespace RunnerV2.Helpers
public static void RegenerateRightClickMenu()
{
_trayIconMenu = CreatePopupMenu();
#if DEBUG
IntPtr ipcMenu = CreateMenu();
AppendMenuW(ipcMenu, 0u, new UIntPtr((uint)TrayButton.DebugSettingsIpc), "Toggle logging Settings IPC");
AppendMenuW(ipcMenu, 0u, new UIntPtr((uint)TrayButton.DebugSendCustomMessage), "Send Custom Message To Runner");
IntPtr modulesMenu = CreateMenu();
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugFullModuleReport), "Full report on all modules");
AppendMenuW(modulesMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // serator
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugActivateModule), "Activate Module by name");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugDeactivateModule), "Deactivate Module by name");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugAllEnableModule), "Run all enable functions of all modules");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugAllDisableModule), "Run all disable functions of all modules");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugSendCustomAction), "Send Custom Action");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugListAllCustomActions), "List all Custom Actions");
AppendMenuW(modulesMenu, 0u, new UIntPtr((uint)TrayButton.DebugListAllShortcuts), "List all Shortcuts");
AppendMenuW(_trayIconMenu, 0x2u, UIntPtr.Zero, "Debug build options:");
AppendMenuW(_trayIconMenu, 0x10u, (UIntPtr)ipcMenu, "Settings <-> Runner IPC");
AppendMenuW(_trayIconMenu, 0x10u, (UIntPtr)modulesMenu, "Module interfaces");
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.DebugKeyboardShortcuts), "Toggle logging Centralized Keyboard Hook");
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.DebugWriteUncaughtExceptionsToConsole), "Toggle logging Uncaught Exceptions");
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // separator
#endif
if (SettingsUtils.Default.GetSettings<GeneralSettings>().EnableQuickAccess)
{
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.QuickAccess), Resources.ContextMenu_QuickAccess + "\t" + Resources.ContextMenu_LeftClick);
@@ -123,7 +161,7 @@ namespace RunnerV2.Helpers
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.Settings), Resources.ContextMenu_Settings + "\t" + Resources.ContextMenu_LeftClick);
}
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // separator
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // serator
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.Documentation), Resources.ContextMenu_Documentation);
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.ReportBug), Resources.ContextMenu_ReportBug);
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // separator
@@ -222,6 +260,207 @@ namespace RunnerV2.Helpers
case TrayButton.Close:
Runner.Close();
break;
#if DEBUG
case TrayButton.DebugKeyboardShortcuts:
AllocConsole();
CentralizedKeyboardHookManager.DebugConsole = !CentralizedKeyboardHookManager.DebugConsole;
break;
case TrayButton.DebugSettingsIpc:
AllocConsole();
SettingsHelper.Debugging = !SettingsHelper.Debugging;
break;
case TrayButton.DebugWriteUncaughtExceptionsToConsole:
AllocConsole();
Runner.DebbugingLogUncaughtExceptions = !Runner.DebbugingLogUncaughtExceptions;
break;
case TrayButton.DebugSendCustomMessage:
AllocConsole();
Console.Write("Enter the message you want to send to the Runner process: ");
string? message = Console.ReadLine();
if (string.IsNullOrEmpty(message))
{
Console.WriteLine("No message entered. Aborting.");
return;
}
SettingsHelper.OnSettingsMessageReceived(message);
break;
case TrayButton.DebugActivateModule:
AllocConsole();
Console.Write("Enter the name of the module you want to activate: ");
string? moduleToActivate = Console.ReadLine();
if (string.IsNullOrEmpty(moduleToActivate))
{
Console.WriteLine("No module name entered. Aborting.");
return;
}
SettingsHelper.OnSettingsMessageReceived("{\"module_status\": {\"" + moduleToActivate + "\": true}}");
break;
case TrayButton.DebugDeactivateModule:
AllocConsole();
Console.Write("Enter the name of the module you want to deactivate: ");
string? moduleToDeactivate = Console.ReadLine();
if (string.IsNullOrEmpty(moduleToDeactivate))
{
Console.WriteLine("No module name entered. Aborting.");
return;
}
SettingsHelper.OnSettingsMessageReceived("{\"module_status\": {\"" + moduleToDeactivate + "\": false}}");
break;
case TrayButton.DebugAllEnableModule:
AllocConsole();
foreach (var module in Runner.ModulesToLoad)
{
module.Enable();
}
Console.WriteLine("All enabled functions run.");
break;
case TrayButton.DebugAllDisableModule:
AllocConsole();
foreach (var module in Runner.ModulesToLoad)
{
module.Disable();
}
Console.WriteLine("All disable functions run.");
break;
case TrayButton.DebugSendCustomAction:
AllocConsole();
Console.Write("Enter the name of the module you want to send the action to: ");
string? moduleName = Console.ReadLine();
if (string.IsNullOrEmpty(moduleName))
{
Console.WriteLine("No module name entered. Aborting.");
return;
}
Console.Write("Enter the name of the action you want to send: ");
string? actionName = Console.ReadLine();
if (string.IsNullOrEmpty(actionName))
{
Console.WriteLine("No action name entered. Aborting.");
return;
}
Console.Write("Enter the data you want to send with the action (or leave empty for no data): ");
string? actionData = Console.ReadLine();
if (actionData is null)
{
Console.WriteLine("No action data entered. Aborting.");
return;
}
SettingsHelper.OnSettingsMessageReceived("{\"action\": {\"" + moduleName + "\": {\"action_name\": \"" + actionName + "\", \"value\": \"" + actionData + "\"}}}");
break;
case TrayButton.DebugListAllCustomActions:
AllocConsole();
Console.Write("Name of the module whose custom actions you want to list: ");
string? moduleNameForCustomActions = Console.ReadLine();
if (string.IsNullOrEmpty(moduleNameForCustomActions))
{
Console.WriteLine("No module name entered. Aborting.");
return;
}
var moduleForCustomActions = Runner.ModulesToLoad.FirstOrDefault(m => m.Name.Equals(moduleNameForCustomActions, StringComparison.OrdinalIgnoreCase));
if (moduleForCustomActions == null)
{
Console.WriteLine("No module with that name found. Aborting.");
return;
}
if (moduleForCustomActions is not IPowerToysModuleCustomActionsProvider customActionsProvider)
{
Console.WriteLine("Module does not provide custom actions. Aborting.");
return;
}
foreach (var customAction in customActionsProvider.CustomActions)
{
Console.WriteLine("Action name: " + customAction.Key);
}
break;
case TrayButton.DebugListAllShortcuts:
AllocConsole();
Console.Write("Name of the module whose shortcuts you want to list: ");
string? moduleNameForShortcuts = Console.ReadLine();
if (string.IsNullOrEmpty(moduleNameForShortcuts))
{
Console.WriteLine("No module name entered. Aborting.");
return;
}
var moduleForShortcuts = Runner.ModulesToLoad.FirstOrDefault(m => m.Name.Equals(moduleNameForShortcuts, StringComparison.OrdinalIgnoreCase));
if (moduleForShortcuts == null)
{
Console.WriteLine("No module with that name found. Aborting.");
return;
}
if (moduleForShortcuts is not IPowerToysModuleShortcutsProvider shortcutsProvider)
{
Console.WriteLine("Module does not provide shortcuts. Aborting.");
return;
}
foreach (var shortcut in shortcutsProvider.Shortcuts)
{
Console.WriteLine("Shortcut: " + shortcut.Hotkey.ToString());
}
break;
case TrayButton.DebugFullModuleReport:
AllocConsole();
static string GpoRuleToString(GpoRuleConfigured g) => g switch
{
GpoRuleConfigured.WrongValue => "Wrong value",
GpoRuleConfigured.Unavailable => "Unavailable",
GpoRuleConfigured.NotConfigured => "Not configured",
GpoRuleConfigured.Disabled => "Disabled",
GpoRuleConfigured.Enabled => "Enabled",
_ => "Unknown",
};
Console.WriteLine("=============================");
Console.WriteLine("=Full report of all modules:=");
Console.WriteLine("=============================");
foreach (var module in Runner.ModulesToLoad)
{
Console.WriteLine("Module name: " + module.Name);
Console.WriteLine("Enabled: " + module.Enabled);
Console.WriteLine("GPO configured: " + GpoRuleToString(module.GpoRuleConfigured));
if (module is ProcessModuleAbstractClass pmac)
{
Console.WriteLine("Process name: " + pmac.ProcessName);
Console.WriteLine("Process path: " + pmac.ProcessPath);
Console.WriteLine("Launch options: " + pmac.LaunchOptions);
Console.WriteLine("Launch arguments: " + pmac.ProcessArguments);
Console.WriteLine("Is running: " + pmac.IsProcessRunning());
}
if (module is IPowerToysModuleCustomActionsProvider ptmcap)
{
Console.WriteLine("Custom actions: " + string.Join(", ", ptmcap.CustomActions.Keys));
}
if (module is IPowerToysModuleShortcutsProvider ptmscp)
{
Console.WriteLine("Shortcuts: " + string.Join(", ", ptmscp.Shortcuts.Select(s => s.Hotkey.ToString())));
}
Console.WriteLine("Is subscribed to settings changes: " + (module is IPowerToysModuleSettingsChangedSubscriber));
Console.WriteLine("-----------------------------");
}
break;
#endif
}
}
}

View File

@@ -96,6 +96,11 @@ namespace RunnerV2.Models
/// </summary>
public abstract ProcessLaunchOptions LaunchOptions { get; }
public bool IsProcessRunning()
{
return Process.GetProcessesByName(ProcessName).Length > 0;
}
/// <summary>
/// Ensures that atleast one process is launched. If the process is already running, does nothing.
/// </summary>

View File

@@ -224,7 +224,6 @@ namespace RunnerV2.ModuleInterfaces
string kindPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap";
changes.Add(new RegistryValueChange
{
Scope = Microsoft.Win32.RegistryHive.LocalMachine,
KeyPath = kindPath,
KeyName = fileType,
Value = fileKindType,
@@ -276,7 +275,6 @@ namespace RunnerV2.ModuleInterfaces
changes.Add(new RegistryValueChange
{
Scope = Microsoft.Win32.RegistryHive.LocalMachine,
KeyPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
KeyName = handlerClsid,
Value = displayName,

View File

@@ -33,14 +33,20 @@ namespace RunnerV2.ModuleInterfaces
var thread = new Thread(() =>
{
uint version = 0x00010008;
int hr = MddBootstrapInitialize(version, 0, IntPtr.Zero);
if (hr < 0)
try
{
throw new InvalidOperationException($"Windows app sdk could not be initialized for MouseJump. HR code:{hr}");
}
uint version = 0x00010008;
int hr = MddBootstrapInitialize(version, 0, IntPtr.Zero);
if (hr < 0)
{
throw new InvalidOperationException($"Windows app sdk could not be initialized for MouseJump. HR code:{hr}");
}
FindMyMouseMain();
FindMyMouseMain();
}
catch
{
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;
@@ -11,8 +12,10 @@ using RunnerV2.Models;
namespace RunnerV2.ModuleInterfaces
{
internal sealed class KeyboardManagerModuleInterface : ProcessModuleAbstractClass, IPowerToysModule
internal sealed class KeyboardManagerModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IPowerToysModuleShortcutsProvider, IPowerToysModuleSettingsChangedSubscriber
{
private bool isRunning;
public string Name => "Keyboard Manager";
public bool Enabled => SettingsUtils.Default.GetSettings<GeneralSettings>().Enabled.KeyboardManager;
@@ -25,14 +28,46 @@ namespace RunnerV2.ModuleInterfaces
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument | ProcessLaunchOptions.RealtimePriority;
public List<(HotkeySettings, Action)> Shortcuts { get; } = [];
private void InitializeShortcuts()
{
Shortcuts.Clear();
Shortcuts.Add((SettingsUtils.Default.GetSettings<KeyboardManagerSettings>(Name).Properties.ToggleShortcut, () =>
{
if (isRunning)
{
Disable();
}
else
{
Enable();
}
}
));
}
public void Disable()
{
isRunning = false;
using var terminateEvent = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.TerminateKBMSharedEvent());
terminateEvent.Set();
}
public void Enable()
{
InitializeShortcuts();
if (!isRunning)
{
isRunning = true;
InitializeShortcuts();
EnsureLaunched();
}
}
public void OnSettingsChanged()
{
InitializeShortcuts();
}
}
}

View File

@@ -12,7 +12,7 @@ using RunnerV2.Models;
namespace RunnerV2.ModuleInterfaces
{
internal sealed class PowerToysRunModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IPowerToysModuleShortcutsProvider
internal sealed class PowerToysRunModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IPowerToysModuleShortcutsProvider, IPowerToysModuleSettingsChangedSubscriber
{
public string Name => "PowerToys Run";
@@ -38,9 +38,15 @@ namespace RunnerV2.ModuleInterfaces
{
}
public void OnSettingsChanged()
{
using var settingsChangedEvent = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, Constants.RunSendSettingsTelemetryEvent());
settingsChangedEvent.Set();
}
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts =>
[
(
/*(
SettingsUtils.Default.GetSettings<PowerLauncherSettings>(Name).Properties.OpenPowerLauncher,
() =>
{
@@ -48,7 +54,7 @@ namespace RunnerV2.ModuleInterfaces
using var invokeRunEvent = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, Constants.PowerLauncherCentralizedHookSharedEvent());
invokeRunEvent.Set();
}
),
),*/
];
}
}

View File

@@ -52,6 +52,9 @@ namespace RunnerV2
[LibraryImport("user32.dll", SetLastError = true)]
internal static partial IntPtr CreatePopupMenu();
[LibraryImport("user32.dll", SetLastError = true)]
internal static partial IntPtr CreateMenu();
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static partial IntPtr FindWindowW(string lpClassName, string lpWindowName);
@@ -342,5 +345,12 @@ namespace RunnerV2
[MarshalAs(UnmanagedType.LPWStr)]
public string lpDisplayName;
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AllocConsole();
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
internal static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
}
}

View File

@@ -30,6 +30,8 @@ namespace RunnerV2
/// </summary>
public static nint RunnerHwnd { get; private set; }
public static bool DebbugingLogUncaughtExceptions { get; set; }
public const string TrayWindowClassName = "pt_tray_icon_window_class";
/// <summary>
@@ -142,6 +144,10 @@ namespace RunnerV2
catch (Exception e)
{
Logger.LogError("Uncaught error in message loop: ", e);
if (DebbugingLogUncaughtExceptions)
{
Console.WriteLine("Uncaught error in message loop: " + e.Message + "\n" + e.StackTrace);
}
}
// Supress duplicate handling of HOTKEY messages
@@ -157,6 +163,10 @@ namespace RunnerV2
catch (Exception e)
{
Logger.LogError("Uncaught error in message handling: ", e);
if (DebbugingLogUncaughtExceptions)
{
Console.WriteLine("Uncaught error in message loop: " + e.Message + "\n" + e.StackTrace);
}
}
}
@@ -321,6 +331,8 @@ namespace RunnerV2
}
}
private static bool _trayMenuCommandProcessed;
/// <summary>
/// Handles Windows messages sent to the tray window.
/// </summary>
@@ -332,6 +344,13 @@ namespace RunnerV2
TrayIconManager.ProcessTrayIconMessage(lParam);
break;
case (uint)WindowMessages.COMMAND:
if (_trayMenuCommandProcessed)
{
_trayMenuCommandProcessed = false;
break;
}
_trayMenuCommandProcessed = true;
TrayIconManager.ProcessTrayMenuCommand((nuint)wParam);
break;
case (uint)WindowMessages.WINDOWPOSCHANGING:

View File

@@ -66,6 +66,15 @@ namespace winrt::PowerToys::Interop::implementation
{
if (nCode == HC_ACTION)
{
const auto* info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
// Don't swallow injected keys (e.g., SendInput / KEYEVENTF_UNICODE from modules like PowerAccent).
// Let them propagate normally.
if ((info->flags & LLKHF_INJECTED) != 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
std::vector<KeyboardHook*> instances_copy;
{
/* Use a copy of instances, to iterate through the copy without needing to maintain the lock */

View File

@@ -188,6 +188,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Helpers
MouseWithoutBordersSettings.ModuleName => ModuleType.MouseWithoutBorders,
NewPlusSettings.ModuleName => ModuleType.NewPlus,
PeekSettings.ModuleName => ModuleType.Peek,
PowerDisplaySettings.ModuleName => ModuleType.PowerDisplay,
PowerRenameSettings.ModuleName => ModuleType.PowerRename,
PowerLauncherSettings.ModuleName => ModuleType.PowerLauncher,
PowerAccentSettings.ModuleName => ModuleType.PowerAccent,

View File

@@ -5809,4 +5809,7 @@ Text uses the current drawing color.</value>
<data name="ZoomIt_Type_DemoSample.Text" xml:space="preserve">
<value>Sample</value>
</data>
<data name="Default_language" xml:space="preserve">
<value>Default</value>
</data>
</root>