mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
Fix ctrl alt key in Keyboard Hook and Advanced Paste custom actions
This commit is contained in:
@@ -21,6 +21,11 @@ namespace RunnerV2.Helpers
|
||||
|
||||
private static void OnKeyDown(int key)
|
||||
{
|
||||
if ((VirtualKey)key == VirtualKey.RightMenu && _ctrlState)
|
||||
{
|
||||
_ctrlAltState = true;
|
||||
}
|
||||
|
||||
switch ((VirtualKey)key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
@@ -41,6 +46,20 @@ namespace RunnerV2.Helpers
|
||||
case VirtualKey.LeftWindows:
|
||||
case VirtualKey.RightWindows:
|
||||
_winState = true;
|
||||
break;
|
||||
default:
|
||||
if (OnKeyboardEvent(new HotkeySettings
|
||||
{
|
||||
Code = key,
|
||||
Ctrl = _ctrlState,
|
||||
Alt = _altState,
|
||||
Shift = _shiftState,
|
||||
Win = _winState,
|
||||
}))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -70,16 +89,15 @@ namespace RunnerV2.Helpers
|
||||
case VirtualKey.RightWindows:
|
||||
_winState = false;
|
||||
break;
|
||||
default:
|
||||
OnKeyboardEvent(new HotkeySettings
|
||||
{
|
||||
Code = key,
|
||||
Ctrl = _ctrlState,
|
||||
Alt = _altState,
|
||||
Shift = _shiftState,
|
||||
Win = _winState,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
// Correctly release Ctrl key if Ctrl+Alt (AltGr) was used.
|
||||
if (_ctrlAltState && (VirtualKey)key == VirtualKey.RightMenu)
|
||||
{
|
||||
_ctrlAltState = false;
|
||||
_ctrlState = false;
|
||||
|
||||
SendSingleKeyboardInput((short)VirtualKey.LeftControl, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
|
||||
}
|
||||
|
||||
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
|
||||
@@ -89,6 +107,7 @@ namespace RunnerV2.Helpers
|
||||
private static bool _altState;
|
||||
private static bool _shiftState;
|
||||
private static bool _winState;
|
||||
private static bool _ctrlAltState;
|
||||
|
||||
private static bool _isActive;
|
||||
|
||||
@@ -114,8 +133,10 @@ namespace RunnerV2.Helpers
|
||||
_keyboardHooks.Remove(moduleName);
|
||||
}
|
||||
|
||||
private static void OnKeyboardEvent(HotkeySettings pressedHotkey)
|
||||
private static bool OnKeyboardEvent(HotkeySettings pressedHotkey)
|
||||
{
|
||||
bool shortcutHandled = false;
|
||||
|
||||
foreach (var moduleHooks in _keyboardHooks.Values)
|
||||
{
|
||||
foreach (var (hotkeySettings, action) in moduleHooks)
|
||||
@@ -123,9 +144,12 @@ namespace RunnerV2.Helpers
|
||||
if (hotkeySettings == pressedHotkey)
|
||||
{
|
||||
action();
|
||||
shortcutHandled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return shortcutHandled;
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
@@ -147,7 +171,12 @@ namespace RunnerV2.Helpers
|
||||
// Function to send a single key event to the system which would be ignored by the hotkey control.
|
||||
private static void SendSingleKeyboardInput(short keyCode, uint keyStatus)
|
||||
{
|
||||
NativeKeyboardHelper.INPUT inputShift = new()
|
||||
if (IsExtendedVirtualKey(keyCode))
|
||||
{
|
||||
keyStatus |= (uint)NativeKeyboardHelper.KeyEventF.ExtendedKey;
|
||||
}
|
||||
|
||||
NativeKeyboardHelper.INPUT input = new()
|
||||
{
|
||||
type = NativeKeyboardHelper.INPUTTYPE.INPUT_KEYBOARD,
|
||||
data = new NativeKeyboardHelper.InputUnion
|
||||
@@ -161,9 +190,30 @@ namespace RunnerV2.Helpers
|
||||
},
|
||||
};
|
||||
|
||||
NativeKeyboardHelper.INPUT[] inputs = [inputShift];
|
||||
NativeKeyboardHelper.INPUT[] inputs = [input];
|
||||
|
||||
_ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size);
|
||||
}
|
||||
|
||||
private static bool IsExtendedVirtualKey(short vk)
|
||||
{
|
||||
return vk switch
|
||||
{
|
||||
0xA5 => true, // VK_RMENU (Right Alt - AltGr)
|
||||
0xA3 => true, // VK_RCONTROL
|
||||
0x2D => true, // VK_INSERT
|
||||
0x2E => true, // VK_DELETE
|
||||
0x23 => true, // VK_END
|
||||
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,10 +5,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using PowerToys.GPOWrapper;
|
||||
@@ -64,18 +64,21 @@ namespace RunnerV2.ModuleInterfaces
|
||||
Process.Start("WinUI3Apps\\PowerToys.AdvancedPaste.exe", $"{Environment.ProcessId} {ipcName}");
|
||||
}
|
||||
|
||||
public void OnSettingsChanged()
|
||||
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)
|
||||
{
|
||||
PopulateShortcuts();
|
||||
}
|
||||
|
||||
public void PopulateShortcuts()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_ipc);
|
||||
if (_ipc is null)
|
||||
{
|
||||
_ipc = new TwoWayPipeMessageIPCManaged(string.Empty, @"\\.\pipe\PowerToys.AdvancedPaste", (_) => { });
|
||||
}
|
||||
|
||||
Shortcuts.Clear();
|
||||
|
||||
AdvancedPasteSettings settings = new SettingsUtils().GetSettings<AdvancedPasteSettings>();
|
||||
AdvancedPasteSettings settings = new SettingsUtils().GetSettingsOrDefault<AdvancedPasteSettings>(Name);
|
||||
Shortcuts.Add((settings.Properties.AdvancedPasteUIShortcut, () =>
|
||||
_ipc.Send("ShowUI")
|
||||
));
|
||||
@@ -84,10 +87,17 @@ namespace RunnerV2.ModuleInterfaces
|
||||
Shortcuts.Add((settings.Properties.PasteAsJsonShortcut, () => _ipc.Send("PasteJson")));
|
||||
|
||||
HotkeyAccessor[] hotkeyAccessors = settings.GetAllHotkeyAccessors();
|
||||
for (int i = 4; i < hotkeyAccessors.Length; i++)
|
||||
int additionalActionsCount = settings.Properties.AdditionalActions.GetAllActions().Count() - 2;
|
||||
for (int i = 0; i < additionalActionsCount; i++)
|
||||
{
|
||||
HotkeyAccessor hotkeyAccessor = hotkeyAccessors[i];
|
||||
Shortcuts.Add((hotkeyAccessor.Value, () => _ipc.Send($"CustomPaste {i}")));
|
||||
int scopedI = i;
|
||||
Shortcuts.Add((hotkeyAccessors[4 + i].Value, () => _ipc.Send("AdditionalAction " + (3 + scopedI))));
|
||||
}
|
||||
|
||||
for (int i = 4 + additionalActionsCount; i < hotkeyAccessors.Length; i++)
|
||||
{
|
||||
int scopedI = i;
|
||||
Shortcuts.Add((hotkeyAccessors[i].Value, () => _ipc.Send("CustomAction " + (scopedI - 5 - additionalActionsCount))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using PowerToys.Interop;
|
||||
using Windows.Graphics;
|
||||
using WinRT;
|
||||
using WinUIEx;
|
||||
|
||||
using static AdvancedPaste.Helpers.NativeMethods;
|
||||
@@ -44,13 +45,6 @@ namespace AdvancedPaste
|
||||
|
||||
public ETWTrace EtwTrace { get; private set; } = new ETWTrace();
|
||||
|
||||
private static readonly Dictionary<string, PasteFormats> AdditionalActionIPCKeys =
|
||||
typeof(PasteFormats).GetFields()
|
||||
.Where(field => field.IsLiteral)
|
||||
.Select(field => (Format: (PasteFormats)field.GetRawConstantValue(), field.GetCustomAttribute<PasteFormatMetadataAttribute>().IPCKey))
|
||||
.Where(field => field.IPCKey != null)
|
||||
.ToDictionary(field => field.IPCKey, field => field.Format);
|
||||
|
||||
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
private readonly OptionsViewModel viewModel;
|
||||
|
||||
@@ -187,14 +181,14 @@ namespace AdvancedPaste
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!AdditionalActionIPCKeys.TryGetValue(messageParts[1], out PasteFormats pasteFormat))
|
||||
if (!int.TryParse(messageParts[1], CultureInfo.InvariantCulture, out int customActionId))
|
||||
{
|
||||
Logger.LogWarning($"Unexpected additional action type {messageParts[1]}");
|
||||
}
|
||||
else
|
||||
{
|
||||
await ShowWindow();
|
||||
await viewModel.ExecutePasteFormatAsync(pasteFormat, PasteActionSource.GlobalKeyboardShortcut);
|
||||
await viewModel.ExecutePasteFormatAsync((PasteFormats)customActionId, PasteActionSource.GlobalKeyboardShortcut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user