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;