From 3231b1d32fda0a7aa0f506b3797309c4c44bb1ad Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 2 Jul 2025 13:02:42 +0800 Subject: [PATCH] Implement initialization model for plugin hotkeys --- Flow.Launcher/Helper/HotKeyMapper.cs | 509 +++++++++++++++++++++++---- 1 file changed, 439 insertions(+), 70 deletions(-) diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs index 682e1dbc7..1085d141d 100644 --- a/Flow.Launcher/Helper/HotKeyMapper.cs +++ b/Flow.Launcher/Helper/HotKeyMapper.cs @@ -26,37 +26,165 @@ internal static class HotKeyMapper private static Settings _settings; private static MainViewModel _mainViewModel; - private static readonly Dictionary _windowHotkeyEvents = new(); + // Registered hotkeys for ActionContext + private static List _actionContextRegisteredHotkeys; + + #region Initializatin internal static void Initialize() { _mainViewModel = Ioc.Default.GetRequiredService(); _settings = Ioc.Default.GetService(); - SetHotkey(_settings.Hotkey, OnToggleHotkey); - LoadCustomPluginHotkey(); - LoadGlobalPluginHotkey(); - LoadWindowPluginHotkey(); + InitializeRegisteredHotkeys(); + + foreach (var hotkey in _settings.RegisteredHotkeys) + { + SetHotkey(hotkey); + } } + private static void InitializeRegisteredHotkeys() + { + // Fixed hotkeys for ActionContext + _actionContextRegisteredHotkeys = new List + { + new(RegisteredHotkeyType.CtrlShiftEnter, HotkeyType.SearchWindow, "Ctrl+Shift+Enter", "HotkeyCtrlShiftEnterDesc", _mainViewModel.OpenResultCommand), + new(RegisteredHotkeyType.CtrlEnter, HotkeyType.SearchWindow, "Ctrl+Enter", "OpenContainFolderHotkey", _mainViewModel.OpenResultCommand), + new(RegisteredHotkeyType.AltEnter, HotkeyType.SearchWindow, "Alt+Enter", "HotkeyOpenResult", _mainViewModel.OpenResultCommand), + }; + + // Fixed hotkeys & Editable hotkeys + var list = new List + { + // System default window hotkeys + new(RegisteredHotkeyType.Up, HotkeyType.SearchWindow, "Up", "HotkeyLeftRightDesc", null), + new(RegisteredHotkeyType.Down, HotkeyType.SearchWindow, "Down", "HotkeyLeftRightDesc", null), + new(RegisteredHotkeyType.Left, HotkeyType.SearchWindow, "Left", "HotkeyUpDownDesc", null), + new(RegisteredHotkeyType.Right, HotkeyType.SearchWindow, "Right", "HotkeyUpDownDesc", null), + + // Flow Launcher window hotkeys + new(RegisteredHotkeyType.Esc, HotkeyType.SearchWindow, "Escape", "HotkeyESCDesc", _mainViewModel.EscCommand), + new(RegisteredHotkeyType.Reload, HotkeyType.SearchWindow, "F5", "ReloadPluginHotkey", _mainViewModel.ReloadPluginDataCommand), + new(RegisteredHotkeyType.SelectFirstResult, HotkeyType.SearchWindow, "Alt+Home", "HotkeySelectFirstResult", _mainViewModel.SelectFirstResultCommand), + new(RegisteredHotkeyType.SelectLastResult, HotkeyType.SearchWindow, "Alt+End", "HotkeySelectLastResult", _mainViewModel.SelectLastResultCommand), + new(RegisteredHotkeyType.ReQuery, HotkeyType.SearchWindow, "Ctrl+R", "HotkeyRequery", _mainViewModel.ReQueryCommand), + new(RegisteredHotkeyType.IncreaseWidth, HotkeyType.SearchWindow, "Ctrl+OemCloseBrackets", "QuickWidthHotkey", _mainViewModel.IncreaseWidthCommand), + new(RegisteredHotkeyType.DecreaseWidth, HotkeyType.SearchWindow, "Ctrl+OemOpenBrackets", "QuickWidthHotkey", _mainViewModel.DecreaseWidthCommand), + new(RegisteredHotkeyType.IncreaseMaxResult, HotkeyType.SearchWindow, "Ctrl+OemPlus", "QuickHeightHotkey", _mainViewModel.IncreaseMaxResultCommand), + new(RegisteredHotkeyType.DecreaseMaxResult, HotkeyType.SearchWindow, "Ctrl+OemMinus", "QuickHeightHotkey", _mainViewModel.DecreaseMaxResultCommand), + new(RegisteredHotkeyType.ShiftEnter, HotkeyType.SearchWindow, "Shift+Enter", "OpenContextMenuHotkey", _mainViewModel.LoadContextMenuCommand), + new(RegisteredHotkeyType.Enter, HotkeyType.SearchWindow, "Enter", "HotkeyRunDesc", _mainViewModel.OpenResultCommand), + new(RegisteredHotkeyType.ToggleGameMode, HotkeyType.SearchWindow, "Ctrl+F12", "ToggleGameModeHotkey", _mainViewModel.ToggleGameModeCommand), + new(RegisteredHotkeyType.CopyFilePath, HotkeyType.SearchWindow, "Ctrl+Shift+C", "CopyFilePathHotkey", _mainViewModel.CopyAlternativeCommand), + new(RegisteredHotkeyType.OpenResultN1, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D1", "HotkeyOpenResultN", 1, _mainViewModel.OpenResultCommand, 0), + new(RegisteredHotkeyType.OpenResultN2, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D2", "HotkeyOpenResultN", 2, _mainViewModel.OpenResultCommand, 1), + new(RegisteredHotkeyType.OpenResultN3, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D3", "HotkeyOpenResultN", 3, _mainViewModel.OpenResultCommand, 2), + new(RegisteredHotkeyType.OpenResultN4, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D4", "HotkeyOpenResultN", 4, _mainViewModel.OpenResultCommand, 3), + new(RegisteredHotkeyType.OpenResultN5, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D5", "HotkeyOpenResultN", 5, _mainViewModel.OpenResultCommand, 4), + new(RegisteredHotkeyType.OpenResultN6, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D6", "HotkeyOpenResultN", 6, _mainViewModel.OpenResultCommand, 5), + new(RegisteredHotkeyType.OpenResultN7, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D7", "HotkeyOpenResultN", 7, _mainViewModel.OpenResultCommand, 6), + new(RegisteredHotkeyType.OpenResultN8, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D8", "HotkeyOpenResultN", 8, _mainViewModel.OpenResultCommand, 7), + new(RegisteredHotkeyType.OpenResultN9, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D9", "HotkeyOpenResultN", 9, _mainViewModel.OpenResultCommand, 8), + new(RegisteredHotkeyType.OpenResultN10, HotkeyType.SearchWindow, $"{_settings.OpenResultModifiers}+D0", "HotkeyOpenResultN", 10, _mainViewModel.OpenResultCommand, 9), + + // Flow Launcher global hotkeys + new(RegisteredHotkeyType.Toggle, HotkeyType.Global, _settings.Hotkey, "flowlauncherHotkey", _mainViewModel.CheckAndToggleFlowLauncherCommand, null, () => _settings.Hotkey = ""), + + // Flow Launcher window hotkeys + new(RegisteredHotkeyType.Preview, HotkeyType.SearchWindow, _settings.PreviewHotkey, "previewHotkey", _mainViewModel.TogglePreviewCommand, null, () => _settings.PreviewHotkey = ""), + new(RegisteredHotkeyType.AutoComplete, HotkeyType.SearchWindow, _settings.AutoCompleteHotkey, "autoCompleteHotkey", _mainViewModel.AutocompleteQueryCommand, null, () => _settings.AutoCompleteHotkey = ""), + new(RegisteredHotkeyType.AutoComplete2, HotkeyType.SearchWindow, _settings.AutoCompleteHotkey2, "autoCompleteHotkey", _mainViewModel.AutocompleteQueryCommand, null, () => _settings.AutoCompleteHotkey2 = ""), + new(RegisteredHotkeyType.SelectNextItem, HotkeyType.SearchWindow, _settings.SelectNextItemHotkey, "SelectNextItemHotkey", _mainViewModel.SelectNextItemCommand, null, () => _settings.SelectNextItemHotkey = ""), + new(RegisteredHotkeyType.SelectNextItem2, HotkeyType.SearchWindow, _settings.SelectNextItemHotkey2, "SelectNextItemHotkey", _mainViewModel.SelectNextItemCommand, null, () => _settings.SelectNextItemHotkey2 = ""), + new(RegisteredHotkeyType.SelectPrevItem, HotkeyType.SearchWindow, _settings.SelectPrevItemHotkey, "SelectPrevItemHotkey", _mainViewModel.SelectPrevItemCommand, null, () => _settings.SelectPrevItemHotkey = ""), + new(RegisteredHotkeyType.SelectPrevItem2, HotkeyType.SearchWindow, _settings.SelectPrevItemHotkey2, "SelectPrevItemHotkey", _mainViewModel.SelectPrevItemCommand, null, () => _settings.SelectPrevItemHotkey2 = ""), + new(RegisteredHotkeyType.SettingWindow, HotkeyType.SearchWindow, _settings.SettingWindowHotkey, "SettingWindowHotkey", _mainViewModel.OpenSettingCommand, null, () => _settings.SettingWindowHotkey = ""), + new(RegisteredHotkeyType.OpenHistory, HotkeyType.SearchWindow, _settings.OpenHistoryHotkey, "OpenHistoryHotkey", _mainViewModel.LoadHistoryCommand, null, () => _settings.OpenHistoryHotkey = ""), + new(RegisteredHotkeyType.OpenContextMenu, HotkeyType.SearchWindow, _settings.OpenContextMenuHotkey, "OpenContextMenuHotkey", _mainViewModel.LoadContextMenuCommand, null, () => _settings.OpenContextMenuHotkey = ""), + new(RegisteredHotkeyType.SelectNextPage, HotkeyType.SearchWindow, _settings.SelectNextPageHotkey, "SelectNextPageHotkey", _mainViewModel.SelectNextPageCommand, null, () => _settings.SelectNextPageHotkey = ""), + new(RegisteredHotkeyType.SelectPrevPage, HotkeyType.SearchWindow, _settings.SelectPrevPageHotkey, "SelectPrevPageHotkey", _mainViewModel.SelectPrevPageCommand, null, () => _settings.SelectPrevPageHotkey = ""), + new(RegisteredHotkeyType.CycleHistoryUp, HotkeyType.SearchWindow, _settings.CycleHistoryUpHotkey, "CycleHistoryUpHotkey", _mainViewModel.ReverseHistoryCommand, null, () => _settings.CycleHistoryUpHotkey = ""), + new(RegisteredHotkeyType.CycleHistoryDown, HotkeyType.SearchWindow, _settings.CycleHistoryDownHotkey, "CycleHistoryDownHotkey", _mainViewModel.ForwardHistoryCommand, null, () => _settings.CycleHistoryDownHotkey = "") + }; + + // Custom query global hotkeys + if (_settings.CustomPluginHotkeys != null) + { + foreach (var customPluginHotkey in _settings.CustomPluginHotkeys) + { + list.Add(new(RegisteredHotkeyType.CustomQuery, HotkeyType.Global, customPluginHotkey.Hotkey, "customQueryHotkey", CustomQueryHotkeyCommand, customPluginHotkey, () => customPluginHotkey.Hotkey = "")); + } + } + + // Plugin hotkeys + // Global plugin hotkeys + var pluginHotkeyInfos = PluginManager.GetPluginHotkeyInfo(); + foreach (var info in pluginHotkeyInfos) + { + var pluginPair = info.Key; + var hotkeyInfo = info.Value; + var metadata = pluginPair.Metadata; + foreach (var hotkey in hotkeyInfo) + { + if (hotkey.HotkeyType == HotkeyType.Global && hotkey is GlobalPluginHotkey globalHotkey) + { + var hotkeyStr = metadata.PluginHotkeys.Find(h => h.Id == hotkey.Id)?.Hotkey ?? hotkey.DefaultHotkey; + // TODO: Support removeAction + Action removeHotkeyAction = hotkey.Editable ? + /*() => metadata.PluginHotkeys.RemoveAll(h => h.Id == hotkey.Id) :*/ null: + null; + // TODO: Handle pluginGlobalHotkey & get translation from PluginManager + list.Add(new(RegisteredHotkeyType.PluginGlobalHotkey, HotkeyType.Global, hotkeyStr, "pluginGlobalHotkey", GlobalPluginHotkeyCommand, new GlobalPluginHotkeyPair(metadata, globalHotkey), () => { })); + } + } + } + + // Window plugin hotkeys + var windowPluginHotkeys = PluginManager.GetWindowPluginHotkeys(); + foreach (var hotkey in windowPluginHotkeys) + { + var hotkeyModel = hotkey.Key; + var windowHotkeys = hotkey.Value; + // TODO: Support removeAction + Action removeHotkeysAction = windowHotkeys.All(h => h.SearchWindowPluginHotkey.Editable) ? + /*() => hotkeyModel.Metadata.PluginWindowHotkeys.RemoveAll(h => h.SearchWindowPluginHotkey.Editable) :*/ null : + null; + // TODO: Handle pluginWindowHotkey & get translation from PluginManager + list.Add(new(RegisteredHotkeyType.PluginWindowHotkey, HotkeyType.SearchWindow, hotkeyModel, "pluginWindowHotkey", WindowPluginHotkeyCommand, new WindowPluginHotkeyPair(windowHotkeys))); + } + + // Add registered hotkeys + foreach (var hotkey in list) + { + _settings.RegisteredHotkeys.Add(hotkey); + } + } + + #endregion + + // TODO: Deprecated internal static void OnToggleHotkey(object sender, HotkeyEventArgs args) { if (!_mainViewModel.ShouldIgnoreHotkeys()) _mainViewModel.ToggleFlowLauncher(); } + // TODO: Deprecated internal static void OnToggleHotkeyWithChefKeys() { if (!_mainViewModel.ShouldIgnoreHotkeys()) _mainViewModel.ToggleFlowLauncher(); } + // TODO: Deprecated private static void SetHotkey(string hotkeyStr, EventHandler action) { var hotkey = new HotkeyModel(hotkeyStr); SetHotkey(hotkey, action); } + // TODO: Deprecated private static void SetWithChefKeys(string hotkeyStr) { try @@ -76,8 +204,14 @@ internal static class HotKeyMapper } } + // TODO: Deprecated internal static void SetHotkey(HotkeyModel hotkey, EventHandler action) { + if (hotkey.IsEmpty) + { + return; + } + string hotkeyStr = hotkey.ToString(); try { @@ -102,6 +236,7 @@ internal static class HotKeyMapper } } + // TODO: Deprecated internal static void RemoveHotkey(string hotkeyStr) { try @@ -127,26 +262,279 @@ internal static class HotKeyMapper } } + // TODO: Deprecated private static void RemoveWithChefKeys(string hotkeyStr) { ChefKeysManager.UnregisterHotkey(hotkeyStr); ChefKeysManager.Stop(); } - /// - /// Custom Query Hotkeys (Global) - /// - internal static void LoadCustomPluginHotkey() - { - if (_settings.CustomPluginHotkeys == null) - return; + #region Hotkey Setting - foreach (CustomPluginHotkey hotkey in _settings.CustomPluginHotkeys) + private static void SetHotkey(RegisteredHotkeyData hotkeyData) + { + if (hotkeyData is null || // Hotkey data is invalid + hotkeyData.Hotkey.IsEmpty || // Hotkey is none + hotkeyData.Command is null) // No need to set - it is a system command { - SetCustomQueryHotkey(hotkey); + return; + } + + if (hotkeyData.Type == HotkeyType.Global) + { + SetGlobalHotkey(hotkeyData); + } + else if (hotkeyData.Type == HotkeyType.SearchWindow) + { + SetWindowHotkey(hotkeyData); } } + private static void RemoveHotkey(RegisteredHotkeyData hotkeyData) + { + if (hotkeyData is null || // Hotkey data is invalid + hotkeyData.Hotkey.IsEmpty || // Hotkey is none + hotkeyData.Command is null) // No need to set - it is a system command + { + return; + } + + if (hotkeyData.Type == HotkeyType.Global) + { + RemoveGlobalHotkey(hotkeyData); + } + else if (hotkeyData.Type == HotkeyType.SearchWindow) + { + RemoveWindowHotkey(hotkeyData); + } + } + + private static void SetGlobalHotkey(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + var hotkeyStr = hotkey.ToString(); + var hotkeyCommand = hotkeyData.Command; + var hotkeyCommandParameter = hotkeyData.CommandParameter; + try + { + if (hotkeyStr == "LWin" || hotkeyStr == "RWin") + { + SetGlobalHotkeyWithChefKeys(hotkeyData); + return; + } + + HotkeyManager.Current.AddOrReplace( + hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, + (s, e) => hotkeyCommand.Execute(hotkeyCommandParameter)); + } + catch (Exception e) + { + App.API.LogError(ClassName, $"Error registering hotkey {hotkeyStr}: {e.Message} \nStackTrace:{e.StackTrace}"); + var errorMsg = string.Format(App.API.GetTranslation("registerHotkeyFailed"), hotkeyStr); + var errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + private static void SetGlobalHotkeyWithChefKeys(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + if (hotkey.IsEmpty) + { + return; + } + + var hotkeyStr = hotkey.ToString(); + try + { + ChefKeysManager.RegisterHotkey(hotkeyStr, hotkeyStr, OnToggleHotkeyWithChefKeys); + ChefKeysManager.Start(); + } + catch (Exception e) + { + App.API.LogError(ClassName, + string.Format("Error registering hotkey: {0} \nStackTrace:{1}", + e.Message, + e.StackTrace)); + string errorMsg = string.Format(App.API.GetTranslation("registerHotkeyFailed"), hotkeyStr); + string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + private static void SetWindowHotkey(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + var hotkeyCommand = hotkeyData.Command; + var hotkeyCommandParameter = hotkeyData.CommandParameter; + try + { + if (Application.Current?.MainWindow is MainWindow window) + { + // Check if the hotkey already exists + var keyGesture = hotkey.ToKeyGesture(); + var existingBinding = window.InputBindings + .OfType() + .FirstOrDefault(kb => + kb.Gesture is KeyGesture keyGesture1 && + keyGesture.Key == keyGesture1.Key && + keyGesture.Modifiers == keyGesture1.Modifiers); + if (existingBinding != null) + { + throw new InvalidOperationException($"Windows key {hotkey} already exists"); + } + + // Add the new hotkey binding + var keyBinding = new KeyBinding() + { + Gesture = keyGesture, + Command = hotkeyCommand, + CommandParameter = hotkeyCommandParameter + }; + window.InputBindings.Add(keyBinding); + } + } + catch (Exception e) + { + App.API.LogError(ClassName, $"Error registering window hotkey {hotkey}: {e.Message} \nStackTrace:{e.StackTrace}"); + var errorMsg = string.Format(App.API.GetTranslation("registerWindowHotkeyFailed"), hotkey); + var errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + private static void RemoveGlobalHotkey(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + var hotkeyStr = hotkey.ToString(); + try + { + if (hotkeyStr == "LWin" || hotkeyStr == "RWin") + { + RemoveGlobalHotkeyWithChefKeys(hotkeyData); + return; + } + + if (!string.IsNullOrEmpty(hotkeyStr)) + HotkeyManager.Current.Remove(hotkeyStr); + } + catch (Exception e) + { + App.API.LogError(ClassName, $"Error removing hotkey: {e.Message} \nStackTrace:{e.StackTrace}"); + var errorMsg = string.Format(App.API.GetTranslation("unregisterHotkeyFailed"), hotkeyStr); + var errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + private static void RemoveGlobalHotkeyWithChefKeys(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + var hotkeyStr = hotkey.ToString(); + try + { + ChefKeysManager.UnregisterHotkey(hotkeyStr); + ChefKeysManager.Stop(); + } + catch (Exception e) + { + App.API.LogError(ClassName, $"Error removing hotkey: {e.Message} \nStackTrace:{e.StackTrace}"); + var errorMsg = string.Format(App.API.GetTranslation("unregisterHotkeyFailed"), hotkeyStr); + var errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + private static void RemoveWindowHotkey(RegisteredHotkeyData hotkeyData) + { + var hotkey = hotkeyData.Hotkey; + try + { + if (Application.Current?.MainWindow is MainWindow window) + { + // Remove the key binding + var keyGesture = hotkey.ToKeyGesture(); + var existingBinding = window.InputBindings + .OfType() + .FirstOrDefault(kb => + kb.Gesture is KeyGesture keyGesture1 && + keyGesture.Key == keyGesture1.Key && + keyGesture.Modifiers == keyGesture1.Modifiers); + if (existingBinding != null) + { + window.InputBindings.Remove(existingBinding); + } + } + } + catch (Exception e) + { + App.API.LogError(ClassName, $"Error removing window hotkey: {e.Message} \nStackTrace:{e.StackTrace}"); + var errorMsg = string.Format(App.API.GetTranslation("unregisterWindowHotkeyFailed"), hotkey); + var errorMsgTitle = App.API.GetTranslation("MessageBoxTitle"); + App.API.ShowMsgBox(errorMsg, errorMsgTitle); + } + } + + #endregion + + #region Commands + + private static RelayCommand _customQueryHotkeyCommand; + private static IRelayCommand CustomQueryHotkeyCommand => _customQueryHotkeyCommand ??= new RelayCommand(CustomQueryHotkey); + + private static RelayCommand _globalPluginHotkeyCommand; + private static IRelayCommand GlobalPluginHotkeyCommand => _globalPluginHotkeyCommand ??= new RelayCommand(GlobalPluginHotkey); + + private static RelayCommand _windowPluginHotkeyCommand; + private static IRelayCommand WindowPluginHotkeyCommand => _windowPluginHotkeyCommand ??= new RelayCommand(WindowPluginHotkey); + + private static void CustomQueryHotkey(CustomPluginHotkey customPluginHotkey) + { + if (_mainViewModel.ShouldIgnoreHotkeys()) + return; + + App.API.ShowMainWindow(); + App.API.ChangeQuery(customPluginHotkey.ActionKeyword, true); + } + + private static void GlobalPluginHotkey(GlobalPluginHotkeyPair pair) + { + if (_mainViewModel.ShouldIgnoreHotkeys() || pair.Metadata.Disabled) + return; + + pair.GlobalPluginHotkey.Action?.Invoke(); + } + + private static void WindowPluginHotkey(WindowPluginHotkeyPair pair) + { + // Get selected result + var selectedResult = _mainViewModel.GetSelectedResults().SelectedItem?.Result; + + // Check result nullability + if (selectedResult != null) + { + var pluginId = selectedResult.PluginID; + foreach (var hotkeyModel in pair.HotkeyModels) + { + var metadata = hotkeyModel.Metadata; + var pluginHotkey = hotkeyModel.PluginHotkey; + + if (metadata.ID != pluginId || // Check plugin ID match + metadata.Disabled || // Check plugin enabled state + !selectedResult.HotkeyIds.Contains(pluginHotkey.Id) || // Check hotkey supported state + pluginHotkey.Action == null) // Check action nullability + continue; + + // TODO: Remove return to skip other commands & Organize main window hotkeys + if (pluginHotkey.Action.Invoke(selectedResult)) + App.API.HideMainWindow(); + } + } + } + + #endregion + + // TODO: Deprecated internal static void SetCustomQueryHotkey(CustomPluginHotkey hotkey) { SetHotkey(hotkey.Hotkey, (s, e) => @@ -159,34 +547,14 @@ internal static class HotKeyMapper }); } - /// - /// Global Plugin Hotkeys (Global) - /// - internal static void LoadGlobalPluginHotkey() - { - var pluginHotkeyInfos = PluginManager.GetPluginHotkeyInfo(); - foreach (var info in pluginHotkeyInfos) - { - var pluginPair = info.Key; - var hotkeyInfo = info.Value; - var metadata = pluginPair.Metadata; - foreach (var hotkey in hotkeyInfo) - { - if (hotkey.HotkeyType == HotkeyType.Global && hotkey is GlobalPluginHotkey globalHotkey) - { - var hotkeyStr = metadata.PluginHotkeys.Find(h => h.Id == hotkey.Id)?.Hotkey ?? hotkey.DefaultHotkey; - SetGlobalPluginHotkey(globalHotkey, metadata, hotkeyStr); - } - } - } - } - + // TODO: Deprecated internal static void SetGlobalPluginHotkey(GlobalPluginHotkey globalHotkey, PluginMetadata metadata, string hotkeyStr) { var hotkey = new HotkeyModel(hotkeyStr); SetGlobalPluginHotkey(globalHotkey, metadata, hotkey); } + // TODO: Deprecated internal static void SetGlobalPluginHotkey(GlobalPluginHotkey globalHotkey, PluginMetadata metadata, HotkeyModel hotkey) { var hotkeyStr = hotkey.ToString(); @@ -199,18 +567,7 @@ internal static class HotKeyMapper }); } - /// - /// Plugin Window Hotkeys (Window) - /// - internal static void LoadWindowPluginHotkey() - { - var windowPluginHotkeys = PluginManager.GetWindowPluginHotkeys(); - foreach (var hotkey in windowPluginHotkeys) - { - SetWindowHotkey(hotkey.Key, hotkey.Value); - } - } - + // TODO: Deprecated internal static void SetWindowHotkey(HotkeyModel hotkey, List<(PluginMetadata Metadata, SearchWindowPluginHotkey PluginHotkey)> hotkeyModels) { try @@ -228,16 +585,7 @@ internal static class HotKeyMapper keyGesture.Modifiers == keyGesture1.Modifiers); if (existingBinding != null) { - // If the hotkey exists, remove the old command - if (_windowHotkeyEvents.ContainsKey(hotkey)) - { - window.InputBindings.Remove(existingBinding); - } - // If the hotkey does not exist, save the old command - else - { - _windowHotkeyEvents[hotkey] = existingBinding.Command; - } + throw new InvalidOperationException($"Key binding {hotkey} already exists"); } // Create and add the new key binding @@ -259,6 +607,7 @@ internal static class HotKeyMapper } } + // TODO: Deprecated private static ICommand BuildCommand(HotkeyModel hotkey, List<(PluginMetadata Metadata, SearchWindowPluginHotkey PluginHotkey)> hotkeyModels) { return new RelayCommand(() => @@ -297,14 +646,10 @@ internal static class HotKeyMapper return; } } - - if (_windowHotkeyEvents.TryGetValue(hotkey, out var existingCommand)) - { - existingCommand.Execute(null); - } }); } + // TODO: Deprecated internal static void RemoveWindowHotkey(HotkeyModel hotkey) { try @@ -323,13 +668,6 @@ internal static class HotKeyMapper { window.InputBindings.Remove(existingBinding); } - - // Restore the command if it exists - if (_windowHotkeyEvents.TryGetValue(hotkey, out var command)) - { - var keyBinding = new KeyBinding(command, keyGesture); - window.InputBindings.Add(keyBinding); - } } } catch (Exception e) @@ -344,6 +682,8 @@ internal static class HotKeyMapper } } + #region Check Hotkey + internal static bool CheckAvailability(HotkeyModel currentHotkey) { try @@ -362,4 +702,33 @@ internal static class HotKeyMapper return false; } + + #endregion + + #region Private Classes + + private class GlobalPluginHotkeyPair + { + public PluginMetadata Metadata { get; } + + public GlobalPluginHotkey GlobalPluginHotkey { get; } + + public GlobalPluginHotkeyPair(PluginMetadata metadata, GlobalPluginHotkey globalPluginHotkey) + { + Metadata = metadata; + GlobalPluginHotkey = globalPluginHotkey; + } + } + + private class WindowPluginHotkeyPair + { + public List<(PluginMetadata Metadata, SearchWindowPluginHotkey PluginHotkey)> HotkeyModels { get; } + + public WindowPluginHotkeyPair(List<(PluginMetadata Metadata, SearchWindowPluginHotkey PluginHotkey)> hotkeys) + { + HotkeyModels = hotkeys; + } + } + + #endregion }