From 343cdf2ad420da450911eb83504a9c8732db99d3 Mon Sep 17 00:00:00 2001 From: Vic <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 25 Feb 2023 15:00:19 +0800 Subject: [PATCH] Fix preview hotkey issue Check if preview hotkey is a valid KeyGesture when setting and loading Ban more printable characters --- .../Hotkey/HotkeyModel.cs | 54 ++++++++++++++++--- Flow.Launcher/HotkeyControl.xaml.cs | 11 ++-- Flow.Launcher/SettingWindow.xaml | 1 + Flow.Launcher/ViewModel/MainViewModel.cs | 20 ++++++- 4 files changed, 75 insertions(+), 11 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs b/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs index b92bc0207..e2816d57a 100644 --- a/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs +++ b/Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Windows.Input; -using System.Windows.Navigation; namespace Flow.Launcher.Infrastructure.Hotkey { @@ -99,7 +99,7 @@ namespace Flow.Launcher.Infrastructure.Hotkey { try { - CharKey = (Key) Enum.Parse(typeof (Key), charKey); + CharKey = (Key)Enum.Parse(typeof(Key), charKey); } catch (ArgumentException) { @@ -137,8 +137,13 @@ namespace Flow.Launcher.Infrastructure.Hotkey } return string.Join(" + ", keys); } - - public bool Validate() + + /// + /// Validate hotkey + /// + /// Try to validate hotkey as a KeyGesture. + /// + public bool Validate(bool validateKeyGestrue = false) { switch (CharKey) { @@ -152,11 +157,20 @@ namespace Flow.Launcher.Infrastructure.Hotkey case Key.RWin: return false; default: + if (validateKeyGestrue) + { + try + { + KeyGesture keyGesture = new KeyGesture(CharKey, ModifierKeys); + } + catch (System.Exception e) when (e is NotSupportedException || e is InvalidEnumArgumentException) + { + return false; + } + } if (ModifierKeys == ModifierKeys.None) { - return !((CharKey >= Key.A && CharKey <= Key.Z) || - (CharKey >= Key.D0 && CharKey <= Key.D9) || - (CharKey >= Key.NumPad0 && CharKey <= Key.NumPad9)); + return !IsPrintableCharacter(CharKey); } else { @@ -165,6 +179,32 @@ namespace Flow.Launcher.Infrastructure.Hotkey } } + private static bool IsPrintableCharacter(Key key) + { + // https://stackoverflow.com/questions/11881199/identify-if-a-event-key-is-text-not-only-alphanumeric + return (key >= Key.A && key <= Key.Z) || + (key >= Key.D0 && key <= Key.D9) || + (key >= Key.NumPad0 && key <= Key.NumPad9) || + key == Key.OemQuestion || + key == Key.OemQuotes || + key == Key.OemPlus || + key == Key.OemOpenBrackets || + key == Key.OemCloseBrackets || + key == Key.OemMinus || + key == Key.DeadCharProcessed || + key == Key.Oem1 || + key == Key.Oem7 || + key == Key.OemPeriod || + key == Key.OemComma || + key == Key.OemMinus || + key == Key.Add || + key == Key.Divide || + key == Key.Multiply || + key == Key.Subtract || + key == Key.Oem102 || + key == Key.Decimal; + } + public override bool Equals(object obj) { if (obj is HotkeyModel other) diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs index b71df9758..3da66caeb 100644 --- a/Flow.Launcher/HotkeyControl.xaml.cs +++ b/Flow.Launcher/HotkeyControl.xaml.cs @@ -19,6 +19,11 @@ namespace Flow.Launcher public event EventHandler HotkeyChanged; + /// + /// Designed for Preview Hotkey and KeyGesture. + /// + public bool ValidateKeyGesture { get; set; } = false; + protected virtual void OnHotkeyChanged() => HotkeyChanged?.Invoke(this, EventArgs.Empty); public HotkeyControl() @@ -68,7 +73,7 @@ namespace Flow.Launcher if (triggerValidate) { - bool hotkeyAvailable = CheckHotkeyAvailability(keyModel); + bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture); CurrentHotkeyAvailable = hotkeyAvailable; SetMessage(hotkeyAvailable); OnHotkeyChanged(); @@ -91,13 +96,13 @@ namespace Flow.Launcher CurrentHotkey = keyModel; } } - + public Task SetHotkeyAsync(string keyStr, bool triggerValidate = true) { return SetHotkeyAsync(new HotkeyModel(keyStr), triggerValidate); } - private static bool CheckHotkeyAvailability(HotkeyModel hotkey) => hotkey.Validate() && HotKeyMapper.CheckAvailability(hotkey); + private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) => hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey); public new bool IsFocused => tbHotkey.IsFocused; diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index daf8ec608..6efdb398b 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -2448,6 +2448,7 @@ Width="300" Height="35" Margin="0,0,0,0" + ValidateKeyGesture="True" HorizontalAlignment="Right" HorizontalContentAlignment="Right" Loaded="OnPreviewHotkeyControlLoaded" diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 705f6aad0..f3f0d2b3d 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -24,6 +24,7 @@ using System.Collections.Specialized; using CommunityToolkit.Mvvm.Input; using System.Globalization; using System.Windows.Input; +using System.ComponentModel; namespace Flow.Launcher.ViewModel { @@ -583,7 +584,24 @@ namespace Flow.Launcher.ViewModel public string OpenResultCommandModifiers => Settings.OpenResultModifiers; - public string PreviewHotkey => Settings.PreviewHotkey; + public string PreviewHotkey + { + get + { + // TODO try to patch issue #1755 + // Should be removed after some time + try + { + var converter = new KeyGestureConverter(); + var key = (KeyGesture)converter.ConvertFromString(Settings.PreviewHotkey); + } + catch (Exception e) when (e is NotSupportedException || e is InvalidEnumArgumentException) + { + Settings.PreviewHotkey = "F1"; + } + return Settings.PreviewHotkey; + } + } public string Image => Constant.QueryTextBoxIconImagePath;