[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:
Tomas Agustin Raies
2020-06-11 12:59:36 -07:00
committed by GitHub
parent fa7e4cc817
commit 670033c4da
28 changed files with 584 additions and 546 deletions

View File

@@ -7,8 +7,6 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using NHotkey;
using NHotkey.Wpf;
using Wox.Core.Plugin;
using Wox.Core.Resource;
using Wox.Helper;
@@ -20,6 +18,7 @@ using Wox.Plugin;
using Microsoft.PowerLauncher.Telemetry;
using Wox.Storage;
using Microsoft.PowerToys.Telemetry;
using interop;
namespace Wox.ViewModel
{
@@ -42,7 +41,8 @@ namespace Wox.ViewModel
private CancellationTokenSource _updateSource;
private CancellationToken _updateToken;
private bool _saved;
private HotkeyManager _hotkeyManager;
private ushort _hotkeyHandle;
private readonly Internationalization _translator = InternationalizationManager.Instance;
#endregion
@@ -51,6 +51,7 @@ namespace Wox.ViewModel
public MainViewModel(Settings settings)
{
_hotkeyManager = new HotkeyManager();
_saved = false;
_queryTextBeforeLeaveResults = "";
_lastQuery = new Query();
@@ -80,7 +81,7 @@ namespace Wox.ViewModel
{
if (_settings.PreviousHotkey != "")
{
RemoveHotkey(_settings.PreviousHotkey);
_hotkeyManager.UnregisterHotkey(_hotkeyHandle);
}
if (_settings.Hotkey != "")
@@ -111,6 +112,13 @@ namespace Wox.ViewModel
}
}
~MainViewModel()
{
if (_hotkeyHandle != 0)
{
_hotkeyManager.UnregisterHotkey(_hotkeyHandle);
}
}
private void InitializeKeyCommands()
{
@@ -186,11 +194,11 @@ namespace Wox.ViewModel
{
MainWindowVisibility = Visibility.Collapsed;
Task.Run(() =>
Application.Current.Dispatcher.Invoke(() =>
{
result.Action(new ActionContext
{
SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
SpecialKeyState = KeyboardHelper.CheckModifiers()
});
});
@@ -524,18 +532,25 @@ namespace Wox.ViewModel
}
#region Hotkey
private void SetHotkey(string hotkeyStr, EventHandler<HotkeyEventArgs> action)
private void SetHotkey(string hotkeyStr, HotkeyCallback action)
{
var hotkey = new HotkeyModel(hotkeyStr);
SetHotkey(hotkey, action);
}
private void SetHotkey(HotkeyModel hotkey, EventHandler<HotkeyEventArgs> action)
private void SetHotkey(HotkeyModel hotkeyModel, HotkeyCallback action)
{
string hotkeyStr = hotkey.ToString();
string hotkeyStr = hotkeyModel.ToString();
try
{
HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action);
Hotkey hotkey = new Hotkey();
hotkey.Alt = hotkeyModel.Alt;
hotkey.Shift = hotkeyModel.Shift;
hotkey.Ctrl = hotkeyModel.Ctrl;
hotkey.Win = hotkeyModel.Win;
hotkey.Key = (byte) KeyInterop.VirtualKeyFromKey(hotkeyModel.CharKey);
_hotkeyHandle = _hotkeyManager.RegisterHotkey(hotkey, action);
}
catch (Exception)
{
@@ -545,14 +560,6 @@ namespace Wox.ViewModel
}
}
public void RemoveHotkey(string hotkeyStr)
{
if (!string.IsNullOrEmpty(hotkeyStr))
{
HotkeyManager.Current.Remove(hotkeyStr);
}
}
/// <summary>
/// Checks if Wox should ignore any hotkeys
/// </summary>
@@ -572,7 +579,7 @@ namespace Wox.ViewModel
if (_settings.CustomPluginHotkeys == null) return;
foreach (CustomPluginHotkey hotkey in _settings.CustomPluginHotkeys)
{
SetHotkey(hotkey.Hotkey, (s, e) =>
SetHotkey(hotkey.Hotkey, () =>
{
if (ShouldIgnoreHotkeys()) return;
MainWindowVisibility = Visibility.Visible;
@@ -581,31 +588,33 @@ namespace Wox.ViewModel
}
}
private void OnHotkey(object sender, HotkeyEventArgs e)
private void OnHotkey()
{
if (!ShouldIgnoreHotkeys())
Application.Current.Dispatcher.Invoke(() =>
{
if (!ShouldIgnoreHotkeys())
{
if (_settings.LastQueryMode == LastQueryMode.Empty)
{
ChangeQueryText(string.Empty);
}
else if (_settings.LastQueryMode == LastQueryMode.Preserved)
{
LastQuerySelected = true;
}
else if (_settings.LastQueryMode == LastQueryMode.Selected)
{
LastQuerySelected = false;
}
else
{
throw new ArgumentException($"wrong LastQueryMode: <{_settings.LastQueryMode}>");
}
if (_settings.LastQueryMode == LastQueryMode.Empty)
{
ChangeQueryText(string.Empty);
}
else if (_settings.LastQueryMode == LastQueryMode.Preserved)
{
LastQuerySelected = true;
}
else if (_settings.LastQueryMode == LastQueryMode.Selected)
{
LastQuerySelected = false;
}
else
{
throw new ArgumentException($"wrong LastQueryMode: <{_settings.LastQueryMode}>");
}
ToggleWox();
e.Handled = true;
}
ToggleWox();
}
});
}
private void ToggleWox()

View File

@@ -7,11 +7,10 @@ using System.Windows.Input;
using System.Windows.Media;
using Wox.Core.Plugin;
using Wox.Infrastructure;
using Wox.Infrastructure.Hotkey;
using Wox.Infrastructure.Image;
using Wox.Infrastructure.Logger;
using Wox.Plugin;
using Wox.Helper;
namespace Wox.ViewModel
{
@@ -128,7 +127,7 @@ namespace Wox.ViewModel
{
bool hideWindow = r.Action != null && r.Action(new ActionContext
{
SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
SpecialKeyState = KeyboardHelper.CheckModifiers()
});
if (hideWindow)