From fcbf97275406c9775149be25a8c68c606871f6e3 Mon Sep 17 00:00:00 2001 From: pc223 <10551242+pc223@users.noreply.github.com> Date: Tue, 13 Jul 2021 03:44:28 +0700 Subject: [PATCH 01/97] Testing new search order: System.Search.Rank --- .../Search/WindowsIndex/QueryConstructor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs index 20e85bbb5..808f8e7e3 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs @@ -114,7 +114,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex /// public const string QueryWhereRestrictionsForAllFilesAndFoldersSearch = "scope='file:'"; - public const string QueryOrderByFileNameRestriction = " ORDER BY System.FileName"; + public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank"; /// From 5d3b0ba2c06ceeea0f9f6cae668068bef0e7763a Mon Sep 17 00:00:00 2001 From: pc223 <10551242+pc223@users.noreply.github.com> Date: Tue, 13 Jul 2021 04:12:09 +0700 Subject: [PATCH 02/97] Should be DESC --- .../Search/WindowsIndex/QueryConstructor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs index 808f8e7e3..c42a60193 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs @@ -114,7 +114,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex /// public const string QueryWhereRestrictionsForAllFilesAndFoldersSearch = "scope='file:'"; - public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank"; + public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank DESC"; /// From 9486355102c12e4c99d00b941eda0380ce8e8716 Mon Sep 17 00:00:00 2001 From: DB P Date: Sat, 5 Apr 2025 20:14:31 +0900 Subject: [PATCH 03/97] Add check registry method --- .../SettingsPaneGeneralViewModel.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs index cec8c318c..a1b38a53c 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Windows.Forms; using CommunityToolkit.Mvvm.Input; @@ -10,6 +11,8 @@ using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; +using Microsoft.Win32; +using OpenFileDialog = System.Windows.Forms.OpenFileDialog; namespace Flow.Launcher.SettingPages.ViewModels; @@ -25,6 +28,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel _updater = updater; _portable = portable; UpdateEnumDropdownLocalizations(); + IsLegacyKoreanIMEEnabled(); } public class SearchWindowScreenData : DropdownDataGeneric { } @@ -187,6 +191,48 @@ public partial class SettingsPaneGeneralViewModel : BaseModel } } + bool IsLegacyKoreanIMEEnabled() + { + const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}"; + const string valueName = "NoTsf3Override5"; + + try + { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath)) + { + if (key != null) + { + object value = key.GetValue(valueName); + if (value != null) + { + Debug.WriteLine($"[IME DEBUG] '{valueName}' 값: {value} (타입: {value.GetType()})"); + + if (value is int intValue) + return intValue == 1; + + if (int.TryParse(value.ToString(), out int parsed)) + return parsed == 1; + } + else + { + Debug.WriteLine($"[IME DEBUG] '{valueName}' 값이 존재하지 않습니다."); + } + } + else + { + Debug.WriteLine($"[IME DEBUG] 레지스트리 키를 찾을 수 없습니다: {subKeyPath}"); + } + } + } + catch (Exception ex) + { + Debug.WriteLine($"[IME DEBUG] 예외 발생: {ex.Message}"); + } + + return false; // 기본적으로 새 IME 사용 중으로 간주 + } + + public bool ShouldUsePinyin { get => Settings.ShouldUsePinyin; From 43330db96925fd595823516079168caf442cbda1 Mon Sep 17 00:00:00 2001 From: DB p Date: Sun, 6 Apr 2025 22:14:15 +0900 Subject: [PATCH 04/97] Add InfoBar Control --- Flow.Launcher/Resources/Dark.xaml | 16 ++++++++--- Flow.Launcher/Resources/Light.xaml | 14 ++++++++-- .../Views/SettingsPaneGeneral.xaml | 27 +++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml index ec089b378..1daddbfa7 100644 --- a/Flow.Launcher/Resources/Dark.xaml +++ b/Flow.Launcher/Resources/Dark.xaml @@ -114,10 +114,20 @@ - - - + + + + + + + + + + diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml index aa6da9fb2..536099546 100644 --- a/Flow.Launcher/Resources/Light.xaml +++ b/Flow.Launcher/Resources/Light.xaml @@ -105,10 +105,20 @@ - + + + + + - + + + + diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index 3f8272dda..c53edd07e 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -28,6 +28,33 @@ Style="{StaticResource PageTitle}" Text="{DynamicResource general}" TextAlignment="left" /> + + + + Date: Sun, 6 Apr 2025 23:17:56 +0900 Subject: [PATCH 05/97] Adjust Inforbar --- Flow.Launcher/Resources/Controls/InfoBar.xaml | 78 +++++++ .../Resources/Controls/InfoBar.xaml.cs | 219 ++++++++++++++++++ .../Views/SettingsPaneGeneral.xaml | 13 +- 3 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 Flow.Launcher/Resources/Controls/InfoBar.xaml create mode 100644 Flow.Launcher/Resources/Controls/InfoBar.xaml.cs diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml b/Flow.Launcher/Resources/Controls/InfoBar.xaml new file mode 100644 index 000000000..1713b3459 --- /dev/null +++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + public GlyphInfo Glyph { get; init; } - /// /// An action to take in the form of a function call when the result has been selected. /// @@ -143,7 +142,7 @@ namespace Flow.Launcher.Plugin /// public string PluginDirectory { - get { return _pluginDirectory; } + get => _pluginDirectory; set { _pluginDirectory = value; From 471c3edc6fc679ebfb5b72f5be9ed418c3575bba Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:21:11 +0800 Subject: [PATCH 31/97] Add BadgePath & BadgeIcon property --- Flow.Launcher.Plugin/Result.cs | 150 ++++++++++++++--------- Flow.Launcher/ViewModel/MainViewModel.cs | 11 +- 2 files changed, 102 insertions(+), 59 deletions(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index 2e4befdc2..7e520175e 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -12,12 +12,19 @@ namespace Flow.Launcher.Plugin /// public class Result { + /// + /// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users. + /// + public const int MaxScore = int.MaxValue; + private string _pluginDirectory; private string _icoPath; private string _copyText = string.Empty; + private string _badgePath; + /// /// The title of the result. This is always required. /// @@ -80,6 +87,33 @@ namespace Flow.Launcher.Plugin } } + /// + /// The image to be displayed for the badge of the result. + /// + /// Can be a local file path or a URL. + /// If null or empty, will use plugin icon + public string BadgePath + { + get => _badgePath; + set + { + // As a standard this property will handle prepping and converting to absolute local path for icon image processing + if (!string.IsNullOrEmpty(value) + && !string.IsNullOrEmpty(PluginDirectory) + && !Path.IsPathRooted(value) + && !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase) + && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase) + && !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase)) + { + _badgePath = Path.Combine(PluginDirectory, value); + } + else + { + _badgePath = value; + } + } + } + /// /// Determines if Icon has a border radius /// @@ -94,7 +128,12 @@ namespace Flow.Launcher.Plugin /// /// Delegate to load an icon for this result. /// - public IconDelegate Icon; + public IconDelegate Icon { get; set; } + + /// + /// Delegate to load an icon for the badge of this result. + /// + public IconDelegate BadgeIcon { get; set; } /// /// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons) @@ -154,47 +193,6 @@ namespace Flow.Launcher.Plugin } } - /// - public override string ToString() - { - return Title + SubTitle + Score; - } - - /// - /// Clones the current result - /// - public Result Clone() - { - return new Result - { - Title = Title, - SubTitle = SubTitle, - ActionKeywordAssigned = ActionKeywordAssigned, - CopyText = CopyText, - AutoCompleteText = AutoCompleteText, - IcoPath = IcoPath, - RoundedIcon = RoundedIcon, - Icon = Icon, - Glyph = Glyph, - Action = Action, - AsyncAction = AsyncAction, - Score = Score, - TitleHighlightData = TitleHighlightData, - OriginQuery = OriginQuery, - PluginDirectory = PluginDirectory, - ContextData = ContextData, - PluginID = PluginID, - TitleToolTip = TitleToolTip, - SubTitleToolTip = SubTitleToolTip, - PreviewPanel = PreviewPanel, - ProgressBar = ProgressBar, - ProgressBarColor = ProgressBarColor, - Preview = Preview, - AddSelectedCount = AddSelectedCount, - RecordKey = RecordKey - }; - } - /// /// Additional data associated with this result /// @@ -223,16 +221,6 @@ namespace Flow.Launcher.Plugin /// public Lazy PreviewPanel { get; set; } - /// - /// Run this result, asynchronously - /// - /// - /// - public ValueTask ExecuteAsync(ActionContext context) - { - return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false); - } - /// /// Progress bar display. Providing an int value between 0-100 will trigger the progress bar to be displayed on the result /// @@ -254,11 +242,6 @@ namespace Flow.Launcher.Plugin /// public bool AddSelectedCount { get; set; } = true; - /// - /// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users. - /// - public const int MaxScore = int.MaxValue; - /// /// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records. /// This can be useful when your plugin will change the Title or SubTitle of the result dynamically. @@ -267,6 +250,59 @@ namespace Flow.Launcher.Plugin /// public string RecordKey { get; set; } = null; + /// + /// Run this result, asynchronously + /// + /// + /// + public ValueTask ExecuteAsync(ActionContext context) + { + return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false); + } + + /// + public override string ToString() + { + return Title + SubTitle + Score; + } + + /// + /// Clones the current result + /// + public Result Clone() + { + return new Result + { + Title = Title, + SubTitle = SubTitle, + ActionKeywordAssigned = ActionKeywordAssigned, + CopyText = CopyText, + AutoCompleteText = AutoCompleteText, + IcoPath = IcoPath, + BadgePath = BadgePath, + RoundedIcon = RoundedIcon, + Icon = Icon, + BadgeIcon = BadgeIcon, + Glyph = Glyph, + Action = Action, + AsyncAction = AsyncAction, + Score = Score, + TitleHighlightData = TitleHighlightData, + OriginQuery = OriginQuery, + PluginDirectory = PluginDirectory, + ContextData = ContextData, + PluginID = PluginID, + TitleToolTip = TitleToolTip, + SubTitleToolTip = SubTitleToolTip, + PreviewPanel = PreviewPanel, + ProgressBar = ProgressBar, + ProgressBarColor = ProgressBarColor, + Preview = Preview, + AddSelectedCount = AddSelectedCount, + RecordKey = RecordKey + }; + } + /// /// Info of the preview section of a /// diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 4a6c1d639..38efca72b 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1268,8 +1268,7 @@ namespace Flow.Launcher.ViewModel // Task.Yield will force it to run in ThreadPool await Task.Yield(); - IReadOnlyList results = - await PluginManager.QueryForPluginAsync(plugin, query, token); + var results = await PluginManager.QueryForPluginAsync(plugin, query, token); if (token.IsCancellationRequested) return; @@ -1285,6 +1284,14 @@ namespace Flow.Launcher.ViewModel resultsCopy = DeepCloneResults(results, token); } + foreach (var result in results) + { + if (string.IsNullOrEmpty(result.BadgePath)) + { + result.BadgePath = plugin.Metadata.IcoPath; + } + } + if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query, token, reSelect))) { From b85c2f48f9a3233991671971b9207996582b177d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:35:36 +0800 Subject: [PATCH 32/97] Add related settings in appreance page --- .../UserSettings/Settings.cs | 2 +- Flow.Launcher/Languages/en.xaml | 2 ++ .../SettingPages/Views/SettingsPaneTheme.xaml | 16 ++++++++++++++-- Flow.Launcher/ViewModel/ResultViewModel.cs | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index b48f047c5..d97a9ed1a 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -101,7 +101,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public bool UseAnimation { get; set; } = true; public bool UseSound { get; set; } = true; public double SoundVolume { get; set; } = 50; - public bool ShowPluginBadges { get; set; } = false; + public bool ShowBadges { get; set; } = false; public bool UseClock { get; set; } = true; public bool UseDate { get; set; } = false; diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 609859d0d..66721d828 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -283,6 +283,8 @@ Use Segoe Fluent Icons Use Segoe Fluent Icons for query results where supported Press Key + Show Result Badges + Show badges for query results where supported HTTP Proxy diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml index 49306cd2d..574002a05 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml @@ -698,11 +698,10 @@ - + + + + + + Settings.ShowPluginBadges ? Visibility.Visible : Visibility.Collapsed; + get => Settings.ShowBadges ? Visibility.Visible : Visibility.Collapsed; } private bool GlyphAvailable => Glyph is not null; From 9e3e0f6e3c561b1106e63e0439162ec3df33a60f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:38:00 +0800 Subject: [PATCH 33/97] Change name to BadgeIcoPath --- Flow.Launcher.Plugin/Result.cs | 12 ++++++------ Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index 7e520175e..70d11dadd 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -23,7 +23,7 @@ namespace Flow.Launcher.Plugin private string _copyText = string.Empty; - private string _badgePath; + private string _badgeIcoPath; /// /// The title of the result. This is always required. @@ -92,9 +92,9 @@ namespace Flow.Launcher.Plugin /// /// Can be a local file path or a URL. /// If null or empty, will use plugin icon - public string BadgePath + public string BadgeIcoPath { - get => _badgePath; + get => _badgeIcoPath; set { // As a standard this property will handle prepping and converting to absolute local path for icon image processing @@ -105,11 +105,11 @@ namespace Flow.Launcher.Plugin && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase) && !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase)) { - _badgePath = Path.Combine(PluginDirectory, value); + _badgeIcoPath = Path.Combine(PluginDirectory, value); } else { - _badgePath = value; + _badgeIcoPath = value; } } } @@ -279,7 +279,7 @@ namespace Flow.Launcher.Plugin CopyText = CopyText, AutoCompleteText = AutoCompleteText, IcoPath = IcoPath, - BadgePath = BadgePath, + BadgeIcoPath = BadgeIcoPath, RoundedIcon = RoundedIcon, Icon = Icon, BadgeIcon = BadgeIcon, diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 38efca72b..0abd14ec5 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1286,9 +1286,9 @@ namespace Flow.Launcher.ViewModel foreach (var result in results) { - if (string.IsNullOrEmpty(result.BadgePath)) + if (string.IsNullOrEmpty(result.BadgeIcoPath)) { - result.BadgePath = plugin.Metadata.IcoPath; + result.BadgeIcoPath = plugin.Metadata.IcoPath; } } From d338c5551d9cf136fffcf74e269f3446215a09e4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:47:41 +0800 Subject: [PATCH 34/97] Fix badge icon url issue --- Flow.Launcher.Plugin/Result.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index 70d11dadd..ac00d5af5 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -188,8 +188,9 @@ namespace Flow.Launcher.Plugin // When the Result object is returned from the query call, PluginDirectory is not provided until // UpdatePluginMetadata call is made at PluginManager.cs L196. Once the PluginDirectory becomes available - // we need to update (only if not Uri path) the IcoPath with the full absolute path so the image can be loaded. + // we need to update (only if not Uri path) the IcoPath and BadgeIcoPath with the full absolute path so the image can be loaded. IcoPath = _icoPath; + BadgeIcoPath = _badgeIcoPath; } } From a1ce6b348dbc679bed986de05447e8fb86d7e21b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:48:49 +0800 Subject: [PATCH 35/97] Fix result badge ico path update issue --- 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 0abd14ec5..c1a237c6a 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1284,7 +1284,7 @@ namespace Flow.Launcher.ViewModel resultsCopy = DeepCloneResults(results, token); } - foreach (var result in results) + foreach (var result in resultsCopy) { if (string.IsNullOrEmpty(result.BadgeIcoPath)) { From ec99a365b9d27a708464b4506a41d55259c15961 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:49:39 +0800 Subject: [PATCH 36/97] Support badge path for result update interface --- Flow.Launcher/ViewModel/MainViewModel.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index c1a237c6a..2155f7bf8 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -245,6 +245,14 @@ namespace Flow.Launcher.ViewModel // make a clone to avoid possible issue that plugin will also change the list and items when updating view model var resultsCopy = DeepCloneResults(e.Results, token); + foreach (var result in resultsCopy) + { + if (string.IsNullOrEmpty(result.BadgeIcoPath)) + { + result.BadgeIcoPath = pair.Metadata.IcoPath; + } + } + PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query); if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query, token))) From 2eda64aa7af74dad5f3cf21fda8e8a8e6230fe64 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 15:51:26 +0800 Subject: [PATCH 37/97] Support badge icon loading --- Flow.Launcher/ResultListBox.xaml | 2 +- Flow.Launcher/ViewModel/ResultViewModel.cs | 46 ++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index 03bff03eb..63c461c43 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -145,7 +145,7 @@ HorizontalAlignment="Right" VerticalAlignment="Bottom" RenderOptions.BitmapScalingMode="Fant" - Source="{Binding Image, TargetNullValue={x:Null}}" + Source="{Binding BadgeImage, TargetNullValue={x:Null}}" Visibility="{Binding ShowBadge}" /> diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 61e228de1..4137d5f58 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -125,13 +125,21 @@ namespace Flow.Launcher.ViewModel public Visibility ShowBadge { - get => Settings.ShowBadges ? Visibility.Visible : Visibility.Collapsed; + get + { + if (Settings.ShowBadges && BadgeIconAvailable) + return Visibility.Visible; + + return Visibility.Collapsed; + } } private bool GlyphAvailable => Glyph is not null; private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null; + private bool BadgeIconAvailable => !string.IsNullOrEmpty(Result.BadgeIcoPath) || Result.BadgeIcon is not null; + private bool PreviewImageAvailable => !string.IsNullOrEmpty(Result.Preview.PreviewImagePath) || Result.Preview.PreviewDelegate != null; public string OpenResultModifiers => Settings.OpenResultModifiers; @@ -145,9 +153,11 @@ namespace Flow.Launcher.ViewModel : Result.SubTitleToolTip; private volatile bool _imageLoaded; + private volatile bool _badgeImageLoaded; private volatile bool _previewImageLoaded; private ImageSource _image = ImageLoader.LoadingImage; + private ImageSource _badgeImage = ImageLoader.LoadingImage; private ImageSource _previewImage = ImageLoader.LoadingImage; public ImageSource Image @@ -165,6 +175,21 @@ namespace Flow.Launcher.ViewModel private set => _image = value; } + public ImageSource BadgeImage + { + get + { + if (!_badgeImageLoaded) + { + _badgeImageLoaded = true; + _ = LoadBadgeImageAsync(); + } + + return _badgeImage; + } + private set => _badgeImage = value; + } + public ImageSource PreviewImage { get @@ -210,7 +235,7 @@ namespace Flow.Launcher.ViewModel { var imagePath = Result.IcoPath; var iconDelegate = Result.Icon; - if (ImageLoader.TryGetValue(imagePath, false, out ImageSource img)) + if (ImageLoader.TryGetValue(imagePath, false, out var img)) { _image = img; } @@ -221,11 +246,26 @@ namespace Flow.Launcher.ViewModel } } + private async Task LoadBadgeImageAsync() + { + var badgeImagePath = Result.BadgeIcoPath; + var badgeIconDelegate = Result.BadgeIcon; + if (ImageLoader.TryGetValue(badgeImagePath, false, out var img)) + { + _badgeImage = img; + } + else + { + // We need to modify the property not field here to trigger the OnPropertyChanged event + BadgeImage = await LoadImageInternalAsync(badgeImagePath, badgeIconDelegate, false).ConfigureAwait(false); + } + } + private async Task LoadPreviewImageAsync() { var imagePath = Result.Preview.PreviewImagePath ?? Result.IcoPath; var iconDelegate = Result.Preview.PreviewDelegate ?? Result.Icon; - if (ImageLoader.TryGetValue(imagePath, true, out ImageSource img)) + if (ImageLoader.TryGetValue(imagePath, true, out var img)) { _previewImage = img; } From 01f896a57844184fb24e883fe5939c9689d96403 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 16:11:39 +0800 Subject: [PATCH 38/97] Support global query only --- .../UserSettings/Settings.cs | 1 + Flow.Launcher/Languages/en.xaml | 2 ++ .../SettingPages/Views/SettingsPaneTheme.xaml | 23 ++++++++++++++----- Flow.Launcher/ViewModel/ResultViewModel.cs | 11 ++++++--- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index d97a9ed1a..7c2457a72 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -102,6 +102,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public bool UseSound { get; set; } = true; public double SoundVolume { get; set; } = 50; public bool ShowBadges { get; set; } = false; + public bool ShowBadgesGlobalOnly { get; set; } = false; public bool UseClock { get; set; } = true; public bool UseDate { get; set; } = false; diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 66721d828..87db45fbe 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -285,6 +285,8 @@ Press Key Show Result Badges Show badges for query results where supported + Show Result Badges Only for Global Query + Show badges only for global query results HTTP Proxy diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml index 574002a05..57c9a5b70 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml @@ -711,16 +711,27 @@ - - - + + + + + + + Result.OriginQuery.ActionKeyword == Query.GlobalPluginWildcardSign; + private bool GlyphAvailable => Glyph is not null; private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null; From e6477e886b3e3589727fa8481dd92a98a6206df4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 16:13:55 +0800 Subject: [PATCH 39/97] Fix global query determination issue --- Flow.Launcher/ViewModel/MainViewModel.cs | 6 +++--- Flow.Launcher/ViewModel/ResultViewModel.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 2155f7bf8..f6b9aa67c 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -1208,11 +1208,11 @@ namespace Flow.Launcher.ViewModel _lastQuery = query; - if (query.ActionKeyword == Plugin.Query.GlobalPluginWildcardSign) + if (string.IsNullOrEmpty(query.ActionKeyword)) { - // Wait 45 millisecond for query change in global query + // Wait 15 millisecond for query change in global query // if query changes, return so that it won't be calculated - await Task.Delay(45, _updateSource.Token); + await Task.Delay(15, _updateSource.Token); if (_updateSource.Token.IsCancellationRequested) return; } diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 27b385805..68c794aec 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Drawing.Text; using System.IO; @@ -137,7 +138,7 @@ namespace Flow.Launcher.ViewModel } } - public bool IsGlobalQuery => Result.OriginQuery.ActionKeyword == Query.GlobalPluginWildcardSign; + public bool IsGlobalQuery => string.IsNullOrEmpty(Result.OriginQuery.ActionKeyword); private bool GlyphAvailable => Glyph is not null; From 8aff3c9f2ae49358d59760675c4ab552da865ad4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 16:14:23 +0800 Subject: [PATCH 40/97] Improve strings --- Flow.Launcher/Languages/en.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 87db45fbe..024258f1b 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -285,8 +285,8 @@ Press Key Show Result Badges Show badges for query results where supported - Show Result Badges Only for Global Query - Show badges only for global query results + Show Result Badges for Global Query Only + Show badges for global query results only HTTP Proxy From c1893366982d2f7d729a0cbdca6363c1d5b1218c Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 16:46:45 +0800 Subject: [PATCH 41/97] Fix possible directory not found issue when saving storage --- Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 3 ++- Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs index 43bb8dade..414743d22 100644 --- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs @@ -82,8 +82,8 @@ namespace Flow.Launcher.Infrastructure.Storage public void Save() { + FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it var serialized = MemoryPackSerializer.Serialize(Data); - File.WriteAllBytes(FilePath, serialized); } @@ -103,6 +103,7 @@ namespace Flow.Launcher.Infrastructure.Storage // so we need to pass it to SaveAsync public async ValueTask SaveAsync(T data) { + FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it await using var stream = new FileStream(FilePath, FileMode.Create); await MemoryPackSerializer.SerializeAsync(stream, data); } diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs index cdf3ae909..f283be59e 100644 --- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs @@ -183,7 +183,10 @@ namespace Flow.Launcher.Infrastructure.Storage public void Save() { - string serialized = JsonSerializer.Serialize(Data, + // User may delete the directory, so we need to check it + FilesFolders.ValidateDirectory(DirectoryPath); + + var serialized = JsonSerializer.Serialize(Data, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(TempFilePath, serialized); @@ -193,6 +196,9 @@ namespace Flow.Launcher.Infrastructure.Storage public async Task SaveAsync() { + // User may delete the directory, so we need to check it + FilesFolders.ValidateDirectory(DirectoryPath); + await using var tempOutput = File.OpenWrite(TempFilePath); await JsonSerializer.SerializeAsync(tempOutput, Data, new JsonSerializerOptions { WriteIndented = true }); From 5c43dd45b236c6074f63dc314f0d3668c1653e09 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 16:48:02 +0800 Subject: [PATCH 42/97] Code quality --- Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs index 414743d22..b85111756 100644 --- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs @@ -82,7 +82,9 @@ namespace Flow.Launcher.Infrastructure.Storage public void Save() { - FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it + // User may delete the directory, so we need to check it + FilesFolders.ValidateDirectory(DirectoryPath); + var serialized = MemoryPackSerializer.Serialize(Data); File.WriteAllBytes(FilePath, serialized); } @@ -103,7 +105,9 @@ namespace Flow.Launcher.Infrastructure.Storage // so we need to pass it to SaveAsync public async ValueTask SaveAsync(T data) { - FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it + // User may delete the directory, so we need to check it + FilesFolders.ValidateDirectory(DirectoryPath); + await using var stream = new FileStream(FilePath, FileMode.Create); await MemoryPackSerializer.SerializeAsync(stream, data); } From e6377d046348058c1b32cb2905960747468a5101 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 18:40:03 +0800 Subject: [PATCH 43/97] Fix old Program plugin constructor issue --- .../Storage/BinaryStorage.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs index b85111756..64f809181 100644 --- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Threading.Tasks; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; @@ -40,6 +41,16 @@ namespace Flow.Launcher.Infrastructure.Storage FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}"); } + // Let the old Program plugin get this constructor + [Obsolete("This constructor is obsolete. Use BinaryStorage(string filename) instead.")] + public BinaryStorage(string filename, string directoryPath = null!) + { + directoryPath ??= DataLocation.CacheDirectory; + FilesFolders.ValidateDirectory(directoryPath); + + FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}"); + } + public async ValueTask TryLoadAsync(T defaultData) { if (Data != null) return Data; From 3aa324d1201a79f7bdb05e21b22775fa85195b6f Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 21:52:51 +0800 Subject: [PATCH 44/97] Throw plugin exception for plugin save interface --- Flow.Launcher.Core/Plugin/PluginManager.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 29d91dc8d..94519bf6f 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -64,7 +64,14 @@ namespace Flow.Launcher.Core.Plugin foreach (var plugin in AllPlugins) { var savable = plugin.Plugin as ISavable; - savable?.Save(); + try + { + savable?.Save(); + } + catch (Exception e) + { + throw new FlowPluginException(plugin.Metadata, e); + } } API.SavePluginSettings(); From bae0fa5c0e128538caf71943407088125289085b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 22:00:36 +0800 Subject: [PATCH 45/97] Improve code quality --- Flow.Launcher.Core/Plugin/PluginManager.cs | 8 ++++---- .../Resource/Internationalization.cs | 17 ++++++++--------- Flow.Launcher/PublicAPIInstance.cs | 14 ++++++++------ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 94519bf6f..1d13dcfd3 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -37,7 +37,7 @@ namespace Flow.Launcher.Core.Plugin private static PluginsSettings Settings; private static List _metadatas; - private static List _modifiedPlugins = new(); + private static readonly List _modifiedPlugins = new(); /// /// Directories that will hold Flow Launcher plugin directory @@ -299,7 +299,7 @@ namespace Flow.Launcher.Core.Plugin { Title = $"{metadata.Name}: Failed to respond!", SubTitle = "Select this result for more info", - IcoPath = Flow.Launcher.Infrastructure.Constant.ErrorIcon, + IcoPath = Constant.ErrorIcon, PluginDirectory = metadata.PluginDirectory, ActionKeywordAssigned = query.ActionKeyword, PluginID = metadata.ID, @@ -376,8 +376,8 @@ namespace Flow.Launcher.Core.Plugin { // this method is only checking for action keywords (defined as not '*') registration // hence the actionKeyword != Query.GlobalPluginWildcardSign logic - return actionKeyword != Query.GlobalPluginWildcardSign - && NonGlobalPlugins.ContainsKey(actionKeyword); + return actionKeyword != Query.GlobalPluginWildcardSign + && NonGlobalPlugins.ContainsKey(actionKeyword); } /// diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index ffa17ab4d..df841dbbe 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -22,8 +22,8 @@ namespace Flow.Launcher.Core.Resource private const string DefaultFile = "en.xaml"; private const string Extension = ".xaml"; private readonly Settings _settings; - private readonly List _languageDirectories = new List(); - private readonly List _oldResources = new List(); + private readonly List _languageDirectories = new(); + private readonly List _oldResources = new(); private readonly string SystemLanguageCode; public Internationalization(Settings settings) @@ -144,7 +144,7 @@ namespace Flow.Launcher.Core.Resource _settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode; } - private Language GetLanguageByLanguageCode(string languageCode) + private static Language GetLanguageByLanguageCode(string languageCode) { var lowercase = languageCode.ToLower(); var language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == lowercase); @@ -239,7 +239,7 @@ namespace Flow.Launcher.Core.Resource return list; } - public string GetTranslation(string key) + public static string GetTranslation(string key) { var translation = Application.Current.TryFindResource(key); if (translation is string) @@ -257,8 +257,7 @@ namespace Flow.Launcher.Core.Resource { foreach (var p in PluginManager.GetPluginsForInterface()) { - var pluginI18N = p.Plugin as IPluginI18n; - if (pluginI18N == null) return; + if (p.Plugin is not IPluginI18n pluginI18N) return; try { p.Metadata.Name = pluginI18N.GetTranslatedPluginTitle(); @@ -272,11 +271,11 @@ namespace Flow.Launcher.Core.Resource } } - public string LanguageFile(string folder, string language) + private static string LanguageFile(string folder, string language) { if (Directory.Exists(folder)) { - string path = Path.Combine(folder, language); + var path = Path.Combine(folder, language); if (File.Exists(path)) { return path; @@ -284,7 +283,7 @@ namespace Flow.Launcher.Core.Resource else { Log.Error($"|Internationalization.LanguageFile|Language path can't be found <{path}>"); - string english = Path.Combine(folder, DefaultFile); + var english = Path.Combine(folder, DefaultFile); if (File.Exists(english)) { return english; diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 95ef6c9f3..5438eac7d 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -38,20 +38,23 @@ namespace Flow.Launcher public class PublicAPIInstance : IPublicAPI, IRemovable { private readonly Settings _settings; - private readonly Internationalization _translater; private readonly MainViewModel _mainVM; + // Must use getter to access Application.Current.Resources.MergedDictionaries so earlier private Theme _theme; private Theme Theme => _theme ??= Ioc.Default.GetRequiredService(); + // Must use getter to avoid circular dependency + private Updater _updater; + private Updater Updater => _updater ??= Ioc.Default.GetRequiredService(); + private readonly object _saveSettingsLock = new(); #region Constructor - public PublicAPIInstance(Settings settings, Internationalization translater, MainViewModel mainVM) + public PublicAPIInstance(Settings settings, MainViewModel mainVM) { _settings = settings; - _translater = translater; _mainVM = mainVM; GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback; WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); @@ -100,8 +103,7 @@ namespace Flow.Launcher remove => _mainVM.VisibilityChanged -= value; } - // Must use Ioc.Default.GetRequiredService() to avoid circular dependency - public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false); + public void CheckForNewUpdate() => _ = Updater.UpdateAppAsync(false); public void SaveAppAllSettings() { @@ -178,7 +180,7 @@ namespace Flow.Launcher public void StopLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Collapsed; - public string GetTranslation(string key) => _translater.GetTranslation(key); + public string GetTranslation(string key) => Internationalization.GetTranslation(key); public List GetAllPlugins() => PluginManager.AllPlugins.ToList(); From 526f00261d2ccf9a148aec46d92708affef2e4d4 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 22:02:03 +0800 Subject: [PATCH 46/97] Throw plugin exception for plugin dispose interface --- Flow.Launcher.Core/Plugin/PluginManager.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 1d13dcfd3..f8a094575 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -88,14 +88,21 @@ namespace Flow.Launcher.Core.Plugin private static async Task DisposePluginAsync(PluginPair pluginPair) { - switch (pluginPair.Plugin) + try { - case IDisposable disposable: - disposable.Dispose(); - break; - case IAsyncDisposable asyncDisposable: - await asyncDisposable.DisposeAsync(); - break; + switch (pluginPair.Plugin) + { + case IDisposable disposable: + disposable.Dispose(); + break; + case IAsyncDisposable asyncDisposable: + await asyncDisposable.DisposeAsync(); + break; + } + } + catch (Exception e) + { + throw new FlowPluginException(pluginPair.Metadata, e); } } From deb22ad0fe02820dcdfe6431793e7ee9ecdf1d75 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 22:05:04 +0800 Subject: [PATCH 47/97] Set CanClose earlier --- Flow.Launcher/MainWindow.xaml.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 30afe67a1..bf7a45b1d 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -291,15 +291,15 @@ namespace Flow.Launcher { if (!CanClose) { + CanClose = true; _notifyIcon.Visible = false; App.API.SaveAppAllSettings(); e.Cancel = true; await ImageLoader.WaitSaveAsync(); await PluginManager.DisposePluginsAsync(); Notification.Uninstall(); - // After plugins are all disposed, we can close the main window - CanClose = true; - // Use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event + // After plugins are all disposed, we shutdown application to close app + // We use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event Application.Current.Shutdown(); } } From 58c3b73ff7d65078185e7072fbac379fc823021a Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 22:13:58 +0800 Subject: [PATCH 48/97] Fix directory path issue --- Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 6 +++--- .../Storage/FlowLauncherJsonStorage.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs index 64f809181..8ff10816c 100644 --- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs @@ -45,10 +45,10 @@ namespace Flow.Launcher.Infrastructure.Storage [Obsolete("This constructor is obsolete. Use BinaryStorage(string filename) instead.")] public BinaryStorage(string filename, string directoryPath = null!) { - directoryPath ??= DataLocation.CacheDirectory; - FilesFolders.ValidateDirectory(directoryPath); + DirectoryPath = directoryPath ?? DataLocation.CacheDirectory; + FilesFolders.ValidateDirectory(DirectoryPath); - FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}"); + FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}"); } public async ValueTask TryLoadAsync(T defaultData) diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs index 8b4062b6b..ca78b2f20 100644 --- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs @@ -17,11 +17,11 @@ namespace Flow.Launcher.Infrastructure.Storage public FlowLauncherJsonStorage() { - var directoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName); - FilesFolders.ValidateDirectory(directoryPath); + DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName); + FilesFolders.ValidateDirectory(DirectoryPath); var filename = typeof(T).Name; - FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}"); + FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}"); } public new void Save() From 4527b334331a64b8ede630e84447de438f83cf5d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 11 Apr 2025 22:16:04 +0800 Subject: [PATCH 49/97] Code quality --- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 1de5841a5..6c506cfc0 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -264,12 +264,12 @@ namespace Flow.Launcher.Plugin.SharedCommands var index = path.LastIndexOf('\\'); if (index > 0 && index < (path.Length - 1)) { - string previousDirectoryPath = path.Substring(0, index + 1); - return locationExists(previousDirectoryPath) ? previousDirectoryPath : ""; + string previousDirectoryPath = path[..(index + 1)]; + return locationExists(previousDirectoryPath) ? previousDirectoryPath : string.Empty; } else { - return ""; + return string.Empty; } } @@ -285,7 +285,7 @@ namespace Flow.Launcher.Plugin.SharedCommands // not full path, get previous level directory string var indexOfSeparator = path.LastIndexOf('\\'); - return path.Substring(0, indexOfSeparator + 1); + return path[..(indexOfSeparator + 1)]; } return path; From c66cbae78bfa96ecbec3a627ac40bed4d2b442ca Mon Sep 17 00:00:00 2001 From: DB p Date: Sat, 12 Apr 2025 00:56:07 +0900 Subject: [PATCH 50/97] - Adjust Badge layout - Fix glyph margin in win11light --- Flow.Launcher/ResultListBox.xaml | 15 +++++---------- Flow.Launcher/Themes/Win11Light.xaml | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index 63c461c43..8231027f4 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -102,8 +102,6 @@ + + - +