From 8656eddf41432dde7f6c591f65d282e03d1d4cd6 Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Fri, 23 Feb 2024 23:25:29 +0200 Subject: [PATCH 01/10] Change protection level of ReQuery instance --- Flow.Launcher/ViewModel/MainViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index db481d410..ab93e08e2 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -208,7 +208,7 @@ namespace Flow.Launcher.ViewModel } [RelayCommand] - private void ReQuery() + public void ReQuery() { if (SelectedIsFromQueryResults()) { From 0522fc79f44f1a3c485aca252a095c30948f213f Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Fri, 23 Feb 2024 23:27:34 +0200 Subject: [PATCH 02/10] Add ReQuery Instance --- Flow.Launcher/PublicAPIInstance.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 36309a22a..5efc2324e 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -315,6 +315,8 @@ namespace Flow.Launcher public void RegisterGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Add(callback); public void RemoveGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Remove(callback); + public void ReQuery() => _mainVM.ReQuery(); + #endregion #region Private Methods From 50f71c07313bb872a20a5a82ee679616fc4e4e56 Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Fri, 23 Feb 2024 23:28:16 +0200 Subject: [PATCH 03/10] Add ReQuery to API --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index 49fe680f1..78f1e0afa 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -291,5 +291,11 @@ namespace Flow.Launcher.Plugin /// /// public bool IsGameModeOn(); + + /// + /// Reload Query + /// + /// + public void ReQuery(); } } From e722927d9e0e1e2dd72359cc11cc80b7a54dc24b Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Sun, 25 Feb 2024 04:05:54 +0200 Subject: [PATCH 04/10] ReQuery method overloading, reselect flag. --- Flow.Launcher/ViewModel/MainViewModel.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index ab93e08e2..6e53879f8 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -33,6 +33,7 @@ namespace Flow.Launcher.ViewModel #region Private Fields private bool _isQueryRunning; + private bool _reselect = true; private Query _lastQuery; private Result lastContextMenuResult = new Result(); private List lastContextMenuResults = new List(); @@ -216,6 +217,15 @@ namespace Flow.Launcher.ViewModel } } + public void ReQuery(bool reselect) + { + if (SelectedIsFromQueryResults()) + { + _reselect = reselect; + QueryResults(isReQuery: true); + } + } + [RelayCommand] private void LoadContextMenu() { @@ -1151,7 +1161,8 @@ namespace Flow.Launcher.ViewModel } } - Results.AddResults(resultsForUpdates, token); + Results.AddResults(resultsForUpdates, token, _reselect); + _reselect = true; } #endregion From 1d6c4cee2e703510ad60e0d011d55d4d0170dc4a Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Sun, 25 Feb 2024 04:11:30 +0200 Subject: [PATCH 05/10] AddResults & UpdateResults new param "reselect" --- Flow.Launcher/ViewModel/ResultsViewModel.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs index bb07ce085..d02dc9bd5 100644 --- a/Flow.Launcher/ViewModel/ResultsViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs @@ -147,23 +147,23 @@ namespace Flow.Launcher.ViewModel /// /// To avoid deadlock, this method should not called from main thread /// - public void AddResults(IEnumerable resultsForUpdates, CancellationToken token) + public void AddResults(IEnumerable resultsForUpdates, CancellationToken token, bool reselect = true) { var newResults = NewResults(resultsForUpdates); if (token.IsCancellationRequested) return; - UpdateResults(newResults, token); + UpdateResults(newResults, token, reselect); } - private void UpdateResults(List newResults, CancellationToken token = default) + private void UpdateResults(List newResults, CancellationToken token = default, bool reselect = true) { lock (_collectionLock) { // update UI in one run, so it can avoid UI flickering Results.Update(newResults, token); - if (Results.Any()) + if (reselect && Results.Any()) SelectedItem = Results[0]; } From ae84dae66dd98a7c894684d51b0fb98304242715 Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Sun, 25 Feb 2024 04:13:09 +0200 Subject: [PATCH 06/10] ReQuery new param "reselect" --- Flow.Launcher/PublicAPIInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 5efc2324e..b49bf39d3 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -315,7 +315,7 @@ namespace Flow.Launcher public void RegisterGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Add(callback); public void RemoveGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Remove(callback); - public void ReQuery() => _mainVM.ReQuery(); + public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect); #endregion From c8a2f10620e46265b879077244ccc452a7dfcff4 Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Sun, 25 Feb 2024 04:29:14 +0200 Subject: [PATCH 07/10] Introduce param "reselect" to ReQuery instance --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index 78f1e0afa..c95a8ce7b 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -293,9 +293,10 @@ namespace Flow.Launcher.Plugin public bool IsGameModeOn(); /// - /// Reload Query + /// Reloads the query. + /// This method should run /// - /// - public void ReQuery(); + /// Choose the first result after reload if true; keep the last selected result if false. Default is true. + public void ReQuery(bool reselect = true); } } From 2d805e53bc3adedf17fe4eb21631c039f21f3a7f Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 20 Mar 2024 00:47:14 -0500 Subject: [PATCH 08/10] revise structure --- Flow.Launcher/ViewModel/MainViewModel.cs | 53 +++++++++++++-------- Flow.Launcher/ViewModel/ResultsForUpdate.cs | 24 ++++------ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 6e53879f8..23e746bd7 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -177,7 +177,8 @@ namespace Flow.Launcher.ViewModel var token = e.Token == default ? _updateToken : e.Token; PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query); - if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, token))) + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, + token))) { Log.Error("MainViewModel", "Unable to add item to Result Update Queue"); } @@ -191,7 +192,8 @@ namespace Flow.Launcher.ViewModel Hide(); await PluginManager.ReloadDataAsync().ConfigureAwait(false); - Notification.Show(InternationalizationManager.Instance.GetTranslation("success"), InternationalizationManager.Instance.GetTranslation("completedSuccessfully")); + Notification.Show(InternationalizationManager.Instance.GetTranslation("success"), + InternationalizationManager.Instance.GetTranslation("completedSuccessfully")); } [RelayCommand] @@ -221,8 +223,7 @@ namespace Flow.Launcher.ViewModel { if (SelectedIsFromQueryResults()) { - _reselect = reselect; - QueryResults(isReQuery: true); + QueryResults(isReQuery: true, reselect: reselect); } } @@ -275,6 +276,7 @@ namespace Flow.Launcher.ViewModel { autoCompleteText = $"{result.ActionKeywordAssigned} {defaultSuggestion}"; } + autoCompleteText = SelectedResults.SelectedItem.QuerySuggestionText; } @@ -296,11 +298,13 @@ namespace Flow.Launcher.ViewModel { results.SelectedIndex = int.Parse(index); } + var result = results.SelectedItem?.Result; if (result == null) { return; } + var hideWindow = await result.ExecuteAsync(new ActionContext { // not null means pressing modifier key + number, should ignore the modifier key @@ -413,6 +417,7 @@ namespace Flow.Launcher.ViewModel public bool GameModeStatus { get; set; } = false; private string _queryText; + public string QueryText { get => _queryText; @@ -436,6 +441,7 @@ namespace Flow.Launcher.ViewModel Settings.WindowSize += 100; Settings.WindowLeft -= 50; } + OnPropertyChanged(); } @@ -451,6 +457,7 @@ namespace Flow.Launcher.ViewModel Settings.WindowLeft += 50; Settings.WindowSize -= 100; } + OnPropertyChanged(); } @@ -530,18 +537,17 @@ namespace Flow.Launcher.ViewModel { if (QueryText != queryText) { - // re-query is done in QueryText's setter method QueryText = queryText; // set to false so the subsequent set true triggers // PropertyChanged and MoveQueryTextToEnd is called QueryTextCursorMovedToEnd = false; - } else if (isReQuery) { Query(isReQuery: true); } + QueryTextCursorMovedToEnd = true; }); } @@ -611,8 +617,8 @@ namespace Flow.Launcher.ViewModel public string OpenResultCommandModifiers => Settings.OpenResultModifiers; - public string PreviewHotkey - { + public string PreviewHotkey + { get { // TODO try to patch issue #1755 @@ -626,6 +632,7 @@ namespace Flow.Launcher.ViewModel { Settings.PreviewHotkey = "F1"; } + return Settings.PreviewHotkey; } } @@ -694,7 +701,6 @@ namespace Flow.Launcher.ViewModel results.Add(ContextMenuTopMost(selected)); results.Add(ContextMenuPluginInfo(selected.PluginID)); } - if (!string.IsNullOrEmpty(query)) @@ -713,7 +719,6 @@ namespace Flow.Launcher.ViewModel r.Score = match.Score; return true; - }).ToList(); ContextMenu.AddResults(filtered, id); } @@ -740,10 +745,7 @@ namespace Flow.Launcher.ViewModel Title = string.Format(title, h.Query), SubTitle = string.Format(time, h.ExecutedDateTime), IcoPath = "Images\\history.png", - OriginQuery = new Query - { - RawQuery = h.Query - }, + OriginQuery = new Query { RawQuery = h.Query }, Action = _ => { SelectedResults = Results; @@ -771,7 +773,7 @@ namespace Flow.Launcher.ViewModel private readonly IReadOnlyList _emptyResult = new List(); - private async void QueryResults(bool isReQuery = false) + private async void QueryResults(bool isReQuery = false, bool reselect = true) { _updateSource?.Cancel(); @@ -880,20 +882,23 @@ namespace Flow.Launcher.ViewModel // Task.Yield will force it to run in ThreadPool await Task.Yield(); - IReadOnlyList results = await PluginManager.QueryForPluginAsync(plugin, query, currentCancellationToken); + IReadOnlyList results = + await PluginManager.QueryForPluginAsync(plugin, query, currentCancellationToken); currentCancellationToken.ThrowIfCancellationRequested(); results ??= _emptyResult; - if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query, currentCancellationToken))) + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query, + currentCancellationToken, reselect))) { Log.Error("MainViewModel", "Unable to add item to Result Update Queue"); } } } - private Query ConstructQuery(string queryText, IEnumerable customShortcuts, IEnumerable builtInShortcuts) + private Query ConstructQuery(string queryText, IEnumerable customShortcuts, + IEnumerable builtInShortcuts) { if (string.IsNullOrWhiteSpace(queryText)) { @@ -930,7 +935,9 @@ namespace Flow.Launcher.ViewModel } catch (Exception e) { - Log.Exception($"{nameof(MainViewModel)}.{nameof(ConstructQuery)}|Error when expanding shortcut {shortcut.Key}", e); + Log.Exception( + $"{nameof(MainViewModel)}.{nameof(ConstructQuery)}|Error when expanding shortcut {shortcut.Key}", + e); } } }); @@ -1075,6 +1082,7 @@ namespace Flow.Launcher.ViewModel { SelectedResults = Results; } + switch (Settings.LastQueryMode) { case LastQueryMode.Empty: @@ -1122,7 +1130,7 @@ namespace Flow.Launcher.ViewModel /// /// To avoid deadlock, this method should not called from main thread /// - public void UpdateResultView(IEnumerable resultsForUpdates) + public void UpdateResultView(ICollection resultsForUpdates) { if (!resultsForUpdates.Any()) return; @@ -1161,7 +1169,10 @@ namespace Flow.Launcher.ViewModel } } - Results.AddResults(resultsForUpdates, token, _reselect); + // it should be the same for all results + bool reSelect = resultsForUpdates.First().ReSelectFirstResult; + + Results.AddResults(resultsForUpdates, token, reSelect); _reselect = true; } diff --git a/Flow.Launcher/ViewModel/ResultsForUpdate.cs b/Flow.Launcher/ViewModel/ResultsForUpdate.cs index 4cb5b1a95..c1daace56 100644 --- a/Flow.Launcher/ViewModel/ResultsForUpdate.cs +++ b/Flow.Launcher/ViewModel/ResultsForUpdate.cs @@ -4,23 +4,15 @@ using System.Threading; namespace Flow.Launcher.ViewModel { - public struct ResultsForUpdate + public record struct ResultsForUpdate( + IReadOnlyList Results, + PluginMetadata Metadata, + Query Query, + CancellationToken Token, + bool ReSelectFirstResult = true) { - public IReadOnlyList Results { get; } + public string ID { get; } = Metadata.ID; - public PluginMetadata Metadata { get; } - public string ID { get; } - - public Query Query { get; } - public CancellationToken Token { get; } - - public ResultsForUpdate(IReadOnlyList results, PluginMetadata metadata, Query query, CancellationToken token) - { - Results = results; - Metadata = metadata; - Query = query; - Token = token; - ID = metadata.ID; - } + public bool ReSelectFirstResult { get; set; } } } From b2f7d34a4d8259576e339a0f81293dbe7eeed6f6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 20 Mar 2024 12:26:39 -0500 Subject: [PATCH 09/10] fix weird issue --- Flow.Launcher/ViewModel/MainViewModel.cs | 10 +++++----- Flow.Launcher/ViewModel/ResultsForUpdate.cs | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 23e746bd7..46102ca92 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -223,7 +223,7 @@ namespace Flow.Launcher.ViewModel { if (SelectedIsFromQueryResults()) { - QueryResults(isReQuery: true, reselect: reselect); + QueryResults(isReQuery: true, reSelect: reselect); } } @@ -773,7 +773,7 @@ namespace Flow.Launcher.ViewModel private readonly IReadOnlyList _emptyResult = new List(); - private async void QueryResults(bool isReQuery = false, bool reselect = true) + private async void QueryResults(bool isReQuery = false, bool reSelect = true) { _updateSource?.Cancel(); @@ -848,7 +848,7 @@ namespace Flow.Launcher.ViewModel var tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch { - false => QueryTask(plugin), + false => QueryTask(plugin, reSelect), true => Task.CompletedTask }).ToArray(); @@ -876,7 +876,7 @@ namespace Flow.Launcher.ViewModel } // Local function - async Task QueryTask(PluginPair plugin) + async Task QueryTask(PluginPair plugin, bool reSelect = true) { // Since it is wrapped within a ThreadPool Thread, the synchronous context is null // Task.Yield will force it to run in ThreadPool @@ -890,7 +890,7 @@ namespace Flow.Launcher.ViewModel results ??= _emptyResult; if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query, - currentCancellationToken, reselect))) + currentCancellationToken, reSelect))) { Log.Error("MainViewModel", "Unable to add item to Result Update Queue"); } diff --git a/Flow.Launcher/ViewModel/ResultsForUpdate.cs b/Flow.Launcher/ViewModel/ResultsForUpdate.cs index c1daace56..bc0be0de8 100644 --- a/Flow.Launcher/ViewModel/ResultsForUpdate.cs +++ b/Flow.Launcher/ViewModel/ResultsForUpdate.cs @@ -12,7 +12,5 @@ namespace Flow.Launcher.ViewModel bool ReSelectFirstResult = true) { public string ID { get; } = Metadata.ID; - - public bool ReSelectFirstResult { get; set; } } } From c0034d8e07d1d86c96d950ad3dae8a96dba05f1a Mon Sep 17 00:00:00 2001 From: AminSallah <124622454+AminSallah@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:17:24 +0200 Subject: [PATCH 10/10] Remove unnecessary top class _reselect parameter --- Flow.Launcher/ViewModel/MainViewModel.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 46102ca92..bb0505973 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -33,7 +33,6 @@ namespace Flow.Launcher.ViewModel #region Private Fields private bool _isQueryRunning; - private bool _reselect = true; private Query _lastQuery; private Result lastContextMenuResult = new Result(); private List lastContextMenuResults = new List(); @@ -1173,7 +1172,6 @@ namespace Flow.Launcher.ViewModel bool reSelect = resultsForUpdates.First().ReSelectFirstResult; Results.AddResults(resultsForUpdates, token, reSelect); - _reselect = true; } #endregion