From e8691c210dbd2ee79d9f06503402a8bd4a2e2720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Sun, 23 May 2021 12:28:45 +0800 Subject: [PATCH 01/25] No need for the wrapped Lazy instance in image loading. --- Flow.Launcher/ResultListBox.xaml | 2 +- Flow.Launcher/ViewModel/ResultViewModel.cs | 92 ++++++---------------- 2 files changed, 27 insertions(+), 67 deletions(-) diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index 2f9d06d81..0f70dce41 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -42,7 +42,7 @@ + Source="{Binding Image}" /> diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index c91bbb107..dd4b351c3 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -11,62 +11,12 @@ namespace Flow.Launcher.ViewModel { public class ResultViewModel : BaseModel { - public class LazyAsync : Lazy> - { - private readonly T defaultValue; - - private readonly Action _updateCallback; - public new T Value - { - get - { - if (!IsValueCreated) - { - _ = Exercute(); // manually use callback strategy - - return defaultValue; - } - - if (!base.Value.IsCompletedSuccessfully) - return defaultValue; - - return base.Value.Result; - - // If none of the variables captured by the local function are captured by other lambdas, - // the compiler can avoid heap allocations. - async ValueTask Exercute() - { - await base.Value.ConfigureAwait(false); - _updateCallback(); - } - - } - } - public LazyAsync(Func> factory, T defaultValue, Action updateCallback) : base(factory) - { - if (defaultValue != null) - { - this.defaultValue = defaultValue; - } - - _updateCallback = updateCallback; - } - } - public ResultViewModel(Result result, Settings settings) { if (result != null) { Result = result; - - Image = new LazyAsync( - SetImage, - ImageLoader.DefaultImage, - () => - { - OnPropertyChanged(nameof(Image)); - }); - } + } Settings = settings; } @@ -85,44 +35,54 @@ namespace Flow.Launcher.ViewModel ? Result.SubTitle : Result.SubTitleToolTip; - public LazyAsync Image { get; set; } + private bool ImageLoaded; - private async ValueTask SetImage() + private ImageSource image = ImageLoader.DefaultImage; + + public ImageSource Image + { + get + { + if (!ImageLoaded) + { + ImageLoaded = true; + LoadImage(); + } + return image; + } + private set => image = value; + } + private async void LoadImage() { var imagePath = Result.IcoPath; if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) { try { - return Result.Icon(); + Image = Result.Icon(); + return; } catch (Exception e) { Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e); - return ImageLoader.DefaultImage; } } if (ImageLoader.CacheContainImage(imagePath)) + { // will get here either when icoPath has value\icon delegate is null\when had exception in delegate - return ImageLoader.Load(imagePath); + Image = ImageLoader.Load(imagePath); + return; + } - return await Task.Run(() => ImageLoader.Load(imagePath)); + Image = await Task.Run(() => ImageLoader.Load(imagePath)).ConfigureAwait(false); } public Result Result { get; } public override bool Equals(object obj) { - var r = obj as ResultViewModel; - if (r != null) - { - return Result.Equals(r.Result); - } - else - { - return false; - } + return obj is ResultViewModel r && Result.Equals(r.Result); } public override int GetHashCode() From 37f1a64495b848e5951cce83d57e375bb5fce5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Sun, 23 May 2021 22:54:52 +0800 Subject: [PATCH 02/25] avoid duplicate removing --- Flow.Launcher.Infrastructure/Image/ImageCache.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index bb7ec6817..4e95278c1 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -26,7 +26,7 @@ namespace Flow.Launcher.Infrastructure.Image private const int MaxCached = 50; public ConcurrentDictionary Data { get; private set; } = new ConcurrentDictionary(); private const int permissibleFactor = 2; - + public void Initialization(Dictionary usage) { foreach (var key in usage.Keys) @@ -35,6 +35,8 @@ namespace Flow.Launcher.Infrastructure.Image } } + private volatile bool removing; + public ImageSource this[string path] { get @@ -62,11 +64,13 @@ namespace Flow.Launcher.Infrastructure.Image // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time - if (Data.Count > permissibleFactor * MaxCached) + if (Data.Count > permissibleFactor * MaxCached && !removing) { + removing = true; // To delete the images from the data dictionary based on the resizing of the Usage Dictionary. foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key)) Data.TryRemove(key, out _); + removing = false; } } } From 1c6d207595c941c8bfa3d99a12d7e5c208ffe007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Mon, 24 May 2021 10:34:16 +0800 Subject: [PATCH 03/25] only modify property when async (avoid duplicate read) --- Flow.Launcher/ViewModel/ResultViewModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index dd4b351c3..791aa6da9 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -59,7 +59,7 @@ namespace Flow.Launcher.ViewModel { try { - Image = Result.Icon(); + image = Result.Icon(); return; } catch (Exception e) @@ -71,7 +71,7 @@ namespace Flow.Launcher.ViewModel if (ImageLoader.CacheContainImage(imagePath)) { // will get here either when icoPath has value\icon delegate is null\when had exception in delegate - Image = ImageLoader.Load(imagePath); + image = ImageLoader.Load(imagePath); return; } From 734a0cbfa1ac5fbfa47b4b6cdae13c8c20b2b051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Mon, 24 May 2021 10:35:18 +0800 Subject: [PATCH 04/25] Update comment --- Flow.Launcher/ViewModel/ResultViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 791aa6da9..4d57f8252 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -75,6 +75,7 @@ namespace Flow.Launcher.ViewModel return; } + // We need to modify the property not field here to trigger the OnPropertyChanged event Image = await Task.Run(() => ImageLoader.Load(imagePath)).ConfigureAwait(false); } From 710d2a89a2f861b396eb91bef2b9d0f1a79557ac Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 31 Jul 2021 16:15:49 +0800 Subject: [PATCH 05/25] Use ValueTask as return value to suppress potential image error --- Flow.Launcher/ViewModel/ResultViewModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 4d57f8252..190f592d7 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -35,7 +35,7 @@ namespace Flow.Launcher.ViewModel ? Result.SubTitle : Result.SubTitleToolTip; - private bool ImageLoaded; + private volatile bool ImageLoaded; private ImageSource image = ImageLoader.DefaultImage; @@ -46,13 +46,13 @@ namespace Flow.Launcher.ViewModel if (!ImageLoaded) { ImageLoaded = true; - LoadImage(); + _ = LoadImageAsync(); } return image; } private set => image = value; } - private async void LoadImage() + private async ValueTask LoadImageAsync() { var imagePath = Result.IcoPath; if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) From a0835288e2335d03bd8aa985d1d63b55c3616dcb Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Sat, 31 Jul 2021 16:23:58 +0800 Subject: [PATCH 06/25] Use SemaphoreSlim to ensure cache only remove once --- .../Image/ImageCache.cs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 4e95278c1..66104e806 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Windows.Media; @@ -26,6 +27,7 @@ namespace Flow.Launcher.Infrastructure.Image private const int MaxCached = 50; public ConcurrentDictionary Data { get; private set; } = new ConcurrentDictionary(); private const int permissibleFactor = 2; + private SemaphoreSlim semaphore = new(1, 1); public void Initialization(Dictionary usage) { @@ -35,8 +37,6 @@ namespace Flow.Launcher.Infrastructure.Image } } - private volatile bool removing; - public ImageSource this[string path] { get @@ -62,15 +62,22 @@ namespace Flow.Launcher.Infrastructure.Image } ); - // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size - // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time - if (Data.Count > permissibleFactor * MaxCached && !removing) + SliceExtra(); + + async void SliceExtra() { - removing = true; - // To delete the images from the data dictionary based on the resizing of the Usage Dictionary. - foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key)) - Data.TryRemove(key, out _); - removing = false; + // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size + // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time + if (Data.Count > permissibleFactor * MaxCached) + { + await semaphore.WaitAsync(); + // To delete the images from the data dictionary based on the resizing of the Usage Dictionary + // Double Check to avoid concurrent remove + if (Data.Count > permissibleFactor * MaxCached) + foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray()) + Data.TryRemove(key, out _); + semaphore.Release(); + } } } } From 7d1d41e6bafd0c46af6b23c3de0cad1cab4e0e84 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 2 Aug 2021 08:23:45 +1000 Subject: [PATCH 07/25] version bump --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 191ee4803..a764edbfd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: '1.8.1.{build}' +version: '1.8.2.{build}' init: - ps: | From df3b91ea9949aec1a40b0b73f8af9867f60a6e09 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 3 Aug 2021 07:58:35 +1000 Subject: [PATCH 08/25] fix PluginsManager's InstallOrUpdate focus --- .../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 5 ++++- Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 995ac0fed..5d2e2bc5d 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -120,7 +120,10 @@ namespace Flow.Launcher.Plugin.PluginsManager .ChangeQuery( $"{Context.CurrentPluginMetadata.ActionKeywords.FirstOrDefault()} {Settings.HotkeyUpdate} {plugin.Name}"); - Application.Current.MainWindow.Show(); + var mainWindow = Application.Current.MainWindow; + mainWindow.Visibility = Visibility.Visible; + mainWindow.Focus(); + shouldHideWindow = false; return; diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json b/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json index fa916a29d..08dab6fbf 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json @@ -6,7 +6,7 @@ "Name": "Plugins Manager", "Description": "Management of installing, uninstalling or updating Flow Launcher plugins", "Author": "Jeremy Wu", - "Version": "1.8.4", + "Version": "1.8.5", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll", From 2a06cb989300a1334b5871ff004a45ebbe4ecf5a Mon Sep 17 00:00:00 2001 From: Jeremy Date: Wed, 4 Aug 2021 08:01:20 +1000 Subject: [PATCH 09/25] fix file path tool tip as file path instead --- Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 2 +- Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index d0f78e14d..dbc1faad9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -144,7 +144,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search return true; }, TitleToolTip = Constants.ToolTipOpenContainingFolder, - SubTitleToolTip = Constants.ToolTipOpenContainingFolder, + SubTitleToolTip = filePath, ContextData = new SearchResult { Type = ResultType.File, diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json index 9f2715188..1881eff31 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json @@ -9,7 +9,7 @@ "Name": "Explorer", "Description": "Search and manage files and folders. Explorer utilises Windows Index Search", "Author": "Jeremy Wu", - "Version": "1.8.3", + "Version": "1.8.4", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll", From 7ada219c0c3fba3cf855f4ab9126058d50be0b5b Mon Sep 17 00:00:00 2001 From: pc223 <10551242+pc223@users.noreply.github.com> Date: Wed, 4 Aug 2021 22:12:11 +0700 Subject: [PATCH 10/25] Fix tool tip for folder --- Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index dbc1faad9..3130eebf7 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -52,7 +52,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search }, Score = score, TitleToolTip = Constants.ToolTipOpenDirectory, - SubTitleToolTip = Constants.ToolTipOpenDirectory, + SubTitleToolTip = subtitle, ContextData = new SearchResult { Type = ResultType.Folder, From 760333520c248493a25e37bff730bc8ce1a21ed8 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Fri, 6 Aug 2021 14:35:14 +0800 Subject: [PATCH 11/25] Adjust JsonRPCPlugin.cs Exception Handling --- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 70 ++++++---------------- 1 file changed, 18 insertions(+), 52 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index 22f547a5a..d8dc2f420 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -40,15 +40,7 @@ namespace Flow.Launcher.Core.Plugin public List LoadContextMenus(Result selectedResult) { var output = ExecuteContextMenu(selectedResult); - try - { - return DeserializedResult(output); - } - catch (Exception e) - { - Log.Exception($"|JsonRPCPlugin.LoadContextMenus|Exception on result <{selectedResult}>", e); - return null; - } + return DeserializedResult(output); } private static readonly JsonSerializerOptions options = new() @@ -65,23 +57,10 @@ namespace Flow.Launcher.Core.Plugin { if (output == Stream.Null) return null; - try - { - var queryResponseModel = - await JsonSerializer.DeserializeAsync(output, options); + var queryResponseModel = + await JsonSerializer.DeserializeAsync(output, options); - return ParseResults(queryResponseModel); - } - catch (JsonException e) - { - Log.Exception(GetType().FullName, "Unexpected Json Input", e); - } - finally - { - await output.DisposeAsync(); - } - - return null; + return ParseResults(queryResponseModel); } private List DeserializedResult(string output) @@ -249,12 +228,14 @@ namespace Flow.Launcher.Core.Plugin await using var source = process.StandardOutput.BaseStream; var buffer = BufferManager.GetStream(); - + token.Register(() => { // ReSharper disable once AccessToModifiedClosure // Manually Check whether disposed + // ReSharper disable once AccessToDisposedClosure if (!disposed && !process.HasExited) + // ReSharper disable once AccessToDisposedClosure process.Kill(); }); @@ -274,6 +255,14 @@ namespace Flow.Launcher.Core.Plugin token.ThrowIfCancellationRequested(); + if (buffer.Length == 0) + { + var errorMessage = process.StandardError.EndOfStream ? + "Empty JSONRPC Response" : + await process.StandardError.ReadToEndAsync(); + throw new InvalidDataException($"{context.CurrentPluginMetadata.Name}|{errorMessage}"); + } + if (!process.StandardError.EndOfStream) { using var standardError = process.StandardError; @@ -281,23 +270,12 @@ namespace Flow.Launcher.Core.Plugin if (!string.IsNullOrEmpty(error)) { - Log.Error($"|JsonRPCPlugin.ExecuteAsync|{error}"); - return Stream.Null; + Log.Error($"|{context.CurrentPluginMetadata.Name}.{nameof(ExecuteAsync)}|{error}"); } - - Log.Error("|JsonRPCPlugin.ExecuteAsync|Empty standard output and standard error."); - return Stream.Null; } return buffer; } - catch (Exception e) - { - Log.Exception( - $"|JsonRPCPlugin.ExecuteAsync|Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", - e); - return Stream.Null; - } finally { process?.Dispose(); @@ -307,20 +285,8 @@ namespace Flow.Launcher.Core.Plugin public async Task> QueryAsync(Query query, CancellationToken token) { - try - { - var output = await ExecuteQueryAsync(query, token); - return await DeserializedResultAsync(output); - } - catch (OperationCanceledException) - { - return null; - } - catch (Exception e) - { - Log.Exception($"|JsonRPCPlugin.Query|Exception when query <{query}>", e); - return null; - } + var output = await ExecuteQueryAsync(query, token); + return await DeserializedResultAsync(output); } public virtual Task InitAsync(PluginInitContext context) From 235fe4aacbebb9aa3f1a11e60364f99e415909b6 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Sat, 7 Aug 2021 13:26:11 +1000 Subject: [PATCH 12/25] remove extra comments --- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index d8dc2f420..ae15d23a8 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -233,7 +233,6 @@ namespace Flow.Launcher.Core.Plugin { // ReSharper disable once AccessToModifiedClosure // Manually Check whether disposed - // ReSharper disable once AccessToDisposedClosure if (!disposed && !process.HasExited) // ReSharper disable once AccessToDisposedClosure process.Kill(); @@ -295,4 +294,4 @@ namespace Flow.Launcher.Core.Plugin return Task.CompletedTask; } } -} \ No newline at end of file +} From 77784492391221dc5544d72ba4fcb596c25c7ea5 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Sat, 7 Aug 2021 13:26:38 +1000 Subject: [PATCH 13/25] remove extra comments --- Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs index ae15d23a8..0df853a5d 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs @@ -234,7 +234,6 @@ namespace Flow.Launcher.Core.Plugin // ReSharper disable once AccessToModifiedClosure // Manually Check whether disposed if (!disposed && !process.HasExited) - // ReSharper disable once AccessToDisposedClosure process.Kill(); }); From 653dc83bd08819308e9a66bf3badeb9e4dc847e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BC=98=E9=9F=AC?= Date: Sun, 8 Aug 2021 13:45:18 +0800 Subject: [PATCH 14/25] fix error thrown in checking cache key when key is null --- Flow.Launcher.Infrastructure/Image/ImageCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 66104e806..4d11abe23 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -84,7 +84,7 @@ namespace Flow.Launcher.Infrastructure.Image public bool ContainsKey(string key) { - return Data.ContainsKey(key) && Data[key].imageSource != null; + return key is not null && Data.ContainsKey(key) && Data[key].imageSource != null; } public int CacheSize() From 3623e119d2be16c1c10668340978cb74de886732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BC=98=E9=9F=AC?= Date: Sun, 8 Aug 2021 13:46:31 +0800 Subject: [PATCH 15/25] add configureAwait(false) in SliceExtra ImageCache --- Flow.Launcher.Infrastructure/Image/ImageCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 4d11abe23..13277c7d9 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -70,7 +70,7 @@ namespace Flow.Launcher.Infrastructure.Image // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time if (Data.Count > permissibleFactor * MaxCached) { - await semaphore.WaitAsync(); + await semaphore.WaitAsync().ConfigureAwait(false); // To delete the images from the data dictionary based on the resizing of the Usage Dictionary // Double Check to avoid concurrent remove if (Data.Count > permissibleFactor * MaxCached) From d536b6fd77aee1452837da78cb2c05dc8b86716d Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 8 Aug 2021 18:47:39 +1000 Subject: [PATCH 16/25] change to path instead of subtitle parameter --- Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index 3130eebf7..09315d9dd 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -52,7 +52,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search }, Score = score, TitleToolTip = Constants.ToolTipOpenDirectory, - SubTitleToolTip = subtitle, + SubTitleToolTip = path, ContextData = new SearchResult { Type = ResultType.Folder, From 2282f043329615c29f2c11bb54209e007e1e31c7 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 11 Aug 2021 19:47:25 +1000 Subject: [PATCH 17/25] fix WinGet publish due to change installer name fix WinGet publish due to change installer name in 1.8.2 release --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a764edbfd..8f0ceee5b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -79,5 +79,5 @@ on_success: if ($env:APPVEYOR_REPO_BRANCH -eq "master" -and $env:APPVEYOR_REPO_TAG -eq "true") { iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe - .\wingetcreate.exe update Flow-Launcher.Flow-Launcher -s true -u https://github.com/Flow-Launcher/Flow.Launcher/releases/download/v$env:flowVersion/Flow-Launcher-v$env:flowVersion.exe -v $env:flowVersion -t $env:winget_token + .\wingetcreate.exe update Flow-Launcher.Flow-Launcher -s true -u https://github.com/Flow-Launcher/Flow.Launcher/releases/download/v$env:flowVersion/Flow-Launcher-Setup.exe -v $env:flowVersion -t $env:winget_token } From 267fb6551b2f5d71107ed0efb7f51497d76b2c27 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Wed, 1 Sep 2021 21:10:52 +1000 Subject: [PATCH 18/25] add File Content Search Enabled status property --- .../Search/SearchManager.cs | 6 +++--- Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 15 ++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index d367eddca..9256a3917 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -75,10 +75,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search keyword == Settings.SearchActionKeyword, Settings.ActionKeyword.PathSearchActionKeyword => Settings.PathSearchKeywordEnabled && keyword == Settings.PathSearchActionKeyword, - Settings.ActionKeyword.FileContentSearchActionKeyword => keyword == - Settings.FileContentSearchActionKeyword, + Settings.ActionKeyword.FileContentSearchActionKeyword => Settings.FileContentSearchKeywordEnabled && + keyword == Settings.FileContentSearchActionKeyword, Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexOnlySearchKeywordEnabled && - keyword == Settings.IndexSearchActionKeyword + keyword == Settings.IndexSearchActionKeyword }; } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 88656a401..e44980b23 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -25,6 +25,8 @@ namespace Flow.Launcher.Plugin.Explorer public string FileContentSearchActionKeyword { get; set; } = Constants.DefaultContentSearchActionKeyword; + public bool FileContentSearchKeywordEnabled { get; set; } = true; + public string PathSearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign; public bool PathSearchKeywordEnabled { get; set; } @@ -48,7 +50,8 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.SearchActionKeyword => SearchActionKeyword, ActionKeyword.PathSearchActionKeyword => PathSearchActionKeyword, ActionKeyword.FileContentSearchActionKeyword => FileContentSearchActionKeyword, - ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword + ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword, + _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyWord property not found") }; internal void SetActionKeyword(ActionKeyword actionKeyword, string keyword) => _ = actionKeyword switch @@ -57,15 +60,16 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.PathSearchActionKeyword => PathSearchActionKeyword = keyword, ActionKeyword.FileContentSearchActionKeyword => FileContentSearchActionKeyword = keyword, ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword = keyword, - _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "Unexpected property") + _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyWord property not found") }; - internal bool? GetActionKeywordEnabled(ActionKeyword actionKeyword) => actionKeyword switch + internal bool GetActionKeywordEnabled(ActionKeyword actionKeyword) => actionKeyword switch { ActionKeyword.SearchActionKeyword => SearchActionKeywordEnabled, ActionKeyword.PathSearchActionKeyword => PathSearchKeywordEnabled, ActionKeyword.IndexSearchActionKeyword => IndexOnlySearchKeywordEnabled, - _ => null + ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled, + _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; internal void SetActionKeywordEnabled(ActionKeyword actionKeyword, bool enable) => _ = actionKeyword switch @@ -73,7 +77,8 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.SearchActionKeyword => SearchActionKeywordEnabled = enable, ActionKeyword.PathSearchActionKeyword => PathSearchKeywordEnabled = enable, ActionKeyword.IndexSearchActionKeyword => IndexOnlySearchKeywordEnabled = enable, - _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "Unexpected property") + ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled = enable, + _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; } } \ No newline at end of file From 91564e0933945bd297da679f8279080e41861d53 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Wed, 1 Sep 2021 21:17:20 +1000 Subject: [PATCH 19/25] remove null state from action keyword Enabled status --- .../Views/ActionKeywordSetting.xaml | 2 +- .../Views/ActionKeywordSetting.xaml.cs | 10 +++++----- .../Views/ExplorerSettings.xaml.cs | 7 +++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml index 19ff624b0..a497d2b26 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml @@ -31,7 +31,7 @@ Margin="10" Grid.Row="0" Grid.Column="2" Content="{DynamicResource plugin_explorer_actionkeyword_enabled}" Width="auto" VerticalAlignment="Center" IsChecked="{Binding Enabled}" - Visibility="{Binding Visible}"/> + Visibility="{Binding EnabledVisibility}"/>