diff --git a/src/RunnerV2/RunnerV2/Helpers/COMUtils.cs b/src/RunnerV2/RunnerV2/Helpers/COMUtils.cs new file mode 100644 index 0000000000..f86d32f28a --- /dev/null +++ b/src/RunnerV2/RunnerV2/Helpers/COMUtils.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace RunnerV2.Helpers +{ + internal static class COMUtils + { + public static void InitializeCOMSecurity(string securityDescriptor) + { + if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW( + securityDescriptor, + 1, + out IntPtr pSD, + out _)) + { + return; + } + + uint absoluteSDSize = 0; + uint daclSize = 0; + uint groupSize = 0; + uint ownerSize = 0; + uint saclSize = 0; + + if (!NativeMethods.MakeAbsoluteSD(pSD, IntPtr.Zero, ref absoluteSDSize, IntPtr.Zero, ref daclSize, IntPtr.Zero, ref saclSize, IntPtr.Zero, ref ownerSize, IntPtr.Zero, ref groupSize)) + { + return; + } + + IntPtr absoluteSD = Marshal.AllocHGlobal((int)absoluteSDSize); + IntPtr dacl = Marshal.AllocHGlobal((int)daclSize); + IntPtr sacl = Marshal.AllocHGlobal((int)saclSize); + IntPtr owner = Marshal.AllocHGlobal((int)ownerSize); + IntPtr group = Marshal.AllocHGlobal((int)groupSize); + + if (!NativeMethods.MakeAbsoluteSD(pSD, absoluteSD, ref absoluteSDSize, dacl, ref daclSize, sacl, ref saclSize, owner, ref ownerSize, group, ref groupSize)) + { + return; + } + + _ = NativeMethods.CoInitializeSecurity( + absoluteSD, + -1, + IntPtr.Zero, + IntPtr.Zero, + 6, // RPC_C_AUTHN_LEVEL_PKT_PRIVACY + 2, // RPC_C_IMP_LEVEL_IDENTIFY + IntPtr.Zero, + 64 | 4096, // EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA + IntPtr.Zero); + } + } +} diff --git a/src/RunnerV2/RunnerV2/Helpers/CentralizedKeyboardHookManager.cs b/src/RunnerV2/RunnerV2/Helpers/CentralizedKeyboardHookManager.cs new file mode 100644 index 0000000000..d56a7c53a1 --- /dev/null +++ b/src/RunnerV2/RunnerV2/Helpers/CentralizedKeyboardHookManager.cs @@ -0,0 +1,169 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Microsoft.PowerToys.Settings.UI.Helpers; +using Microsoft.PowerToys.Settings.UI.Library; +using Windows.System; + +namespace RunnerV2.Helpers +{ + internal static class CentralizedKeyboardHookManager + { + private static readonly UIntPtr _ignoreKeyEventFlag = 0x5555; + + private static readonly Dictionary> _keyboardHooks = []; + + private static HotkeySettingsControlHook _hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag); + + private static void OnKeyDown(int key) + { + switch ((VirtualKey)key) + { + case VirtualKey.Control: + case VirtualKey.LeftControl: + case VirtualKey.RightControl: + _ctrlState = true; + break; + case VirtualKey.Menu: + case VirtualKey.LeftMenu: + case VirtualKey.RightMenu: + _altState = true; + break; + case VirtualKey.Shift: + case VirtualKey.LeftShift: + case VirtualKey.RightShift: + _shiftState = true; + break; + case VirtualKey.LeftWindows: + case VirtualKey.RightWindows: + _winState = true; + break; + } + + SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyDown); + } + + private static void OnKeyUp(int key) + { + switch ((VirtualKey)key) + { + case VirtualKey.Control: + case VirtualKey.LeftControl: + case VirtualKey.RightControl: + _ctrlState = false; + break; + case VirtualKey.Menu: + case VirtualKey.LeftMenu: + case VirtualKey.RightMenu: + _altState = false; + break; + case VirtualKey.Shift: + case VirtualKey.LeftShift: + case VirtualKey.RightShift: + _shiftState = false; + break; + case VirtualKey.LeftWindows: + case VirtualKey.RightWindows: + _winState = false; + break; + default: + OnKeyboardEvent(new HotkeySettings + { + Code = key, + Ctrl = _ctrlState, + Alt = _altState, + Shift = _shiftState, + Win = _winState, + }); + break; + } + + SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyUp); + } + + private static bool _ctrlState; + private static bool _altState; + private static bool _shiftState; + private static bool _winState; + + private static bool _isActive; + + private static bool IsActive() + { + return _isActive; + } + + public static void AddKeyboardHook(string moduleName, HotkeySettings hotkeySettings, Action action) + { +#pragma warning disable CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method + if (!_keyboardHooks.ContainsKey(moduleName)) + { + _keyboardHooks[moduleName] = []; + } +#pragma warning restore CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method + + _keyboardHooks[moduleName].Add((hotkeySettings, action)); + } + + public static void RemoveAllHooksFromModule(string moduleName) + { + _keyboardHooks.Remove(moduleName); + } + + private static void OnKeyboardEvent(HotkeySettings pressedHotkey) + { + foreach (var moduleHooks in _keyboardHooks.Values) + { + foreach (var (hotkeySettings, action) in moduleHooks) + { + if (hotkeySettings == pressedHotkey) + { + action(); + } + } + } + } + + public static void Start() + { + if (_hotkeySettingsControlHook.GetDisposedState()) + { + _hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag); + } + + _isActive = true; + } + + public static void Stop() + { + _isActive = false; + _hotkeySettingsControlHook.Dispose(); + } + + // 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() + { + type = NativeKeyboardHelper.INPUTTYPE.INPUT_KEYBOARD, + data = new NativeKeyboardHelper.InputUnion + { + ki = new NativeKeyboardHelper.KEYBDINPUT + { + wVk = keyCode, + dwFlags = keyStatus, + dwExtraInfo = _ignoreKeyEventFlag, + }, + }, + }; + + NativeKeyboardHelper.INPUT[] inputs = [inputShift]; + + _ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size); + } + } +} diff --git a/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs b/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs index 61567ca4c2..072d2b4ba6 100644 --- a/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs +++ b/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs @@ -14,6 +14,7 @@ using System.Threading; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using PowerToys.Interop; +using RunnerV2.ModuleInterfaces; using Update; using Windows.Media.Devices; diff --git a/src/RunnerV2/RunnerV2/ModuleInterfaces/AdvancedPasteModuleInterface.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/AdvancedPasteModuleInterface.cs new file mode 100644 index 0000000000..e5d5942f51 --- /dev/null +++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/AdvancedPasteModuleInterface.cs @@ -0,0 +1,112 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +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; +using PowerToys.Interop; + +namespace RunnerV2.ModuleInterfaces +{ + internal sealed class AdvancedPasteModuleInterface : IPowerToysModule, IDisposable + { + public string Name => "AdvancedPaste"; + + public bool Enabled => new SettingsUtils().GetSettings().Enabled.AdvancedPaste; + + public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAdvancedPasteEnabledValue(); + + public void Disable() + { + if (_ipc != null) + { + _ipc.Send("TerminateApp"); + _ipc.End(); + _ipc = null; + } + + Task.Run(async () => + { + await Task.Delay(500); + foreach (var process in Process.GetProcessesByName("PowerToys.AdvancedPaste.exe")) + { + process.Kill(); + } + }); + } + + private TwoWayPipeMessageIPCManaged? _ipc; + + public void Enable() + { + if (Process.GetProcessesByName("PowerToys.AdvancedPaste.exe").Length > 0) + { + return; + } + + string ipcName = @"\\.\pipe\PowerToys.AdvancedPaste"; + _ipc = new TwoWayPipeMessageIPCManaged(string.Empty, ipcName, (_) => { }); + _ipc.Start(); + + if (Shortcuts.Count == 0) + { + PopulateShortcuts(); + } + + Process.Start("WinUI3Apps\\PowerToys.AdvancedPaste.exe", $"{Environment.ProcessId} {ipcName}"); + } + + public void OnSettingsChanged() + { + PopulateShortcuts(); + } + + public void PopulateShortcuts() + { + ArgumentNullException.ThrowIfNull(_ipc); + + Shortcuts.Clear(); + + AdvancedPasteSettings settings = new SettingsUtils().GetSettings(); + Shortcuts.Add((settings.Properties.AdvancedPasteUIShortcut, () => + _ipc.Send("ShowUI") + )); + Shortcuts.Add((settings.Properties.PasteAsPlainTextShortcut, TryToPasteAsPlainText)); + Shortcuts.Add((settings.Properties.PasteAsMarkdownShortcut, () => _ipc.Send("PasteMarkdown"))); + Shortcuts.Add((settings.Properties.PasteAsJsonShortcut, () => _ipc.Send("PasteJson"))); + + HotkeyAccessor[] hotkeyAccessors = settings.GetAllHotkeyAccessors(); + for (int i = 4; i < hotkeyAccessors.Length; i++) + { + HotkeyAccessor hotkeyAccessor = hotkeyAccessors[i]; + Shortcuts.Add((hotkeyAccessor.Value, () => _ipc.Send($"CustomPaste {i}"))); + } + } + + private void TryToPasteAsPlainText() + { + if (Clipboard.ContainsText()) + { + string text = Clipboard.GetText(); + SendKeys.SendWait(text); + } + + throw new NotImplementedException(); + } + + public void Dispose() + { + _ipc?.Dispose(); + } + + public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = []; + } +} diff --git a/src/RunnerV2/RunnerV2/ModuleInterfaces/HostsModuleInterface.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/HostsModuleInterface.cs index ae69334e6d..8facc738d8 100644 --- a/src/RunnerV2/RunnerV2/ModuleInterfaces/HostsModuleInterface.cs +++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/HostsModuleInterface.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using PowerToys.GPOWrapper; diff --git a/src/common/ManagedCommon/IPowerToysModule.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/IPowerToysModule.cs similarity index 80% rename from src/common/ManagedCommon/IPowerToysModule.cs rename to src/RunnerV2/RunnerV2/ModuleInterfaces/IPowerToysModule.cs index 6b550df469..e4498fa196 100644 --- a/src/common/ManagedCommon/IPowerToysModule.cs +++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/IPowerToysModule.cs @@ -5,9 +5,11 @@ using System; using System.Collections.Generic; using System.Text.Json; +using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library; using PowerToys.GPOWrapper; -namespace ManagedCommon +namespace RunnerV2.ModuleInterfaces { public interface IPowerToysModule { @@ -23,6 +25,8 @@ namespace ManagedCommon public Dictionary Hotkeys { get => []; } + public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get => []; } + public Dictionary CustomActions { get => []; } public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties) diff --git a/src/RunnerV2/RunnerV2/ModuleInterfaces/PowerAccentModuleInterface.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/PowerAccentModuleInterface.cs index 6b1722ecac..9531384741 100644 --- a/src/RunnerV2/RunnerV2/ModuleInterfaces/PowerAccentModuleInterface.cs +++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/PowerAccentModuleInterface.cs @@ -3,13 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using PowerToys.GPOWrapper; diff --git a/src/RunnerV2/RunnerV2/NativeMethods.cs b/src/RunnerV2/RunnerV2/NativeMethods.cs index 0c412b1a94..bb08c06aa0 100644 --- a/src/RunnerV2/RunnerV2/NativeMethods.cs +++ b/src/RunnerV2/RunnerV2/NativeMethods.cs @@ -5,6 +5,7 @@ using System; using System.Drawing; using System.Runtime.InteropServices; +using Microsoft.PowerToys.Settings.UI.Helpers; namespace RunnerV2 { @@ -186,5 +187,48 @@ namespace RunnerV2 [MarshalAs(UnmanagedType.LPWStr)] public string LpszClassName; } + + [DllImport("user32.dll", SetLastError = true)] + internal static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); + + internal delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("Advapi32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptorW( + [MarshalAs(UnmanagedType.LPWStr)] string StringSecurityDescriptor, + uint StringSDRevision, + out IntPtr SecurityDescriptor, + out uint SecurityDescriptorSize); + + [DllImport("Advapi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool MakeAbsoluteSD( + IntPtr pSelfRelativeSD, + IntPtr pAbsoluteSD, + ref uint lpdwAbsoluteSDSize, + IntPtr pDacl, + ref uint lpdwDaclSize, + IntPtr pSacl, + ref uint lpdwSaclSize, + IntPtr pOwner, + ref uint lpdwOwnerSize, + IntPtr pPrimaryGroup, + ref uint lpdwPrimaryGroupSize); + + [DllImport("ole32.dll", SetLastError = true)] + internal static extern int CoInitializeSecurity( + IntPtr pSecDesc, + int cAuthSvc, + IntPtr asAuthSvc, + IntPtr pReserved1, + uint dwAuthnLevel, + uint dwImpLevel, + IntPtr pAuthList, + uint dwCapabilities, + IntPtr pReserved3); + + [DllImport("user32.dll")] + internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize); } } diff --git a/src/RunnerV2/RunnerV2/Program.cs b/src/RunnerV2/RunnerV2/Program.cs index 951a766698..e005b1968c 100644 --- a/src/RunnerV2/RunnerV2/Program.cs +++ b/src/RunnerV2/RunnerV2/Program.cs @@ -22,6 +22,20 @@ internal sealed class Program private static void Main(string[] args) { + string securityDescriptor = + "O:BA" // Owner: Builtin (local) administrator + + "G:BA" // Group: Builtin (local) administrator + + "D:" + + "(A;;0x7;;;PS)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self + + "(A;;0x7;;;IU)" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users + + "(A;;0x3;;;SY)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system + + "(A;;0x7;;;BA)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator + + "(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability + + "S:" + + "(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level + + COMUtils.InitializeCOMSecurity(securityDescriptor); + switch (ShouldRunInSpecialMode(args)) { case SpecialMode.None: diff --git a/src/RunnerV2/RunnerV2/Runner.cs b/src/RunnerV2/RunnerV2/Runner.cs index 251a28169d..e30bc3a23d 100644 --- a/src/RunnerV2/RunnerV2/Runner.cs +++ b/src/RunnerV2/RunnerV2/Runner.cs @@ -15,8 +15,8 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using ManagedCommon; using RunnerV2.Helpers; +using RunnerV2.ModuleInterfaces; using Update; using static RunnerV2.NativeMethods; @@ -28,11 +28,6 @@ namespace RunnerV2 private const string TrayWindowClassName = "pt_tray_icon_window_class"; - static Runner() - { - InitializeTrayWindow(); - } - public static List LoadedModules { get; } = []; public static FrozenSet ModulesToLoad { get; } = @@ -40,10 +35,12 @@ namespace RunnerV2 new ModuleInterfaces.AlwaysOnTopModuleInterface(), new ModuleInterfaces.HostsModuleInterface(), new ModuleInterfaces.PowerAccentModuleInterface(), + new ModuleInterfaces.AdvancedPasteModuleInterface(), ]; internal static bool Run(Action afterInitializationAction) { + InitializeTrayWindow(); TrayIconManager.StartTrayIcon(); Task.Run(UpdateUtilities.UninstallPreviousMsixVersions); @@ -53,6 +50,8 @@ namespace RunnerV2 ToggleModuleStateBasedOnEnabledProperty(module); } + CentralizedKeyboardHookManager.Start(); + afterInitializationAction(); MessageLoop(); @@ -116,16 +115,23 @@ namespace RunnerV2 { /* Todo: conflict manager */ + if (!LoadedModules.Contains(module)) + { + module.Enable(); + LoadedModules.Add(module); + } + // ToArray is called to mitigate mutations while the foreach is executing foreach (var hotkey in module.Hotkeys.ToArray()) { HotkeyManager.EnableHotkey(hotkey.Key, hotkey.Value); } - if (!LoadedModules.Contains(module)) + CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name); + + foreach (var shortcut in module.Shortcuts.ToArray()) { - module.Enable(); - LoadedModules.Add(module); + CentralizedKeyboardHookManager.AddKeyboardHook(module.Name, shortcut.Hotkey, shortcut.Action); } return; @@ -149,6 +155,8 @@ namespace RunnerV2 HotkeyManager.DisableHotkey(hotkey.Key); } + CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name); + LoadedModules.Remove(module); } catch (IOException) diff --git a/src/RunnerV2/RunnerV2/RunnerV2.csproj b/src/RunnerV2/RunnerV2/RunnerV2.csproj index 6776e6acc1..c52cd30d2f 100644 --- a/src/RunnerV2/RunnerV2/RunnerV2.csproj +++ b/src/RunnerV2/RunnerV2/RunnerV2.csproj @@ -16,6 +16,7 @@ + diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj index 1c80479c2d..fd4a48b64d 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj @@ -25,13 +25,6 @@ DISABLE_XAML_GENERATED_MAIN,TRACE - - - PowerToys.GPOWrapper - $(OutDir) - false - - @@ -108,9 +101,9 @@ + - diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs index 3fa940952e..9dcd68c365 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPasteXAML/App.xaml.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO.Abstractions; using System.Linq; @@ -22,6 +23,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; +using PowerToys.Interop; using Windows.Graphics; using WinUIEx; @@ -132,47 +134,44 @@ namespace AdvancedPaste if (cmdArgs?.Length > 2) { - ProcessNamedPipe(cmdArgs[2]); + TwoWayPipeMessageIPCManaged ipc = new(cmdArgs[2], string.Empty, async (m) => await OnNamedPipeMessage(m)); + ipc.Start(); } } - private void ProcessNamedPipe(string pipeName) - { - void OnMessage(string message) => _dispatcherQueue.TryEnqueue(async () => await OnNamedPipeMessage(message)); - - Task.Run(async () => await NamedPipeProcessor.ProcessNamedPipeAsync(pipeName, connectTimeout: TimeSpan.FromSeconds(10), OnMessage, CancellationToken.None)); - } - private async Task OnNamedPipeMessage(string message) { - var messageParts = message.Split(); - var messageType = messageParts.First(); + _dispatcherQueue.TryEnqueue(async () => + { + var messageParts = message.Split(); + var messageType = messageParts.First(); - if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage()) - { - await ShowWindow(); - } - else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage()) - { - await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut); - } - else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage()) - { - await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut); - } - else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage()) - { - await OnAdvancedPasteAdditionalActionHotkey(messageParts); - } - else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage()) - { - await OnAdvancedPasteCustomActionHotkey(messageParts); - } - else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage()) - { - Dispose(); - Environment.Exit(0); - } + if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage()) + { + await ShowWindow(); + } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage()) + { + await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut); + } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage()) + { + await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut); + } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage()) + { + await OnAdvancedPasteAdditionalActionHotkey(messageParts); + } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage()) + { + await OnAdvancedPasteCustomActionHotkey(messageParts); + } + else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage()) + { + Dispose(); + Environment.Exit(0); + } + }); } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) diff --git a/src/settings-ui/Settings.UI/Helpers/NativeKeyboardHelper.cs b/src/settings-ui/Settings.UI/Helpers/NativeKeyboardHelper.cs index b9d32e25d3..43fb8aeb10 100644 --- a/src/settings-ui/Settings.UI/Helpers/NativeKeyboardHelper.cs +++ b/src/settings-ui/Settings.UI/Helpers/NativeKeyboardHelper.cs @@ -7,16 +7,16 @@ using System.Runtime.InteropServices; namespace Microsoft.PowerToys.Settings.UI.Helpers { - internal static class NativeKeyboardHelper + public static class NativeKeyboardHelper { [StructLayout(LayoutKind.Sequential)] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")] - internal struct INPUT + public struct INPUT { - internal INPUTTYPE type; - internal InputUnion data; + public INPUTTYPE type; + public InputUnion data; - internal static int Size + public static int Size { get { return Marshal.SizeOf(); } } @@ -24,49 +24,49 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers [StructLayout(LayoutKind.Explicit)] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")] - internal struct InputUnion + public struct InputUnion { [FieldOffset(0)] - internal MOUSEINPUT mi; + public MOUSEINPUT mi; [FieldOffset(0)] - internal KEYBDINPUT ki; + public KEYBDINPUT ki; [FieldOffset(0)] - internal HARDWAREINPUT hi; + public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")] - internal struct MOUSEINPUT + public struct MOUSEINPUT { - internal int dx; - internal int dy; - internal int mouseData; - internal uint dwFlags; - internal uint time; - internal UIntPtr dwExtraInfo; + public int dx; + public int dy; + public int mouseData; + public uint dwFlags; + public uint time; + public UIntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")] - internal struct KEYBDINPUT + public struct KEYBDINPUT { - internal short wVk; - internal short wScan; - internal uint dwFlags; - internal int time; - internal UIntPtr dwExtraInfo; + public short wVk; + public short wScan; + public uint dwFlags; + public int time; + public UIntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")] - internal struct HARDWAREINPUT + public struct HARDWAREINPUT { - internal int uMsg; - internal short wParamL; - internal short wParamH; + public int uMsg; + public short wParamL; + public short wParamH; } - internal enum INPUTTYPE : uint + public enum INPUTTYPE : uint { INPUT_MOUSE = 0, INPUT_KEYBOARD = 1, @@ -74,7 +74,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers } [Flags] - internal enum KeyEventF + public enum KeyEventF { KeyDown = 0x0000, ExtendedKey = 0x0001,