mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-07 03:36:44 +02:00
[Settings/Run] LowLevel Keyboard hooking for Hotkeys (#3825)
* [Launcher/Settings] Low Level Keyboard Hooks * [Run] LowLevel Keyboard Hook for Hotkeys * Prevent shortcuts from auto repeating when keeping the keys pressed down
This commit is contained in:
committed by
GitHub
parent
fa7e4cc817
commit
670033c4da
@@ -1,19 +0,0 @@
|
||||
<UserControl x:Class="Wox.HotkeyControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
|
||||
mc:Ignorable="d"
|
||||
Height="24"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="120" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="tbHotkey" TabIndex="100" VerticalContentAlignment="Center" Grid.Column="0"
|
||||
PreviewKeyDown="TbHotkey_OnPreviewKeyDown" input:InputMethod.IsInputMethodEnabled="False"/>
|
||||
<TextBlock x:Name="tbMsg" Visibility="Hidden" Margin="5 0 0 0" VerticalAlignment="Center" Grid.Column="1" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,117 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using NHotkey.Wpf;
|
||||
using Wox.Core.Resource;
|
||||
using Wox.Infrastructure.Hotkey;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class HotkeyControl : UserControl
|
||||
{
|
||||
public HotkeyModel CurrentHotkey { get; private set; }
|
||||
public bool CurrentHotkeyAvailable { get; private set; }
|
||||
|
||||
public event EventHandler HotkeyChanged;
|
||||
|
||||
protected virtual void OnHotkeyChanged()
|
||||
{
|
||||
EventHandler handler = HotkeyChanged;
|
||||
if (handler != null) handler(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public HotkeyControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void TbHotkey_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
tbMsg.Visibility = Visibility.Hidden;
|
||||
|
||||
//when alt is pressed, the real key should be e.SystemKey
|
||||
Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
|
||||
|
||||
SpecialKeyState specialKeyState = GlobalHotkey.Instance.CheckModifiers();
|
||||
|
||||
var hotkeyModel = new HotkeyModel(
|
||||
specialKeyState.AltPressed,
|
||||
specialKeyState.ShiftPressed,
|
||||
specialKeyState.WinPressed,
|
||||
specialKeyState.CtrlPressed,
|
||||
key);
|
||||
|
||||
var hotkeyString = hotkeyModel.ToString();
|
||||
|
||||
if (hotkeyString == tbHotkey.Text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
await Task.Delay(500);
|
||||
SetHotkey(hotkeyModel);
|
||||
});
|
||||
}
|
||||
|
||||
public void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
|
||||
{
|
||||
CurrentHotkey = keyModel;
|
||||
|
||||
tbHotkey.Text = CurrentHotkey.ToString();
|
||||
tbHotkey.Select(tbHotkey.Text.Length, 0);
|
||||
|
||||
if (triggerValidate)
|
||||
{
|
||||
CurrentHotkeyAvailable = CheckHotkeyAvailability();
|
||||
if (!CurrentHotkeyAvailable)
|
||||
{
|
||||
tbMsg.Foreground = new SolidColorBrush(Colors.Red);
|
||||
tbMsg.Text = InternationalizationManager.Instance.GetTranslation("hotkeyUnavailable");
|
||||
}
|
||||
else
|
||||
{
|
||||
tbMsg.Foreground = new SolidColorBrush(Colors.Green);
|
||||
tbMsg.Text = InternationalizationManager.Instance.GetTranslation("success");
|
||||
}
|
||||
tbMsg.Visibility = Visibility.Visible;
|
||||
OnHotkeyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHotkey(string keyStr, bool triggerValidate = true)
|
||||
{
|
||||
SetHotkey(new HotkeyModel(keyStr), triggerValidate);
|
||||
}
|
||||
|
||||
private bool CheckHotkeyAvailability()
|
||||
{
|
||||
try
|
||||
{
|
||||
HotkeyManager.Current.AddOrReplace("HotkeyAvailabilityTest", CurrentHotkey.CharKey, CurrentHotkey.ModifierKeys, (sender, e) => { });
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
HotkeyManager.Current.Remove("HotkeyAvailabilityTest");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public new bool IsFocused
|
||||
{
|
||||
get { return tbHotkey.IsFocused; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,6 @@
|
||||
<PackageReference Include="Mages" Version="1.6.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="NHotkey.Wpf" Version="2.0.1" />
|
||||
<PackageReference Include="NuGet.CommandLine" Version="5.5.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace PowerLauncher
|
||||
var openPowerlauncher = ConvertHotkey(overloadSettings.properties.open_powerlauncher);
|
||||
if (_settings.Hotkey != openPowerlauncher)
|
||||
{
|
||||
_settings.Hotkey = ConvertHotkey(overloadSettings.properties.open_powerlauncher);
|
||||
_settings.Hotkey = openPowerlauncher;
|
||||
}
|
||||
|
||||
var shell = PluginManager.AllPlugins.Find(pp => pp.Metadata.Name == "Shell");
|
||||
|
||||
Reference in New Issue
Block a user