diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs index a09185696..30a77f799 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs @@ -12,9 +12,9 @@ namespace Flow.Launcher.Infrastructure.Hotkey public unsafe class GlobalHotkey : IDisposable { private static readonly IntPtr hookId; - - - + + + public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state); internal static Func hookedKeyboardCallback; @@ -27,12 +27,15 @@ namespace Flow.Launcher.Infrastructure.Hotkey static GlobalHotkey() { // Set the hook - hookId = InterceptKeys.SetHook(& LowLevelKeyboardProc); + hookId = InterceptKeys.SetHook(&LowLevelKeyboardProc); } public static SpecialKeyState CheckModifiers() { SpecialKeyState state = new SpecialKeyState(); + + + if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0) { //SHIFT is pressed diff --git a/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs b/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs index 5bd97714c..0a7737fb7 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs @@ -31,15 +31,15 @@ namespace Flow.Launcher.Infrastructure.Hotkey } if (Shift) { - modifierKeys = modifierKeys | ModifierKeys.Shift; + modifierKeys |= ModifierKeys.Shift; } if (Win) { - modifierKeys = modifierKeys | ModifierKeys.Windows; + modifierKeys |= ModifierKeys.Windows; } if (Ctrl) { - modifierKeys = modifierKeys | ModifierKeys.Control; + modifierKeys |= ModifierKeys.Control; } return modifierKeys; } diff --git a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs b/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs index d33bac34c..737394bae 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs @@ -34,5 +34,8 @@ namespace Flow.Launcher.Infrastructure.Hotkey [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] public static extern short GetKeyState(int keyCode); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + public static extern short GetAsyncKeyState(int keyCode); } } \ No newline at end of file diff --git a/Flow.Launcher/HotkeyControl.xaml b/Flow.Launcher/HotkeyControl.xaml index 9b5f671d8..5bc6cbbc8 100644 --- a/Flow.Launcher/HotkeyControl.xaml +++ b/Flow.Launcher/HotkeyControl.xaml @@ -49,7 +49,6 @@ Margin="0,0,18,0" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" - PreviewKeyDown="TbHotkey_OnPreviewKeyDown" TabIndex="100" LostFocus="tbHotkey_LostFocus"/> diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs index bc437d862..5d1a258e7 100644 --- a/Flow.Launcher/HotkeyControl.xaml.cs +++ b/Flow.Launcher/HotkeyControl.xaml.cs @@ -9,6 +9,8 @@ using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Plugin; using System.Threading; +using Flow.Launcher.Core.Plugin; +using Flow.Launcher.Infrastructure.Logger; namespace Flow.Launcher { @@ -25,41 +27,93 @@ namespace Flow.Launcher protected virtual void OnHotkeyChanged() => HotkeyChanged?.Invoke(this, EventArgs.Empty); + private Func callback { get; set; } + public HotkeyControl() { InitializeComponent(); tbMsgTextOriginal = tbMsg.Text; tbMsgForegroundColorOriginal = tbMsg.Foreground; + + callback = TbHotkey_OnPreviewKeyDown; + + GotFocus += (_, _) => + { + PluginManager.API.RegisterGlobalKeyboardCallback(callback); + }; + LostFocus += (_, _) => + { + PluginManager.API.RemoveGlobalKeyboardCallback(callback); + }; } private CancellationTokenSource hotkeyUpdateSource; - private void TbHotkey_OnPreviewKeyDown(object sender, KeyEventArgs e) + private SpecialKeyState state = new SpecialKeyState(); + + private bool TbHotkey_OnPreviewKeyDown(int keyevent, int vkcode, SpecialKeyState dummy) { + var key = KeyInterop.KeyFromVirtualKey(vkcode); + + if ((KeyEvent)keyevent is not (KeyEvent.WM_KEYDOWN or KeyEvent.WM_SYSKEYDOWN)) + { + switch (key) + { + case Key.LeftAlt or Key.RightAlt: + state.AltPressed = false; + break; + case Key.LeftCtrl or Key.RightCtrl: + state.CtrlPressed = false; + break; + case Key.LeftShift or Key.RightShift: + state.ShiftPressed = false; + break; + case Key.LWin or Key.LWin: + state.WinPressed = false; + break; + default: + break; + } + return true; + } + + switch (key) + { + case Key.LeftAlt or Key.RightAlt: + state.AltPressed = true; + break; + case Key.LeftCtrl or Key.RightCtrl: + state.CtrlPressed = true; + break; + case Key.LeftShift or Key.RightShift: + state.ShiftPressed = true; + break; + case Key.LWin or Key.LWin: + state.WinPressed = true; + break; + } + + hotkeyUpdateSource?.Cancel(); hotkeyUpdateSource?.Dispose(); hotkeyUpdateSource = new(); var token = hotkeyUpdateSource.Token; - e.Handled = true; - //when alt is pressed, the real key should be e.SystemKey - Key key = e.Key == Key.System ? e.SystemKey : e.Key; - - SpecialKeyState specialKeyState = GlobalHotkey.CheckModifiers(); var hotkeyModel = new HotkeyModel( - specialKeyState.AltPressed, - specialKeyState.ShiftPressed, - specialKeyState.WinPressed, - specialKeyState.CtrlPressed, + state.AltPressed, + state.ShiftPressed, + state.WinPressed, + state.CtrlPressed, key); var hotkeyString = hotkeyModel.ToString(); if (hotkeyString == tbHotkey.Text) { - return; + return false; } + Log.Debug("test hotkey" + hotkeyString); _ = Dispatcher.InvokeAsync(async () => { @@ -67,6 +121,8 @@ namespace Flow.Launcher if (!token.IsCancellationRequested) await SetHotkey(hotkeyModel); }); + + return false; } public async Task SetHotkey(HotkeyModel keyModel, bool triggerValidate = true) diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 338b96406..e9d8fb35c 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -137,7 +137,7 @@ namespace Flow.Launcher private void OnHotkeyControlFocused(object sender, RoutedEventArgs e) { - HotKeyMapper.RemoveHotkey(settings.Hotkey); + //HotKeyMapper.RemoveHotkey(settings.Hotkey); } private void OnHotkeyControlFocusLost(object sender, RoutedEventArgs e)