Skip to content

IPluginHotkey Interface for Global Hotkey & Window Hotkey / Support Rename File & Folder by Hotkey or Context Menu #3770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 167 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
167 commits
Select commit Hold shift + click to select a range
81d5065
Added function to convert rad to deg and vice versa
Koisu-unavailable Jun 19, 2025
4e03b76
cleanup
Koisu-unavailable Jun 19, 2025
0c34eb0
fix formatting
Koisu-unavailable Jun 19, 2025
762e1c7
Fix Typo
VictoriousRaptor Jun 20, 2025
60e8226
added new action keyword
Koisu-unavailable Jun 20, 2025
8d8388b
Merge branch 'dev' of https://github.com/Koisu-unavailable/Flow.Launc…
Koisu-unavailable Jun 20, 2025
9eb4e64
Revert "Fix Typo"
Koisu-unavailable Jun 20, 2025
3bc06ac
Reapply "Fix Typo"
Koisu-unavailable Jun 20, 2025
c116ea2
added new view
Koisu-unavailable Jun 20, 2025
91e3582
Revert "added new view"
Koisu-unavailable Jun 20, 2025
bfb2adf
Revert "Reapply "Fix Typo""
Koisu-unavailable Jun 20, 2025
670dd1c
added new view
Koisu-unavailable Jun 20, 2025
39366b7
Revert "Revert "added new view""
Koisu-unavailable Jun 20, 2025
459d85d
added new dialogue box for renaming files
Koisu-unavailable Jun 22, 2025
5ae6f97
renaming half-works
Koisu-unavailable Jun 22, 2025
8282304
basic features of renaming files works
Koisu-unavailable Jun 22, 2025
c943982
polishing changes
Koisu-unavailable Jun 22, 2025
502a50b
added keybind to open the renaming dialog
Koisu-unavailable Jun 23, 2025
f36ee61
feat: :sparkles: Added keybind to rename files
Koisu-unavailable Jun 24, 2025
e12c2be
polished ui
Koisu-unavailable Jun 24, 2025
efe6595
revert bad changes
Koisu-unavailable Jun 24, 2025
9f32814
removed unnesscasry stuff
Koisu-unavailable Jun 24, 2025
432f6da
fixed icon in hotkey settings
Koisu-unavailable Jun 24, 2025
657bde5
revert changes to calculator plugin
Koisu-unavailable Jun 24, 2025
8138158
refactoring
Koisu-unavailable Jun 24, 2025
518f883
Changed RenameDialog to modal and added exception logging
Koisu-unavailable Jun 24, 2025
781feeb
added default to RenameFileHotkey
Koisu-unavailable Jun 24, 2025
b0beaaf
formatting
Koisu-unavailable Jun 24, 2025
402d398
checks for reserved names
Koisu-unavailable Jun 24, 2025
b556dac
Refactoring
Koisu-unavailable Jun 24, 2025
a6f1981
removed fragile error handling
Koisu-unavailable Jun 24, 2025
7ae261e
fix typo
Koisu-unavailable Jun 24, 2025
a5ef0cb
fixed unreachable code
Koisu-unavailable Jun 24, 2025
a326a76
refactoring
Koisu-unavailable Jun 24, 2025
54f126a
removed dynamic type
Koisu-unavailable Jun 24, 2025
f991d91
Improved File Rename Feature and Icon Update
onesounds Jun 25, 2025
94f3746
Add plugin hotkey model
Jack251970 Jun 25, 2025
5f49c43
Display plugin hotkey setting
Jack251970 Jun 25, 2025
605837b
Add global key registeration
Jack251970 Jun 25, 2025
f841175
Fix log message issue
Jack251970 Jun 25, 2025
8abd531
Add window key registeration
Jack251970 Jun 25, 2025
4d77bad
Sort hotkey info list
Jack251970 Jun 25, 2025
8ed495d
Improve code quality
Jack251970 Jun 25, 2025
f7fa647
Use IPluginHotkey for explorer plugin
Jack251970 Jun 25, 2025
f2358a5
Fix hotkey control construction issue
Jack251970 Jun 25, 2025
30b9b1f
Add Visible api
Jack251970 Jun 25, 2025
f837b2a
Remove unused using
Jack251970 Jun 25, 2025
35f8ea3
Check hotkey mapper count
Jack251970 Jun 25, 2025
8da182d
Close window when escape pressed
Koisu-unavailable Jun 25, 2025
043bf3b
remove unused using
Koisu-unavailable Jun 25, 2025
0aff9e3
Merge branch 'rename-file' of https://github.com/Koisu-unavailable/Fl…
Jack251970 Jun 26, 2025
53e0bc3
Improve hotkey model
Jack251970 Jun 26, 2025
724b8a7
Support change window hotkey
Jack251970 Jun 26, 2025
c7de03b
Save & restore old command
Jack251970 Jun 26, 2025
b52c7e7
Check result null & Improve docuements
Jack251970 Jun 26, 2025
590ea61
Skip other commands if executed
Jack251970 Jun 26, 2025
ead9b1e
Return to skip other commands
Jack251970 Jun 26, 2025
030a7f3
Adjust margins
Jack251970 Jun 26, 2025
854f808
Use IPluginHotkey for plugin manager plugin
Jack251970 Jun 26, 2025
9f404aa
Use IPluginHotkey for program plugin
Jack251970 Jun 26, 2025
3fe1e50
Resolve context data for uwps
Jack251970 Jun 26, 2025
96b5eb3
Skip this plugin if all hotkeys are invisible
Jack251970 Jun 26, 2025
ddc890e
Skip invisible hotkeys
Jack251970 Jun 26, 2025
e9727c4
Add todo
Jack251970 Jun 26, 2025
95fadcb
Merge branch 'dev' into rename-file
Jack251970 Jun 27, 2025
cda33df
Make constructor protected
Koisu-unavailable Jun 27, 2025
96b3645
Merge branch 'rename-file' of https://github.com/Koisu-unavailable/Fl…
Koisu-unavailable Jun 27, 2025
7fddfd9
Merge branch 'dev' into rename-file
Jack251970 Jun 28, 2025
e087d33
Add hotkey id check
Jack251970 Jun 28, 2025
3b4698e
Use selected results
Jack251970 Jun 28, 2025
e24af14
Add hotkey ids for all results
Jack251970 Jun 28, 2025
73a232f
Fix clone issue
Jack251970 Jun 30, 2025
c9db3ec
Improve string resource
Jack251970 Jun 30, 2025
14310d2
Add code comments
Jack251970 Jul 1, 2025
b87f233
Code quality
Jack251970 Jul 1, 2025
afdb56d
Change RegisteredHotkeys to observable
Jack251970 Jul 2, 2025
1d2aa96
Add property changed for CustomPluginHotkey
Jack251970 Jul 2, 2025
989206b
Add is empty for HotkeyModel
Jack251970 Jul 2, 2025
5910d1d
Add property changed for RegisteredHotkeyData.Hotkey
Jack251970 Jul 2, 2025
2259d74
Add registered type, type, command, command parameter for RegisteredH…
Jack251970 Jul 2, 2025
3231b1d
Implement initialization model for plugin hotkeys
Jack251970 Jul 2, 2025
051af06
Add toggle cmmand for main view model
Jack251970 Jul 2, 2025
20f065a
Remove key bindings which will be registered in hotkey mapper
Jack251970 Jul 2, 2025
d332472
Add todo
Jack251970 Jul 2, 2025
43beef4
Use command & parameter for SetGlobalHotkeyWithChefKeys
Jack251970 Jul 2, 2025
39fa79b
Prepare to deprecation
Jack251970 Jul 2, 2025
6e94d16
Code quality
Jack251970 Jul 2, 2025
f36ca62
Fix typos
Jack251970 Jul 2, 2025
495e2c1
Revert "Add property changed for RegisteredHotkeyData.Hotkey"
Jack251970 Jul 2, 2025
40f1fc6
Allow setter for RegisteredHotkeyData.Hotkey
Jack251970 Jul 2, 2025
f63b8bd
Add ToString
Jack251970 Jul 2, 2025
e41eccc
Add initialization log information
Jack251970 Jul 2, 2025
3b1e014
Add change support for Flow Launcher hotkeys
Jack251970 Jul 2, 2025
2cf6bfb
Prepare for deprecation
Jack251970 Jul 2, 2025
730625c
Remove ChangeHotkey event & Remove deprecated functions
Jack251970 Jul 2, 2025
1c8a8d0
Code quality
Jack251970 Jul 2, 2025
e061f14
Check plugin modified state
Jack251970 Jul 2, 2025
1057f4d
Improve code quality
Jack251970 Jul 2, 2025
d46dedd
Remove Settings.CustomPluginHotkeys null check
Jack251970 Jul 2, 2025
fd3eef4
Add Equals & GetHashCode for CustomPluginHotkey
Jack251970 Jul 2, 2025
96e8eae
Revert "Add property changed for CustomPluginHotkey"
Jack251970 Jul 2, 2025
d0fc344
Explictly implement PropertyChanged
Jack251970 Jul 2, 2025
c4ce8fe
Add check for invalid query shortcuts
Jack251970 Jul 2, 2025
476ad9b
Add constructor for CustomPluginHotkey
Jack251970 Jul 2, 2025
42e2035
Improve string
Jack251970 Jul 2, 2025
ff99669
Refactor custom query hotkey setting window
Jack251970 Jul 2, 2025
5fa3bec
Add hotkey change events for custom query hotkeys
Jack251970 Jul 2, 2025
698fe79
Remove unused removing
Jack251970 Jul 2, 2025
7d0cf1f
Add plugin hotkey type
Jack251970 Jul 2, 2025
805b8ef
No need to check hotkey command when removing
Jack251970 Jul 2, 2025
503bc48
Add empty for hotkey model
Jack251970 Jul 2, 2025
db1c1b2
Use changed event for plugin hotkeys
Jack251970 Jul 2, 2025
c4fbb3d
Check count
Jack251970 Jul 2, 2025
dad681d
Use callback to check plugin hotkey change
Jack251970 Jul 2, 2025
8d26c1c
Add string resource
Jack251970 Jul 2, 2025
cd3eeba
Remove used functions
Jack251970 Jul 2, 2025
11c5b7c
Merge branch 'dev' into rename-file
Jack251970 Jul 2, 2025
e196aa4
Remove todos
Jack251970 Jul 2, 2025
e6fb766
Mark ActionContext as deprecated
Jack251970 Jul 2, 2025
f657494
Workaround for ActionContext compatibility
Jack251970 Jul 2, 2025
2625f6f
Make GetPluginsForInterface private
Jack251970 Jul 3, 2025
089c0fd
Initialize plugin enumerable after all plugins are initialized
Jack251970 Jul 3, 2025
2a52c28
Store plugin hotkey info
Jack251970 Jul 3, 2025
19c5cc3
Merge branch 'dev' into rename-file
Jack251970 Jul 6, 2025
515f24d
Merge branch 'dev' into rename-file
Jack251970 Jul 6, 2025
4874586
Fix build issue
Jack251970 Jul 6, 2025
1948711
Add hotkey get function
Jack251970 Jul 6, 2025
9b92061
Check modified & use IDictionary
Jack251970 Jul 6, 2025
89b454b
Fix typos
Jack251970 Jul 6, 2025
f52ef92
Fix string typos
Jack251970 Jul 6, 2025
5191780
Fix blank line change
Jack251970 Jul 6, 2025
4055e30
Use set hotkey function instead of setter
Jack251970 Jul 6, 2025
a693773
Improve code quality
Jack251970 Jul 6, 2025
d79272a
Cache reversed names
Jack251970 Jul 6, 2025
35474f2
Merge branch 'dev' into rename-file
Jack251970 Jul 7, 2025
9806997
Merge branch 'dev' into rename-file
Jack251970 Jul 10, 2025
c326901
Fix spelling
Jack251970 Jul 10, 2025
e8707ad
Unify error strings
Jack251970 Jul 10, 2025
40ba1ae
Do not validate key gesture for plugin hotkeys
Jack251970 Jul 10, 2025
c2c8a82
Restore plugin hotkey setting if it is not editable anymore
Jack251970 Jul 10, 2025
0dd2f5c
Fix typos
Jack251970 Jul 10, 2025
476d846
Improve code quality
Jack251970 Jul 10, 2025
3dcf22e
Use sorted info
Jack251970 Jul 10, 2025
0077856
Return for exceptions
Jack251970 Jul 10, 2025
ad81a3c
Fix hotkey string issue
Jack251970 Jul 10, 2025
96bf445
Fix action context hotkey event logic
Jack251970 Jul 10, 2025
2febc34
Merge branch 'dev' into rename-file
Jack251970 Jul 12, 2025
633e6d3
Redesign welcome page 3
Jack251970 Jul 12, 2025
b7db22a
Redesign hotkey page
Jack251970 Jul 12, 2025
4ad7ca9
Only use one string
Jack251970 Jul 12, 2025
0d4598b
Add property changed for OpenResultModifiers
Jack251970 Jul 12, 2025
6c21f74
Add Result Modifier Hotkeys changed event
Jack251970 Jul 12, 2025
28bd07d
Improve code quality
Jack251970 Jul 12, 2025
64cf1ed
Fix IsActionContextEvent logic
Jack251970 Jul 12, 2025
ada2af8
Fix open result command parameter issue
Jack251970 Jul 12, 2025
2acf9b4
Merge branch 'dev' into rename-file
Jack251970 Jul 14, 2025
98179eb
Merge branch 'dev' into rename-file
Jack251970 Jul 15, 2025
15e4a4f
Merge branch 'dev' into rename-file
Jack251970 Jul 19, 2025
45ed9fa
Merge branch 'dev' into rename-file
Jack251970 Jul 20, 2025
11e8a58
Add dialog jump hotkey
Jack251970 Jul 20, 2025
2ce4157
Fix build issue
Jack251970 Jul 20, 2025
2f71d0d
Fix key duplication
Jack251970 Jul 20, 2025
adb1adb
Do not execute when dialog jump is disabled
Jack251970 Jul 20, 2025
b88e2e9
Do not register dialog jump hotkey when dialog jump is disabled
Jack251970 Jul 20, 2025
912d5dd
Merge branch 'dev' into rename-file
Jack251970 Jul 24, 2025
d8d42b8
Merge branch 'dev' into rename-file
Jack251970 Jul 27, 2025
98816ac
Fix build issue
Jack251970 Jul 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.DialogJump;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
Expand All @@ -29,6 +31,8 @@ public static class PluginManager
public static readonly HashSet<PluginPair> GlobalPlugins = new();
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new();

public static Action<PluginHotkeyChangedEvent> PluginHotkeyChanged { get; set; }

// We should not initialize API in static constructor because it will create another API instance
private static IPublicAPI api = null;
private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService<IPublicAPI>();
Expand All @@ -40,6 +44,10 @@ public static class PluginManager
private static IEnumerable<PluginPair> _homePlugins;
private static IEnumerable<PluginPair> _resultUpdatePlugin;
private static IEnumerable<PluginPair> _translationPlugins;
private static IEnumerable<PluginPair> _hotkeyPlugins;

private static readonly Dictionary<PluginPair, List<BasePluginHotkey>> _pluginHotkeyInfo = new();
private static readonly Dictionary<HotkeyModel, List<(PluginMetadata, SearchWindowPluginHotkey)>> _windowPluginHotkeys = new();

private static readonly List<DialogJumpExplorerPair> _dialogJumpExplorerPlugins = new();
private static readonly List<DialogJumpDialogPair> _dialogJumpDialogPlugins = new();
Expand Down Expand Up @@ -190,6 +198,7 @@ public static void LoadPlugins(PluginsSettings settings)
_homePlugins = GetPluginsForInterface<IAsyncHomeQuery>();
_resultUpdatePlugin = GetPluginsForInterface<IResultUpdated>();
_translationPlugins = GetPluginsForInterface<IPluginI18n>();
_hotkeyPlugins = GetPluginsForInterface<IPluginHotkey>();

// Initialize Dialog Jump plugin pairs
foreach (var pair in GetPluginsForInterface<IDialogJumpExplorer>())
Expand Down Expand Up @@ -277,6 +286,10 @@ public static async Task InitializePluginsAsync()

await Task.WhenAll(InitTasks);

InitializePluginHotkeyInfo();
Settings.UpdatePluginHotkeyInfo(GetPluginHotkeyInfo());
InitializeWindowPluginHotkeys();

foreach (var plugin in AllPlugins)
{
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
Expand Down Expand Up @@ -485,6 +498,11 @@ public static IList<PluginPair> GetTranslationPlugins()
return _translationPlugins.Where(p => !PluginModified(p.Metadata.ID)).ToList();
}

public static IList<PluginPair> GetHotkeyPlugins()
{
return _hotkeyPlugins.Where(p => !PluginModified(p.Metadata.ID)).ToList();
}

public static List<Result> GetContextMenusForPlugin(Result result)
{
var results = new List<Result>();
Expand Down Expand Up @@ -529,6 +547,131 @@ public static IList<DialogJumpDialogPair> GetDialogJumpDialogs()
return _dialogJumpDialogPlugins.Where(p => !PluginModified(p.Metadata.ID)).ToList();
}

public static IDictionary<PluginPair, List<BasePluginHotkey>> GetPluginHotkeyInfo()
{
return _pluginHotkeyInfo.Where(p => !PluginModified(p.Key.Metadata.ID))
.ToDictionary(p => p.Key, p => p.Value);
}

public static IDictionary<HotkeyModel, List<(PluginMetadata Metadata, SearchWindowPluginHotkey SearchWindowPluginHotkey)>> GetWindowPluginHotkeys()
{
// Here we do not need to check PluginModified since we will check it in hotkey events
return _windowPluginHotkeys.ToDictionary(p => p.Key, p => p.Value);
}

public static void UpdatePluginHotkeyInfoTranslations()
{
foreach (var plugin in GetHotkeyPlugins())
{
var newHotkeys = ((IPluginHotkey)plugin.Plugin).GetPluginHotkeys();
if (_pluginHotkeyInfo.TryGetValue(plugin, out var oldHotkeys))
{
foreach (var newHotkey in newHotkeys)
{
if (oldHotkeys.FirstOrDefault(h => h.Id == newHotkey.Id) is BasePluginHotkey pluginHotkey)
{
pluginHotkey.Name = newHotkey.Name;
pluginHotkey.Description = newHotkey.Description;
}
else
{
oldHotkeys.Add(newHotkey);
}
}
}
else
{
_pluginHotkeyInfo.Add(plugin, newHotkeys);
}
}
}

private static void InitializePluginHotkeyInfo()
{
foreach (var plugin in GetHotkeyPlugins())
{
var hotkeys = ((IPluginHotkey)plugin.Plugin).GetPluginHotkeys();
_pluginHotkeyInfo.Add(plugin, hotkeys);
}
}

private static void InitializeWindowPluginHotkeys()
{
foreach (var info in GetPluginHotkeyInfo())
{
var pluginPair = info.Key;
var hotkeyInfo = info.Value;
var metadata = pluginPair.Metadata;
foreach (var hotkey in hotkeyInfo)
{
if (hotkey.HotkeyType == HotkeyType.SearchWindow && hotkey is SearchWindowPluginHotkey searchWindowHotkey)
{
var hotkeySetting = metadata.PluginHotkeys.Find(h => h.Id == hotkey.Id)?.Hotkey ?? hotkey.DefaultHotkey;
var hotkeyModel = new HotkeyModel(hotkeySetting);
if (!_windowPluginHotkeys.TryGetValue(hotkeyModel, out var list))
{
list = new List<(PluginMetadata, SearchWindowPluginHotkey)>();
_windowPluginHotkeys[hotkeyModel] = list;
}
list.Add((pluginPair.Metadata, searchWindowHotkey));
}
}
}
}

public static void ChangePluginHotkey(PluginMetadata plugin, GlobalPluginHotkey pluginHotkey, HotkeyModel newHotkey)
{
var oldHotkeyItem = plugin.PluginHotkeys.First(h => h.Id == pluginHotkey.Id);
var settingHotkeyItem = Settings.GetPluginSettings(plugin.ID).pluginHotkeys.First(h => h.Id == pluginHotkey.Id);
var oldHotkeyStr = settingHotkeyItem.Hotkey;
var oldHotkey = new HotkeyModel(oldHotkeyStr);
var newHotkeyStr = newHotkey.ToString();

// Update hotkey in plugin metadata & setting
oldHotkeyItem.Hotkey = newHotkeyStr;
settingHotkeyItem.Hotkey = newHotkeyStr;

PluginHotkeyChanged?.Invoke(new PluginHotkeyChangedEvent(oldHotkey, newHotkey, plugin, pluginHotkey));
}

public static void ChangePluginHotkey(PluginMetadata plugin, SearchWindowPluginHotkey pluginHotkey, HotkeyModel newHotkey)
{
var oldHotkeyItem = plugin.PluginHotkeys.First(h => h.Id == pluginHotkey.Id);
var settingHotkeyItem = Settings.GetPluginSettings(plugin.ID).pluginHotkeys.First(h => h.Id == pluginHotkey.Id);
var oldHotkeyStr = settingHotkeyItem.Hotkey;
var converter = new KeyGestureConverter();
var oldHotkey = new HotkeyModel(oldHotkeyStr);
var newHotkeyStr = newHotkey.ToString();

// Update hotkey in plugin metadata & setting
oldHotkeyItem.Hotkey = newHotkeyStr;
settingHotkeyItem.Hotkey = newHotkeyStr;

// Update window plugin hotkey dictionary
var oldHotkeyModels = _windowPluginHotkeys[oldHotkey];
_windowPluginHotkeys[oldHotkey] = oldHotkeyModels.Where(x => x.Item1.ID != plugin.ID || x.Item2.Id != pluginHotkey.Id).ToList();
if (_windowPluginHotkeys[oldHotkey].Count == 0)
{
_windowPluginHotkeys.Remove(oldHotkey);
}

if (_windowPluginHotkeys.TryGetValue(newHotkey, out var newHotkeyModels))
{
var newList = newHotkeyModels.ToList();
newList.Add((plugin, pluginHotkey));
_windowPluginHotkeys[newHotkey] = newList;
}
else
{
_windowPluginHotkeys[newHotkey] = new List<(PluginMetadata, SearchWindowPluginHotkey)>()
{
(plugin, pluginHotkey)
};
}

PluginHotkeyChanged?.Invoke(new PluginHotkeyChangedEvent(oldHotkey, newHotkey, plugin, pluginHotkey));
}

public static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
Expand Down Expand Up @@ -826,5 +969,28 @@ internal static async Task<bool> UninstallPluginAsync(PluginMetadata plugin, boo
}

#endregion

#region Class

public class PluginHotkeyChangedEvent
{
public HotkeyModel NewHotkey { get; }

public HotkeyModel OldHotkey { get; }

public PluginMetadata Metadata { get; }

public BasePluginHotkey PluginHotkey { get; }

public PluginHotkeyChangedEvent(HotkeyModel oldHotkey, HotkeyModel newHotkey, PluginMetadata metadata, BasePluginHotkey pluginHotkey)
{
OldHotkey = oldHotkey;
NewHotkey = newHotkey;
Metadata = metadata;
PluginHotkey = pluginHotkey;
}
}

#endregion
}
}
3 changes: 3 additions & 0 deletions Flow.Launcher.Core/Resource/Internationalization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ public static void UpdatePluginMetadataTranslations()
API.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
}
}

// Update plugin hotkey name & description
PluginManager.UpdatePluginHotkeyInfoTranslations();
}

#endregion
Expand Down
11 changes: 8 additions & 3 deletions Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
using Flow.Launcher.Infrastructure.DialogJump.Models;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using NHotkey;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Accessibility;
using CommunityToolkit.Mvvm.Input;

namespace Flow.Launcher.Infrastructure.DialogJump
{
Expand Down Expand Up @@ -162,22 +162,22 @@
}
if (!_locationChangeHook.IsNull)
{
PInvoke.UnhookWinEvent(_locationChangeHook);

Check warning on line 165 in Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
_locationChangeHook = HWINEVENTHOOK.Null;
}
if (!_destroyChangeHook.IsNull)
{
PInvoke.UnhookWinEvent(_destroyChangeHook);

Check warning on line 170 in Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
_destroyChangeHook = HWINEVENTHOOK.Null;
}
if (!_hideChangeHook.IsNull)
{
PInvoke.UnhookWinEvent(_hideChangeHook);

Check warning on line 175 in Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
_hideChangeHook = HWINEVENTHOOK.Null;
}
if (!_dialogEndChangeHook.IsNull)
{
PInvoke.UnhookWinEvent(_dialogEndChangeHook);

Check warning on line 180 in Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
_dialogEndChangeHook = HWINEVENTHOOK.Null;
}

Expand Down Expand Up @@ -318,7 +318,7 @@
if (API.PluginModified(explorer.Metadata.ID) || // Plugin is modified
explorer.Metadata.Disabled) continue; // Plugin is disabled

var explorerWindow = explorer.Plugin.CheckExplorerWindow(hWnd);

Check warning on line 321 in Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`Wnd` is not a recognized word. (unrecognized-spelling)
if (explorerWindow != null)
{
_dialogJumpExplorers[explorer] = explorerWindow;
Expand Down Expand Up @@ -453,10 +453,15 @@

#endregion

#region Hotkey
#region Hotkey Command

public static void OnToggleHotkey(object sender, HotkeyEventArgs args)
private static RelayCommand _dialogJumpCommand;
public static IRelayCommand DialogJumpCommand => _dialogJumpCommand ??= new RelayCommand(OnToggleHotkey);

private static void OnToggleHotkey()
{
if (!_settings.EnableDialogJump) return;

_ = Task.Run(async () =>
{
try
Expand Down
24 changes: 19 additions & 5 deletions Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
}
}

public readonly bool IsEmpty => CharKey == Key.None && !Alt && !Shift && !Win && !Ctrl;

public static HotkeyModel Empty => new();

public HotkeyModel(string hotkeyString)
{
Parse(hotkeyString);
Expand Down Expand Up @@ -117,12 +121,22 @@
}
}

public override string ToString()
public bool Equals(HotkeyModel other)
{
return CharKey == other.CharKey && ModifierKeys == other.ModifierKeys;
}

public KeyGesture ToKeyGesture()
{
return new KeyGesture(CharKey, ModifierKeys);
}

public override readonly string ToString()
{
return string.Join(" + ", EnumerateDisplayKeys());
}

public IEnumerable<string> EnumerateDisplayKeys()
public readonly IEnumerable<string> EnumerateDisplayKeys()
{
if (Ctrl && CharKey is not (Key.LeftCtrl or Key.RightCtrl))
{
Expand Down Expand Up @@ -155,9 +169,9 @@
/// <summary>
/// Validate hotkey
/// </summary>
/// <param name="validateKeyGestrue">Try to validate hotkey as a KeyGesture.</param>
/// <param name="validateKeyGesture">Try to validate hotkey as a KeyGesture.</param>
/// <returns></returns>
public bool Validate(bool validateKeyGestrue = false)
public bool Validate(bool validateKeyGesture = false)
{
switch (CharKey)
{
Expand All @@ -167,12 +181,12 @@
case Key.RightCtrl:
case Key.LeftShift:
case Key.RightShift:
case Key.LWin:

Check warning on line 184 in Flow.Launcher.Infrastructure/Hotkey/HotkeyModel.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`LWin` is not a recognized word. (unrecognized-spelling)
case Key.RWin:
case Key.None:
return false;
default:
if (validateKeyGestrue)
if (validateKeyGesture)
{
try
{
Expand Down
4 changes: 2 additions & 2 deletions Flow.Launcher.Infrastructure/Hotkey/IHotkeySettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Flow.Launcher.Infrastructure.Hotkey;

Expand All @@ -13,5 +13,5 @@ public interface IHotkeySettings
/// A list of hotkeys that have already been registered. The dialog will display these hotkeys and provide a way to
/// unregister them.
/// </summary>
public List<RegisteredHotkeyData> RegisteredHotkeys { get; }
public ObservableCollection<RegisteredHotkeyData> RegisteredHotkeys { get; }
}
Loading
Loading