diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
index e92a93c12..3ea8915f7 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
@@ -9,13 +9,14 @@ namespace Flow.Launcher.Infrastructure.Hotkey
/// Listens keyboard globally.
/// Uses WH_KEYBOARD_LL.
///
- public class GlobalHotkey : IDisposable
+ public unsafe static class GlobalHotkey
{
- private static GlobalHotkey instance;
- private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
- private IntPtr hookId = IntPtr.Zero;
+ private static readonly IntPtr hookId;
+
+
+
public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
- public event KeyboardCallback hookedKeyboardCallback;
+ internal static Func hookedKeyboardCallback;
//Modifier key constants
private const int VK_SHIFT = 0x10;
@@ -23,27 +24,14 @@ namespace Flow.Launcher.Infrastructure.Hotkey
private const int VK_ALT = 0x12;
private const int VK_WIN = 91;
- public static GlobalHotkey Instance
+ static GlobalHotkey()
{
- get
- {
- if (instance == null)
- {
- instance = new GlobalHotkey();
- }
- return instance;
- }
- }
-
- private GlobalHotkey()
- {
- // We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
- hookedLowLevelKeyboardProc = LowLevelKeyboardProc;
// Set the hook
- hookId = InterceptKeys.SetHook(hookedLowLevelKeyboardProc);
+ hookId = InterceptKeys.SetHook(& LowLevelKeyboardProc);
+ AppDomain.CurrentDomain.ProcessExit += (_, _) => Dispose();
}
- public SpecialKeyState CheckModifiers()
+ public static SpecialKeyState CheckModifiers()
{
SpecialKeyState state = new SpecialKeyState();
if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0)
@@ -71,7 +59,7 @@ namespace Flow.Launcher.Infrastructure.Hotkey
}
[MethodImpl(MethodImplOptions.NoInlining)]
- private IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
+ private static IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
{
bool continues = true;
@@ -94,12 +82,7 @@ namespace Flow.Launcher.Infrastructure.Hotkey
return (IntPtr)1;
}
- ~GlobalHotkey()
- {
- Dispose();
- }
-
- public void Dispose()
+ public static void Dispose()
{
InterceptKeys.UnhookWindowsHookEx(hookId);
}
diff --git a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs b/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
index c45e685f3..7fec3c383 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
@@ -4,13 +4,13 @@ using System.Runtime.InteropServices;
namespace Flow.Launcher.Infrastructure.Hotkey
{
- internal static class InterceptKeys
+ internal static unsafe class InterceptKeys
{
public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
private const int WH_KEYBOARD_LL = 13;
- public static IntPtr SetHook(LowLevelKeyboardProc proc)
+ public static IntPtr SetHook(delegate* proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
@@ -20,7 +20,7 @@ namespace Flow.Launcher.Infrastructure.Hotkey
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
+ public static extern IntPtr SetWindowsHookEx(int idHook, delegate* lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index 2b6e275df..a20537e3a 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -33,7 +33,7 @@ namespace Flow.Launcher
//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();
+ SpecialKeyState specialKeyState = GlobalHotkey.CheckModifiers();
var hotkeyModel = new HotkeyModel(
specialKeyState.AltPressed,
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e90a53fc3..562db43f1 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -40,7 +40,7 @@ namespace Flow.Launcher
_settingsVM = settingsVM;
_mainVM = mainVM;
_alphabet = alphabet;
- GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
+ GlobalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index d7bbaf1cd..9d6b124a0 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -227,7 +227,7 @@ namespace Flow.Launcher.ViewModel
{
bool hideWindow = result.Action != null && result.Action(new ActionContext
{
- SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
+ SpecialKeyState = GlobalHotkey.CheckModifiers()
});
if (hideWindow)