mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
Fix some bugs and add debug menu
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
),
|
||||
),*/
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user