1- using System ;
1+ using System ;
2+ using System . Diagnostics ;
23using System . Runtime . InteropServices ;
34using Flow . Launcher . Plugin ;
5+ using Windows . Win32 ;
6+ using Windows . Win32 . Foundation ;
7+ using Windows . Win32 . UI . Input . KeyboardAndMouse ;
8+ using Windows . Win32 . UI . WindowsAndMessaging ;
49
510namespace Flow . Launcher . Infrastructure . Hotkey
611{
@@ -10,44 +15,45 @@ namespace Flow.Launcher.Infrastructure.Hotkey
1015 /// </summary>
1116 public unsafe class GlobalHotkey : IDisposable
1217 {
13- private static readonly IntPtr hookId ;
14-
15-
16-
18+ private static readonly HOOKPROC _procKeyboard = HookKeyboardCallback ;
19+ private static readonly UnhookWindowsHookExSafeHandle hookId ;
20+
1721 public delegate bool KeyboardCallback ( KeyEvent keyEvent , int vkCode , SpecialKeyState state ) ;
1822 internal static Func < KeyEvent , int , SpecialKeyState , bool > hookedKeyboardCallback ;
1923
20- //Modifier key constants
21- private const int VK_SHIFT = 0x10 ;
22- private const int VK_CONTROL = 0x11 ;
23- private const int VK_ALT = 0x12 ;
24- private const int VK_WIN = 91 ;
25-
2624 static GlobalHotkey ( )
2725 {
2826 // Set the hook
29- hookId = InterceptKeys . SetHook ( & LowLevelKeyboardProc ) ;
27+ hookId = SetHook ( _procKeyboard , WINDOWS_HOOK_ID . WH_KEYBOARD_LL ) ;
28+ }
29+
30+ private static UnhookWindowsHookExSafeHandle SetHook ( HOOKPROC proc , WINDOWS_HOOK_ID hookId )
31+ {
32+ using var curProcess = Process . GetCurrentProcess ( ) ;
33+ using var curModule = curProcess . MainModule ;
34+ return PInvoke . SetWindowsHookEx ( hookId , proc , PInvoke . GetModuleHandle ( curModule . ModuleName ) , 0 ) ;
3035 }
3136
3237 public static SpecialKeyState CheckModifiers ( )
3338 {
3439 SpecialKeyState state = new SpecialKeyState ( ) ;
35- if ( ( InterceptKeys . GetKeyState ( VK_SHIFT ) & 0x8000 ) != 0 )
40+ if ( ( PInvoke . GetKeyState ( ( int ) VIRTUAL_KEY . VK_SHIFT ) & 0x8000 ) != 0 )
3641 {
3742 //SHIFT is pressed
3843 state . ShiftPressed = true ;
3944 }
40- if ( ( InterceptKeys . GetKeyState ( VK_CONTROL ) & 0x8000 ) != 0 )
45+ if ( ( PInvoke . GetKeyState ( ( int ) VIRTUAL_KEY . VK_CONTROL ) & 0x8000 ) != 0 )
4146 {
4247 //CONTROL is pressed
4348 state . CtrlPressed = true ;
4449 }
45- if ( ( InterceptKeys . GetKeyState ( VK_ALT ) & 0x8000 ) != 0 )
50+ if ( ( PInvoke . GetKeyState ( ( int ) VIRTUAL_KEY . VK_MENU ) & 0x8000 ) != 0 )
4651 {
4752 //ALT is pressed
4853 state . AltPressed = true ;
4954 }
50- if ( ( InterceptKeys . GetKeyState ( VK_WIN ) & 0x8000 ) != 0 )
55+ if ( ( PInvoke . GetKeyState ( ( int ) VIRTUAL_KEY . VK_LWIN ) & 0x8000 ) != 0 ||
56+ ( PInvoke . GetKeyState ( ( int ) VIRTUAL_KEY . VK_RWIN ) & 0x8000 ) != 0 )
5157 {
5258 //WIN is pressed
5359 state . WinPressed = true ;
@@ -56,38 +62,38 @@ public static SpecialKeyState CheckModifiers()
5662 return state ;
5763 }
5864
59- [ UnmanagedCallersOnly ]
60- private static IntPtr LowLevelKeyboardProc ( int nCode , UIntPtr wParam , IntPtr lParam )
65+ private static LRESULT HookKeyboardCallback ( int nCode , WPARAM wParam , LPARAM lParam )
6166 {
6267 bool continues = true ;
6368
6469 if ( nCode >= 0 )
6570 {
66- if ( wParam . ToUInt32 ( ) == ( int ) KeyEvent . WM_KEYDOWN ||
67- wParam . ToUInt32 ( ) == ( int ) KeyEvent . WM_KEYUP ||
68- wParam . ToUInt32 ( ) == ( int ) KeyEvent . WM_SYSKEYDOWN ||
69- wParam . ToUInt32 ( ) == ( int ) KeyEvent . WM_SYSKEYUP )
71+ if ( wParam . Value == ( int ) KeyEvent . WM_KEYDOWN ||
72+ wParam . Value == ( int ) KeyEvent . WM_KEYUP ||
73+ wParam . Value == ( int ) KeyEvent . WM_SYSKEYDOWN ||
74+ wParam . Value == ( int ) KeyEvent . WM_SYSKEYUP )
7075 {
7176 if ( hookedKeyboardCallback != null )
72- continues = hookedKeyboardCallback ( ( KeyEvent ) wParam . ToUInt32 ( ) , Marshal . ReadInt32 ( lParam ) , CheckModifiers ( ) ) ;
77+ continues = hookedKeyboardCallback ( ( KeyEvent ) wParam . Value , Marshal . ReadInt32 ( lParam ) , CheckModifiers ( ) ) ;
7378 }
7479 }
7580
7681 if ( continues )
7782 {
78- return InterceptKeys . CallNextHookEx ( hookId , nCode , wParam , lParam ) ;
83+ return PInvoke . CallNextHookEx ( hookId , nCode , wParam , lParam ) ;
7984 }
80- return ( IntPtr ) ( - 1 ) ;
85+
86+ return new LRESULT ( 1 ) ;
8187 }
8288
8389 public void Dispose ( )
8490 {
85- InterceptKeys . UnhookWindowsHookEx ( hookId ) ;
91+ hookId . Dispose ( ) ;
8692 }
8793
8894 ~ GlobalHotkey ( )
8995 {
9096 Dispose ( ) ;
9197 }
9298 }
93- }
99+ }
0 commit comments