From 5c2127ec52bbde14de45950382ae63aa88dedee9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 6 Jul 2025 21:06:54 +0800
Subject: [PATCH 1/9] Add constructor for CustomPluginHotkey
---
.../UserSettings/PluginHotkey.cs | 24 ++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginHotkey.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginHotkey.cs
index 9dc395aca..0c5c38028 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginHotkey.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginHotkey.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Plugin;
+using System;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Infrastructure.UserSettings
{
@@ -6,5 +7,26 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public string Hotkey { get; set; }
public string ActionKeyword { get; set; }
+
+ public CustomPluginHotkey(string hotkey, string actionKeyword)
+ {
+ Hotkey = hotkey;
+ ActionKeyword = actionKeyword;
+ }
+
+ public override bool Equals(object other)
+ {
+ if (other is CustomPluginHotkey otherHotkey)
+ {
+ return Hotkey == otherHotkey.Hotkey && ActionKeyword == otherHotkey.ActionKeyword;
+ }
+
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(Hotkey, ActionKeyword);
+ }
}
}
From 7c41a37daaa8b76cef86ae6f4ec6406f30bede57 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 6 Jul 2025 21:07:25 +0800
Subject: [PATCH 2/9] Add blank lines
---
Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index e180f6570..f4644a267 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -43,12 +43,14 @@ namespace Flow.Launcher
App.API.ShowMsgBox(App.API.GetTranslation("emptyShortcut"));
return;
}
+
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
App.API.ShowMsgBox(App.API.GetTranslation("duplicateShortcut"));
return;
}
+
DialogResult = !update || originalKey != Key || originalValue != Value;
Close();
}
From eb2b8d06a1141f25ccebbdf8384341773d3e0118 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 6 Jul 2025 21:15:00 +0800
Subject: [PATCH 3/9] Refactor CustomQueryHotkeySetting control
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 18 ++++-
.../CustomQueryHotkeySetting.xaml.cs | 72 +++++++------------
Flow.Launcher/Languages/en.xaml | 4 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 38 ++++++++--
4 files changed, 77 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 0171e6d79..9575f8121 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -119,7 +119,8 @@
Grid.Column="1"
Margin="10"
HorizontalAlignment="Stretch"
- VerticalAlignment="Center" />
+ VerticalAlignment="Center"
+ Text="{Binding ActionKeyword}" />
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 77febde9d..685fdf00a 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -1,73 +1,52 @@
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Windows;
-using System.Windows.Input;
+using System.Windows;
using System.Windows.Controls;
-using Flow.Launcher.Helper;
+using System.Windows.Input;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- private readonly Settings _settings;
+ public string Hotkey { get; set; } = string.Empty;
+ public string ActionKeyword { get; set; } = string.Empty;
- private bool update;
- private CustomPluginHotkey updateCustomHotkey;
+ private readonly bool update;
+ private readonly CustomPluginHotkey originalCustomHotkey;
- public CustomQueryHotkeySetting(Settings settings)
+ public CustomQueryHotkeySetting()
{
- _settings = settings;
InitializeComponent();
+ lblAdd.Visibility = Visibility.Visible;
+ }
+
+ public CustomQueryHotkeySetting(CustomPluginHotkey hotkey)
+ {
+ originalCustomHotkey = hotkey;
+ update = true;
+ ActionKeyword = originalCustomHotkey.ActionKeyword;
+ InitializeComponent();
+ lblUpdate.Visibility = Visibility.Visible;
+ HotkeyControl.SetHotkey(originalCustomHotkey.Hotkey, false);
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
+ DialogResult = false;
Close();
}
private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
- if (!update)
+ Hotkey = HotkeyControl.CurrentHotkey.ToString();
+
+ if (string.IsNullOrEmpty(Hotkey) && string.IsNullOrEmpty(ActionKeyword))
{
- _settings.CustomPluginHotkeys ??= new ObservableCollection();
-
- var pluginHotkey = new CustomPluginHotkey
- {
- Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
- };
- _settings.CustomPluginHotkeys.Add(pluginHotkey);
-
- HotKeyMapper.SetCustomQueryHotkey(pluginHotkey);
- }
- else
- {
- var oldHotkey = updateCustomHotkey.Hotkey;
- updateCustomHotkey.ActionKeyword = tbAction.Text;
- updateCustomHotkey.Hotkey = HotkeyControl.CurrentHotkey.ToString();
- //remove origin hotkey
- HotKeyMapper.RemoveHotkey(oldHotkey);
- HotKeyMapper.SetCustomQueryHotkey(updateCustomHotkey);
- }
-
- Close();
- }
-
- public void UpdateItem(CustomPluginHotkey item)
- {
- updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
- o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
- if (updateCustomHotkey == null)
- {
- App.API.ShowMsgBox(App.API.GetTranslation("invalidPluginHotkey"));
- Close();
+ App.API.ShowMsgBox(App.API.GetTranslation("emptyPluginHotkey"));
return;
}
- tbAction.Text = updateCustomHotkey.ActionKeyword;
- HotkeyControl.SetHotkey(updateCustomHotkey.Hotkey, false);
- update = true;
- lblAdd.Text = App.API.GetTranslation("update");
+ DialogResult = !update || originalCustomHotkey.Hotkey != Hotkey || originalCustomHotkey.ActionKeyword != ActionKeyword;
+ Close();
}
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
@@ -79,6 +58,7 @@ namespace Flow.Launcher
private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
+ DialogResult = false;
Close();
}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index bd4cbd282..a6ec4718f 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -429,13 +429,14 @@
Press a custom hotkey to open Flow Launcher and input the specified query automatically.
Preview
Hotkey is unavailable, please select a new hotkey
- Invalid plugin hotkey
+ Hotkey is invalid
Update
Binding Hotkey
Current hotkey is unavailable.
This hotkey is reserved for "{0}" and can't be used. Please choose another hotkey.
This hotkey is already in use by "{0}". If you press "Overwrite", it will be removed from "{0}".
Press the keys you want to use for this function.
+ Hotkey and action keyword are empty
Custom Query Shortcut
@@ -444,6 +445,7 @@
Shortcut already exists, please enter a new Shortcut or edit the existing one.
Shortcut and/or its expansion is empty.
+ Shortcut is invalid
Save
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 7a7c19dd3..fdc9ef530 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -69,15 +69,33 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomQueryHotkeySetting(Settings);
- window.UpdateItem(item);
- window.ShowDialog();
+ var settingItem = Settings.CustomPluginHotkeys.FirstOrDefault(o =>
+ o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
+ if (settingItem == null)
+ {
+ App.API.ShowMsgBox(App.API.GetTranslation("invalidPluginHotkey"));
+ return;
+ }
+
+ var window = new CustomQueryHotkeySetting(settingItem);
+ if (window.ShowDialog() is not true) return;
+
+ var index = Settings.CustomPluginHotkeys.IndexOf(settingItem);
+ Settings.CustomPluginHotkeys[index] = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword);
+ HotKeyMapper.RemoveHotkey(settingItem.Hotkey); // remove origin hotkey
+ HotKeyMapper.SetCustomQueryHotkey(Settings.CustomPluginHotkeys[index]); // set new hotkey
}
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(Settings).ShowDialog();
+ var window = new CustomQueryHotkeySetting();
+ if (window.ShowDialog() is true)
+ {
+ var customHotkey = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword);
+ Settings.CustomPluginHotkeys.Add(customHotkey);
+ HotKeyMapper.SetCustomQueryHotkey(customHotkey); // set new hotkey
+ }
}
[RelayCommand]
@@ -114,10 +132,18 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomShortcutSetting(item.Key, item.Value, this);
+ var settingItem = Settings.CustomShortcuts.FirstOrDefault(o =>
+ o.Key == item.Key && o.Value == item.Value);
+ if (settingItem == null)
+ {
+ App.API.ShowMsgBox(App.API.GetTranslation("invalidShortcut"));
+ return;
+ }
+
+ var window = new CustomShortcutSetting(settingItem.Key, settingItem.Value, this);
if (window.ShowDialog() is not true) return;
- var index = Settings.CustomShortcuts.IndexOf(item);
+ var index = Settings.CustomShortcuts.IndexOf(settingItem);
Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value);
}
From 2856da83c1bcb23636b393047cae82681cc398b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Jul 2025 09:44:17 +0800
Subject: [PATCH 4/9] Fix quick access link type fetching issue
---
.../Views/QuickAccessLinkSettings.xaml.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index eb66e1efc..7261d37e2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -27,6 +27,9 @@ public partial class QuickAccessLinkSettings
if (string.IsNullOrEmpty(_selectedName))
{
SelectedName = _selectedPath.GetPathName();
+ }
+ if (!string.IsNullOrEmpty(_selectedPath))
+ {
_accessLinkType = GetResultType(_selectedPath);
}
}
From bad7db69dc252e96de5002f42ede8ddebcf24c65 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Jul 2025 09:45:54 +0800
Subject: [PATCH 5/9] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Explorer/Main.cs | 2 +-
.../Views/QuickAccessLinkSettings.xaml.cs | 7 ++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index 0d1d99f8a..f1aea98b4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -97,7 +97,7 @@ namespace Flow.Launcher.Plugin.Explorer
return Context.API.GetTranslation("plugin_explorer_plugin_description");
}
- private void FillQuickAccessLinkNames()
+ private static void FillQuickAccessLinkNames()
{
// Legacy version does not have names for quick access links, so we fill them with the path name.
foreach (var link in Settings.QuickAccessLinks)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 7261d37e2..818e59724 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
@@ -190,13 +191,13 @@ public partial class QuickAccessLinkSettings
private static ResultType GetResultType(string path)
{
// Check if the path is a file or folder
- if (System.IO.File.Exists(path))
+ if (File.Exists(path))
{
return ResultType.File;
}
- else if (System.IO.Directory.Exists(path))
+ else if (Directory.Exists(path))
{
- if (string.Equals(System.IO.Path.GetPathRoot(path), path, StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(Path.GetPathRoot(path), path, StringComparison.OrdinalIgnoreCase))
{
return ResultType.Volume;
}
From fe3babd4fc8d57a7532fda4dc16cdbe6c97dc330 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Jul 2025 09:50:12 +0800
Subject: [PATCH 6/9] Log error when fail to fetch type
---
.../Views/QuickAccessLinkSettings.xaml.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
index 818e59724..e6294b98b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
@@ -15,6 +15,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
[INotifyPropertyChanged]
public partial class QuickAccessLinkSettings
{
+ private static readonly string ClassName = nameof(QuickAccessLinkSettings);
+
private string _selectedPath;
public string SelectedPath
{
@@ -209,6 +211,7 @@ public partial class QuickAccessLinkSettings
else
{
// This should not happen, but just in case, we assume it's a folder
+ Main.Context.API.LogError(ClassName, $"The path '{path}' does not exist or is invalid. Defaulting to Folder type.");
return ResultType.Folder;
}
}
From b1e352dd54317e7d1d2f4606e9a3ad048ae99b91 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Jul 2025 11:12:46 +0800
Subject: [PATCH 7/9] Update home page when language changes
---
Flow.Launcher/MainWindow.xaml.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index aa5040dac..8474ba50e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -284,6 +284,10 @@ namespace Flow.Launcher
break;
case nameof(Settings.Language):
UpdateNotifyIconText();
+ if (_settings.ShowHomePage && _viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText))
+ {
+ _viewModel.QueryResults();
+ }
break;
case nameof(Settings.Hotkey):
UpdateNotifyIconText();
From e36d5d8ce7bcf21950c0adccd2b03b1afd2d3ca2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 10 Jul 2025 13:24:07 +0800
Subject: [PATCH 8/9] Fix spelling
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 4 ++--
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 9575f8121..db99b704a 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -153,13 +153,13 @@
Style="{StaticResource AccentButtonStyle}">
Date: Thu, 10 Jul 2025 13:27:04 +0800
Subject: [PATCH 9/9] Fix typos
---
Flow.Launcher/Languages/en.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index a6ec4718f..5bfeeb615 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -12,7 +12,7 @@
Your selected {0} executable is invalid.
{2}{2}
- Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+ Click yes if you would like select the {0} executable again. Click no if you would like to download {1}
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
@@ -378,7 +378,7 @@
Select File Manager
Learn more
Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
- For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
+ For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fields blank.
File Manager
Profile Name
File Manager Path