From 5a80adcbfec1309b537721ab9e98f9d07187c135 Mon Sep 17 00:00:00 2001
From: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
Date: Sun, 17 Nov 2024 23:59:43 -0600
Subject: [PATCH 001/200] Send a reload request with ctx when reloading
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 5a6633525..ae4fd639d 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -133,10 +133,16 @@ namespace Flow.Launcher.Core.Plugin
RPC.StartListening();
}
- public virtual Task ReloadDataAsync()
+ public virtual async Task ReloadDataAsync()
{
SetupJsonRPC();
- return Task.CompletedTask;
+ try
+ {
+ await RPC.InvokeAsync("reload", context);
+ }
+ catch (RemoteMethodNotFoundException e)
+ {
+ }
}
public virtual async ValueTask DisposeAsync()
From fa8cd548f6c11d71cf9dbd91a5c6c1495837222b Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Thu, 5 Dec 2024 14:18:13 +0600
Subject: [PATCH 002/200] Add `.`, `./lib`, `./plugin` directories to path for
Python plugins
---
Flow.Launcher.Core/Plugin/PythonPlugin.cs | 52 ++++++++++++++++++---
Flow.Launcher.Core/Plugin/PythonPluginV2.cs | 31 +++++++++++-
2 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
index 536e69b3d..36160b920 100644
--- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
@@ -1,4 +1,5 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
@@ -29,10 +30,6 @@ namespace Flow.Launcher.Core.Plugin
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
_startInfo.EnvironmentVariables["FLOW_APPLICATION_DIRECTORY"] = Constant.ApplicationDirectory;
-
-
- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
- _startInfo.ArgumentList.Add("-B");
}
protected override Task RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
@@ -50,10 +47,51 @@ namespace Flow.Launcher.Core.Plugin
// TODO: Async Action
return Execute(_startInfo);
}
+
public override async Task InitAsync(PluginInitContext context)
{
- _startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
- _startInfo.ArgumentList.Add("");
+ // Run .py files via `-c `
+ if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
+ {
+ var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
+ var libDirectory = Path.Combine(rootDirectory, "lib");
+ var pluginDirectory = Path.Combine(rootDirectory, "plugin");
+
+ // This makes it easier for plugin authors to import their own modules.
+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
+ _startInfo.ArgumentList.Add("-c");
+ _startInfo.ArgumentList.Add(
+ $"""
+ import sys
+ sys.path.append(r'{rootDirectory}')
+ sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{pluginDirectory}')
+
+ import runpy
+ runpy.run_path(r'{context.CurrentPluginMetadata.ExecuteFilePath}', None, '__main__')
+ """
+ );
+ // Plugins always expect the JSON data to be in the third argument
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
+ _startInfo.ArgumentList.Add("");
+ // Because plugins always expect the JSON data to be in the third argument, and specifying -c
+ // takes up two arguments, we have to move `-B` to the end.
+ _startInfo.ArgumentList.Add("-B");
+ }
+ // Run .pyz files as is
+ else
+ {
+ // -B flag is needed to tell python not to write .py[co] files.
+ // Because .pyc contains location infos which will prevent python portable
+ _startInfo.ArgumentList.Add("-B");
+ _startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ // Plugins always expect the JSON data to be in the third argument
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
+ _startInfo.ArgumentList.Add("");
+ }
+
await base.InitAsync(context);
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
}
diff --git a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
index 5c36e0eea..224653ba1 100644
--- a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
@@ -33,7 +33,36 @@ namespace Flow.Launcher.Core.Plugin
public override async Task InitAsync(PluginInitContext context)
{
- StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ // Run .py files via `-c `
+ if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
+ {
+ var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
+ var libDirectory = Path.Combine(rootDirectory, "lib");
+ var pluginDirectory = Path.Combine(rootDirectory, "plugin");
+ var filePath = context.CurrentPluginMetadata.ExecuteFilePath;
+
+ // This makes it easier for plugin authors to import their own modules.
+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
+ StartInfo.ArgumentList.Add("-c");
+ StartInfo.ArgumentList.Add(
+ $"""
+ import sys
+ sys.path.append(r'{rootDirectory}')
+ sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{pluginDirectory}')
+
+ import runpy
+ runpy.run_path(r'{filePath}', None, '__main__')
+ """
+ );
+ }
+ // Run .pyz files as is
+ else
+ {
+ StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ }
await base.InitAsync(context);
}
From d5dd7b44a41322ebdd9e4e97a25e62e653775688 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Thu, 5 Dec 2024 17:37:54 +0600
Subject: [PATCH 003/200] Use PYTHONDONTWRITEBYTECODE instead of -B flag when
running Python plugins
---
Flow.Launcher.Core/Plugin/PythonPlugin.cs | 11 ++++++-----
Flow.Launcher.Core/Plugin/PythonPluginV2.cs | 4 +---
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
index 36160b920..7b670742a 100644
--- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
@@ -26,6 +26,9 @@ namespace Flow.Launcher.Core.Plugin
var path = Path.Combine(Constant.ProgramDirectory, JsonRPC);
_startInfo.EnvironmentVariables["PYTHONPATH"] = path;
+ // Prevent Python from writing .py[co] files.
+ // Because .pyc contains location infos which will prevent python portable.
+ _startInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
@@ -76,15 +79,13 @@ namespace Flow.Launcher.Core.Plugin
// Plugins always expect the JSON data to be in the third argument
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
_startInfo.ArgumentList.Add("");
- // Because plugins always expect the JSON data to be in the third argument, and specifying -c
- // takes up two arguments, we have to move `-B` to the end.
- _startInfo.ArgumentList.Add("-B");
}
// Run .pyz files as is
else
{
- // -B flag is needed to tell python not to write .py[co] files.
- // Because .pyc contains location infos which will prevent python portable
+ // No need for -B flag because we're using PYTHONDONTWRITEBYTECODE env variable now,
+ // but the plugins still expect data to be sent as the third argument, so we're keeping
+ // the flag here, even though it's not necessary anymore.
_startInfo.ArgumentList.Add("-B");
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
// Plugins always expect the JSON data to be in the third argument
diff --git a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
index 224653ba1..03ac0e661 100644
--- a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
@@ -26,9 +26,7 @@ namespace Flow.Launcher.Core.Plugin
var path = Path.Combine(Constant.ProgramDirectory, JsonRpc);
StartInfo.EnvironmentVariables["PYTHONPATH"] = path;
-
- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
- StartInfo.ArgumentList.Add("-B");
+ StartInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
}
public override async Task InitAsync(PluginInitContext context)
From 4b9c23d49bcf823641258ab003225edd9face248 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 30 Dec 2024 22:46:08 +0000
Subject: [PATCH 004/200] Bump nunit from 3.14.0 to 4.3.2
Bumps [nunit](https://github.com/nunit/nunit) from 3.14.0 to 4.3.2.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v3.14.0...4.3.2)
---
updated-dependencies:
- dependency-name: nunit
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
index 8286e142e..0241a374e 100644
--- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj
+++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
@@ -49,7 +49,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
From 921d6a3beb6a3c05ca00e6ce70a41fbf9e98b21b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 2 Jan 2025 18:47:25 +0800
Subject: [PATCH 005/200] Add support for system language item
---
.../Resource/Internationalization.cs | 51 ++++++++++++++++---
1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1505e84f8..aac6ecc1e 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,6 +18,8 @@ namespace Flow.Launcher.Core.Resource
{
public Settings Settings { get; set; }
private const string Folder = "Languages";
+ private const string SystemLanguageCode = "System";
+ private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
private readonly List _languageDirectories = new List();
@@ -68,8 +70,18 @@ namespace Flow.Launcher.Core.Resource
public void ChangeLanguage(string languageCode)
{
languageCode = languageCode.NonNull();
- Language language = GetLanguageByLanguageCode(languageCode);
- ChangeLanguage(language);
+
+ // Get actual language if language code is system
+ var isSystem = false;
+ if (languageCode == SystemLanguageCode)
+ {
+ languageCode = GetSystemLanguageCode();
+ isSystem = true;
+ }
+
+ // Get language by language code and change language
+ var language = GetLanguageByLanguageCode(languageCode);
+ ChangeLanguage(language, isSystem);
}
private Language GetLanguageByLanguageCode(string languageCode)
@@ -87,11 +99,10 @@ namespace Flow.Launcher.Core.Resource
}
}
- public void ChangeLanguage(Language language)
+ private void ChangeLanguage(Language language, bool isSystem)
{
language = language.NonNull();
-
RemoveOldLanguageFiles();
if (language != AvailableLanguages.English)
{
@@ -103,7 +114,7 @@ namespace Flow.Launcher.Core.Resource
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
- Settings.Language = language.LanguageCode;
+ Settings.Language = isSystem ? SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
@@ -167,7 +178,35 @@ namespace Flow.Launcher.Core.Resource
public List LoadAvailableLanguages()
{
- return AvailableLanguages.GetAvailableLanguages();
+ var list = AvailableLanguages.GetAvailableLanguages();
+ list.Insert(0, new Language(SystemLanguageCode, "System"));
+ return list;
+ }
+
+ private string GetSystemLanguageCode()
+ {
+ var availableLanguages = AvailableLanguages.GetAvailableLanguages();
+
+ // Retrieve the language identifiers for the current culture
+ var currentCulture = CultureInfo.CurrentCulture;
+ var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
+ var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
+ var fullName = currentCulture.Name;
+
+ // Try to find a match in the available languages list
+ foreach (var language in availableLanguages)
+ {
+ var languageCode = language.LanguageCode;
+
+ if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
+ {
+ return languageCode;
+ }
+ }
+
+ return DefaultLanguageCode;
}
public string GetTranslation(string key)
From 0ae3cfcdd6f735b6f8e16ffa0e782c394fbd2e68 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 2 Jan 2025 18:50:02 +0800
Subject: [PATCH 006/200] Add display translation for system language item
---
.../Resource/AvailableLanguages.cs | 34 ++++++++++++++++++-
.../Resource/Internationalization.cs | 2 +-
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/AvailableLanguages.cs b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
index c385cd8e8..ecaecf646 100644
--- a/Flow.Launcher.Core/Resource/AvailableLanguages.cs
+++ b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
@@ -30,7 +30,6 @@ namespace Flow.Launcher.Core.Resource
public static Language Vietnamese = new Language("vi-vn", "Tiếng Việt");
public static Language Hebrew = new Language("he", "עברית");
-
public static List GetAvailableLanguages()
{
List languages = new List
@@ -63,5 +62,38 @@ namespace Flow.Launcher.Core.Resource
};
return languages;
}
+
+ public static string GetSystemTranslation(string languageCode)
+ {
+ return languageCode switch
+ {
+ "en" => "System",
+ "zh-cn" => "系统",
+ "zh-tw" => "系統",
+ "uk-UA" => "Система",
+ "ru" => "Система",
+ "fr" => "Système",
+ "ja" => "システム",
+ "nl" => "Systeem",
+ "pl" => "System",
+ "da" => "System",
+ "de" => "System",
+ "ko" => "시스템",
+ "sr" => "Систем",
+ "pt-pt" => "Sistema",
+ "pt-br" => "Sistema",
+ "es" => "Sistema",
+ "es-419" => "Sistema",
+ "it" => "Sistema",
+ "nb-NO" => "System",
+ "sk" => "Systém",
+ "tr" => "Sistem",
+ "cs" => "Systém",
+ "ar" => "النظام",
+ "vi-vn" => "Hệ thống",
+ "he" => "מערכת",
+ _ => "System",
+ };
+ }
}
}
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index aac6ecc1e..4db3e8633 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -179,7 +179,7 @@ namespace Flow.Launcher.Core.Resource
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(SystemLanguageCode, "System"));
+ list.Insert(0, new Language(SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
return list;
}
From 37058f765185341a08007d4c713d944e25303b79 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 21:55:44 +0800
Subject: [PATCH 007/200] Improve code quality.
---
.../Flow.Launcher.Plugin.PluginsManager/Main.cs | 2 +-
.../PluginsManager.cs | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
index bec84f484..156135f81 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -51,7 +51,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return query.FirstSearch.ToLower() switch
{
//search could be url, no need ToLower() when passed in
- Settings.InstallCommand => await pluginManager.RequestInstallOrUpdate(query.SecondToEndSearch, token, query.IsReQuery),
+ Settings.InstallCommand => await pluginManager.RequestInstallOrUpdateAsync(query.SecondToEndSearch, token, query.IsReQuery),
Settings.UninstallCommand => pluginManager.RequestUninstall(query.SecondToEndSearch),
Settings.UpdateCommand => await pluginManager.RequestUpdateAsync(query.SecondToEndSearch, token, query.IsReQuery),
_ => pluginManager.GetDefaultHotKeys().Where(hotkey =>
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 305d248d3..b1b1a7502 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -324,7 +324,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
x.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
+ }, token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
return true;
},
@@ -337,7 +337,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
});
// Update all result
- if (resultsForUpdate.Count() > 1)
+ if (resultsForUpdate.Count > 1)
{
var updateAllResult = new Result
{
@@ -351,13 +351,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
message = string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"),
- resultsForUpdate.Count(), Environment.NewLine);
+ resultsForUpdate.Count, Environment.NewLine);
}
else
{
message = string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"),
- resultsForUpdate.Count());
+ resultsForUpdate.Count);
}
if (Context.API.ShowMsgBox(message,
@@ -401,7 +401,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
- resultsForUpdate.Count()));
+ resultsForUpdate.Count));
Context.API.RestartApp();
}
else
@@ -409,7 +409,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
- resultsForUpdate.Count()));
+ resultsForUpdate.Count));
}
return true;
@@ -545,7 +545,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
}
- internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token,
+ internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
From 562b233c157f2d11bc00f744f2772223037c4eb4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 23:11:13 +0800
Subject: [PATCH 008/200] Add progress box support for downloading plugin
---
Flow.Launcher.Core/ProgressBoxEx.xaml | 106 ++++++++++++++++++
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 76 +++++++++++++
.../PluginsManager.cs | 59 +++++++++-
3 files changed, 239 insertions(+), 2 deletions(-)
create mode 100644 Flow.Launcher.Core/ProgressBoxEx.xaml
create mode 100644 Flow.Launcher.Core/ProgressBoxEx.xaml.cs
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml b/Flow.Launcher.Core/ProgressBoxEx.xaml
new file mode 100644
index 000000000..4cce82221
--- /dev/null
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
new file mode 100644
index 000000000..61ba397de
--- /dev/null
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+using Flow.Launcher.Infrastructure.Logger;
+
+namespace Flow.Launcher.Core
+{
+ public partial class ProgressBoxEx : Window
+ {
+ private ProgressBoxEx()
+ {
+ InitializeComponent();
+ }
+
+ public static ProgressBoxEx Show(string caption)
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ return Application.Current.Dispatcher.Invoke(() => Show(caption));
+ }
+
+ try
+ {
+ var prgBox = new ProgressBoxEx
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ return prgBox;
+ }
+ catch (Exception e)
+ {
+ Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
+ return null;
+ }
+ }
+
+ public void ReportProgress(double progress)
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ Application.Current.Dispatcher.Invoke(() => ReportProgress(progress));
+ return;
+ }
+
+ if (progress < 0)
+ {
+ ProgressBar.Value = 0;
+ }
+ else if (progress >= 100)
+ {
+ ProgressBar.Value = 100;
+ }
+ else
+ {
+ ProgressBar.Value = progress;
+ }
+ }
+
+ private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void Button_Cancel(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index b1b1a7502..39390ae10 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -142,6 +143,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
+ ProgressBoxEx prgBox = null;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -149,7 +151,42 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (File.Exists(filePath))
File.Delete(filePath);
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ using var httpClient = new HttpClient();
+ using var response = await httpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+
+ response.EnsureSuccessStatusCode();
+
+ var totalBytes = response.Content.Headers.ContentLength ?? -1L;
+ var canReportProgress = totalBytes != -1;
+
+ if (canReportProgress && (prgBox = ProgressBoxEx.Show("Download plugin...")) != null)
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
+
+ while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
+ totalRead += read;
+
+ var progressValue = totalRead * 100 / totalBytes;
+ prgBox.ReportProgress(progressValue);
+ }
+
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox.Close();
+ prgBox = null;
+ });
+ }
+ else
+ {
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ }
}
else
{
@@ -164,6 +201,15 @@ namespace Flow.Launcher.Plugin.PluginsManager
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ // force close progress box
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (prgBox != null)
+ {
+ prgBox.Close();
+ prgBox = null;
+ }
+ });
return;
}
catch (Exception e)
@@ -172,6 +218,15 @@ namespace Flow.Launcher.Plugin.PluginsManager
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
plugin.Name));
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ // force close progress box
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (prgBox != null)
+ {
+ prgBox.Close();
+ prgBox = null;
+ }
+ });
return;
}
From 54f02e04e6d67d46152e2480d553ec7628ed9980 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:08:56 +0800
Subject: [PATCH 009/200] Use public api for ProgressBoxEx & Add support for
force close event
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 45 +++++++++++++++----
Flow.Launcher.Plugin/IProgressBoxEx.cs | 20 +++++++++
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 11 ++++-
Flow.Launcher/PublicAPIInstance.cs | 2 +
.../PluginsManager.cs | 7 ++-
5 files changed, 72 insertions(+), 13 deletions(-)
create mode 100644 Flow.Launcher.Plugin/IProgressBoxEx.cs
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 61ba397de..b6801d2c1 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -2,26 +2,31 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core
{
- public partial class ProgressBoxEx : Window
+ public partial class ProgressBoxEx : Window, IProgressBoxEx
{
- private ProgressBoxEx()
+ private readonly Action _forceClosed;
+ private bool _isClosed;
+
+ private ProgressBoxEx(Action forceClosed)
{
+ _forceClosed = forceClosed;
InitializeComponent();
}
- public static ProgressBoxEx Show(string caption)
+ public static IProgressBoxEx Show(string caption, Action forceClosed)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- return Application.Current.Dispatcher.Invoke(() => Show(caption));
+ return Application.Current.Dispatcher.Invoke(() => Show(caption, forceClosed));
}
try
{
- var prgBox = new ProgressBoxEx
+ var prgBox = new ProgressBoxEx(forceClosed)
{
Title = caption
};
@@ -51,6 +56,7 @@ namespace Flow.Launcher.Core
else if (progress >= 100)
{
ProgressBar.Value = 100;
+ Close();
}
else
{
@@ -58,19 +64,42 @@ namespace Flow.Launcher.Core
}
}
+ private new void Close()
+ {
+ if (_isClosed)
+ {
+ return;
+ }
+
+ base.Close();
+ _isClosed = true;
+ }
+
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
- Close();
+ ForceClose();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
- Close();
+ ForceClose();
}
private void Button_Cancel(object sender, RoutedEventArgs e)
{
- Close();
+ ForceClose();
+ }
+
+ private void ForceClose()
+ {
+ if (_isClosed)
+ {
+ return;
+ }
+
+ base.Close();
+ _isClosed = true;
+ _forceClosed?.Invoke();
}
}
}
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
new file mode 100644
index 000000000..0b245411f
--- /dev/null
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -0,0 +1,20 @@
+namespace Flow.Launcher.Plugin;
+
+///
+/// Interface for progress box
+///
+public interface IProgressBoxEx
+{
+ ///
+ /// Show progress box
+ ///
+ ///
+ /// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
+ ///
+ public void ReportProgress(double progress);
+
+ ///
+ /// Close progress box.
+ ///
+ public void Close();
+}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index a0186b7a2..9cd45a1d3 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Plugin.SharedModels;
+using Flow.Launcher.Plugin.SharedModels;
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
@@ -316,5 +316,14 @@ namespace Flow.Launcher.Plugin
/// Specifies the default result of the message box.
/// Specifies which message box button is clicked by the user.
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK);
+
+ ///
+ /// Displays a standardised Flow message box.
+ /// If there is issue when showing the message box, it will return null.
+ ///
+ /// The caption of the message box.
+ /// When user closes the progress box manually by button or esc key, this action will be called.
+ /// A progress box interface.
+ public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf24..b403d6046 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,6 +324,8 @@ namespace Flow.Launcher
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
+ public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null) => ProgressBoxEx.Show(caption, forceClosed);
+
#endregion
#region Private Methods
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 39390ae10..f7383ff2f 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -143,7 +142,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- ProgressBoxEx prgBox = null;
+ IProgressBoxEx prgBox = null;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -159,7 +158,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = ProgressBoxEx.Show("Download plugin...")) != null)
+ if (canReportProgress && (prgBox = Context.API.ShowProgressBox("Download plugin...")) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
From d0bab86377d51234337ab2f682f320e9dd80cc47 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:11:03 +0800
Subject: [PATCH 010/200] Improve code quality
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 2 +-
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index b6801d2c1..9a32f7303 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -17,7 +17,7 @@ namespace Flow.Launcher.Core
InitializeComponent();
}
- public static IProgressBoxEx Show(string caption, Action forceClosed)
+ public static IProgressBoxEx Show(string caption, Action forceClosed = null)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f7383ff2f..2ac4be93e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -158,7 +158,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = Context.API.ShowProgressBox("Download plugin...")) != null)
+ if (canReportProgress && (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...")) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
From f69dd0f15572d1135ac753563d8f3ecb9ab40dcf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:13:32 +0800
Subject: [PATCH 011/200] Improve documents
---
Flow.Launcher.Plugin/IProgressBoxEx.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 0b245411f..6468e3c83 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -6,7 +6,7 @@
public interface IProgressBoxEx
{
///
- /// Show progress box
+ /// Show progress box. It should be called from the main ui thread.
///
///
/// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
@@ -14,7 +14,7 @@ public interface IProgressBoxEx
public void ReportProgress(double progress);
///
- /// Close progress box.
+ /// Close progress box. It should be called from the main ui thread.
///
public void Close();
}
From c06ba595b4f784757958702a3abcec1aed9e7fea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:08:07 +0800
Subject: [PATCH 012/200] Add support for cancelling download
---
.../PluginsManager.cs | 24 ++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 2ac4be93e..a1b37f428 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -143,6 +143,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
IProgressBoxEx prgBox = null;
+ var downloadCancelled = false;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -158,7 +159,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...")) != null)
+ if (canReportProgress &&
+ (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
+ {
+ httpClient.CancelPendingRequests();
+ downloadCancelled = true;
+ prgBox = null;
+ })) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
@@ -173,27 +180,38 @@ namespace Flow.Launcher.Plugin.PluginsManager
totalRead += read;
var progressValue = totalRead * 100 / totalBytes;
+
+ // check if user cancelled download before reporting progress
+ if (downloadCancelled)
+ return;
+
prgBox.ReportProgress(progressValue);
}
+ // check if user cancelled download before closing progress box
+ if (downloadCancelled)
+ return;
+
Application.Current.Dispatcher.Invoke(() =>
{
prgBox.Close();
prgBox = null;
});
+
+ Install(plugin, filePath);
}
else
{
await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ Install(plugin, filePath);
}
}
else
{
filePath = plugin.LocalInstallPath;
- }
-
Install(plugin, filePath);
}
+ }
catch (HttpRequestException e)
{
Context.API.ShowMsgError(
From 07bb16c8f30813eece608b09cde5bbced5ac91a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:08:23 +0800
Subject: [PATCH 013/200] Improve code quality
---
.../PluginsManager.cs | 38 +++++++++++--------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index a1b37f428..f1c634640 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -161,7 +161,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (canReportProgress &&
(prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
- {
+ {
httpClient.CancelPendingRequests();
downloadCancelled = true;
prgBox = null;
@@ -209,32 +209,31 @@ namespace Flow.Launcher.Plugin.PluginsManager
else
{
filePath = plugin.LocalInstallPath;
- Install(plugin, filePath);
- }
+ Install(plugin, filePath);
+ }
}
catch (HttpRequestException e)
{
+ // force close progress box
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (prgBox != null)
+ {
+ prgBox.Close();
+ prgBox = null;
+ }
+ });
+
+ // show error message
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
- // force close progress box
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (prgBox != null)
- {
- prgBox.Close();
- prgBox = null;
- }
- });
+
return;
}
catch (Exception e)
{
- Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
- plugin.Name));
- Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
// force close progress box
Application.Current.Dispatcher.Invoke(() =>
{
@@ -244,6 +243,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
prgBox = null;
}
});
+
+ // show error message
+ Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ plugin.Name));
+ Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+
return;
}
From c907c291480aeb800dba9cadd45e9c2d50917600 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:16:49 +0800
Subject: [PATCH 014/200] Fix plugin install issue
---
.../PluginsManager.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f1c634640..fd222d909 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -197,20 +197,22 @@ namespace Flow.Launcher.Plugin.PluginsManager
prgBox.Close();
prgBox = null;
});
-
- Install(plugin, filePath);
}
else
{
await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- Install(plugin, filePath);
}
}
else
{
filePath = plugin.LocalInstallPath;
- Install(plugin, filePath);
}
+
+ // check if user cancelled download before installing plugin
+ if (downloadCancelled)
+ return;
+
+ Install(plugin, filePath);
}
catch (HttpRequestException e)
{
From 3ccd8b42ae53ccd33f66492f6134078a2656c96b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 16:58:08 +0800
Subject: [PATCH 015/200] Move SystemLanguageCode to constant
---
Flow.Launcher.Core/Resource/Internationalization.cs | 7 +++----
Flow.Launcher.Infrastructure/Constant.cs | 2 ++
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 4db3e8633..70f23c897 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,7 +18,6 @@ namespace Flow.Launcher.Core.Resource
{
public Settings Settings { get; set; }
private const string Folder = "Languages";
- private const string SystemLanguageCode = "System";
private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
@@ -73,7 +72,7 @@ namespace Flow.Launcher.Core.Resource
// Get actual language if language code is system
var isSystem = false;
- if (languageCode == SystemLanguageCode)
+ if (languageCode == Constant.SystemLanguageCode)
{
languageCode = GetSystemLanguageCode();
isSystem = true;
@@ -114,7 +113,7 @@ namespace Flow.Launcher.Core.Resource
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
- Settings.Language = isSystem ? SystemLanguageCode : language.LanguageCode;
+ Settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
@@ -179,7 +178,7 @@ namespace Flow.Launcher.Core.Resource
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
+ list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
return list;
}
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index 2889e5ec7..f03d327f2 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -52,5 +52,7 @@ namespace Flow.Launcher.Infrastructure
public const string SponsorPage = "https://github.com/sponsors/Flow-Launcher";
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
public const string Docs = "https://flowlauncher.com/docs";
+
+ public const string SystemLanguageCode = "System";
}
}
From 6febbe719a956d1e9928e9d690c70ffa55105467 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 16:58:19 +0800
Subject: [PATCH 016/200] Use system language as default in settings
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 83f06279c..5b5d10e6e 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -13,7 +13,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public class Settings : BaseModel, IHotkeySettings
{
- private string language = "en";
+ private string language = Constant.SystemLanguageCode;
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
From 46c2c1f6683e50652afbfa541f187d15fb6275b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 19:20:47 +0800
Subject: [PATCH 017/200] Change system language code to lowercase
---
Flow.Launcher.Infrastructure/Constant.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index f03d327f2..c86ed4324 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -53,6 +53,6 @@ namespace Flow.Launcher.Infrastructure
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
public const string Docs = "https://flowlauncher.com/docs";
- public const string SystemLanguageCode = "System";
+ public const string SystemLanguageCode = "system";
}
}
From 675ee9e3952fcc4093dd6f70e3da0d3bae917f47 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:16:12 +0800
Subject: [PATCH 018/200] Add translation for progress box title
---
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fd222d909..0ed849bb3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -159,8 +159,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
+ var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
if (canReportProgress &&
- (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
+ (prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
{
httpClient.CancelPendingRequests();
downloadCancelled = true;
From 0fabe31fe4344acb49bae294ac4cf23981a1951d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:16:28 +0800
Subject: [PATCH 019/200] Improve code quality
---
.../PluginsManager.cs | 29 ++++++++++---------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 0ed849bb3..bbb5c179e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -163,9 +163,12 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (canReportProgress &&
(prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
{
- httpClient.CancelPendingRequests();
- downloadCancelled = true;
- prgBox = null;
+ if (prgBox != null)
+ {
+ httpClient.CancelPendingRequests();
+ downloadCancelled = true;
+ prgBox = null;
+ }
})) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@@ -185,19 +188,19 @@ namespace Flow.Launcher.Plugin.PluginsManager
// check if user cancelled download before reporting progress
if (downloadCancelled)
return;
-
- prgBox.ReportProgress(progressValue);
+ else
+ prgBox.ReportProgress(progressValue);
}
// check if user cancelled download before closing progress box
if (downloadCancelled)
return;
-
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox.Close();
- prgBox = null;
- });
+ else
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox.Close();
+ prgBox = null;
+ });
}
else
{
@@ -212,8 +215,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
// check if user cancelled download before installing plugin
if (downloadCancelled)
return;
-
- Install(plugin, filePath);
+ else
+ Install(plugin, filePath);
}
catch (HttpRequestException e)
{
From cc0fb66b2245dbc1e7f4098b5da492b19a8868ac Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:26:05 +0800
Subject: [PATCH 020/200] Extract duplicate cleanup code into a method
---
.../PluginsManager.cs | 32 +++++++------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index bbb5c179e..a41a82c67 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,11 +196,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (downloadCancelled)
return;
else
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox.Close();
- prgBox = null;
- });
+ CleanupProgressBoxEx(prgBox);
}
else
{
@@ -221,14 +217,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (HttpRequestException e)
{
// force close progress box
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (prgBox != null)
- {
- prgBox.Close();
- prgBox = null;
- }
- });
+ CleanupProgressBoxEx(prgBox);
// show error message
Context.API.ShowMsgError(
@@ -241,14 +230,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (Exception e)
{
// force close progress box
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (prgBox != null)
- {
- prgBox.Close();
- prgBox = null;
- }
- });
+ CleanupProgressBoxEx(prgBox);
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
@@ -274,6 +256,14 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
}
+ private static void CleanupProgressBoxEx(IProgressBoxEx prgBox)
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox?.Close();
+ });
+ }
+
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
From bc84910e56c041d59fa966737a15fa3fdb7511fa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:30:28 +0800
Subject: [PATCH 021/200] Use static HttpClient instance for heavy load issue
---
.../PluginsManager.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index a41a82c67..9670f4909 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -17,7 +17,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
- const string zip = "zip";
+ private static readonly HttpClient HttpClient = new();
+
+ private const string zip = "zip";
private PluginInitContext Context { get; set; }
@@ -151,8 +153,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (File.Exists(filePath))
File.Delete(filePath);
- using var httpClient = new HttpClient();
- using var response = await httpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+ using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
@@ -165,7 +166,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
if (prgBox != null)
{
- httpClient.CancelPendingRequests();
+ HttpClient.CancelPendingRequests();
downloadCancelled = true;
prgBox = null;
}
From aff6b1aff1fa80fa79e9eecd0a630d1ce3ed7e28 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:32:02 +0800
Subject: [PATCH 022/200] Perserve prgBox value when force close
---
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 9670f4909..2923f7eef 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -168,7 +168,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
HttpClient.CancelPendingRequests();
downloadCancelled = true;
- prgBox = null;
}
})) != null)
{
From 8aebf958aa940770c23854167d4c0304a7890fd3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 12:13:46 +0800
Subject: [PATCH 023/200] Check ui thread when calling close function & Update
documents
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 7 ++++++-
Flow.Launcher.Plugin/IProgressBoxEx.cs | 4 ++--
.../PluginsManager.cs | 14 +++-----------
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 9a32f7303..f5d34617b 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -66,11 +66,16 @@ namespace Flow.Launcher.Core
private new void Close()
{
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ Application.Current.Dispatcher.Invoke(Close);
+ }
+
if (_isClosed)
{
return;
}
-
+
base.Close();
_isClosed = true;
}
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 6468e3c83..27b061895 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -6,7 +6,7 @@
public interface IProgressBoxEx
{
///
- /// Show progress box. It should be called from the main ui thread.
+ /// Show progress box.
///
///
/// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
@@ -14,7 +14,7 @@ public interface IProgressBoxEx
public void ReportProgress(double progress);
///
- /// Close progress box. It should be called from the main ui thread.
+ /// Close progress box.
///
public void Close();
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 2923f7eef..0af2af5ec 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,7 +196,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (downloadCancelled)
return;
else
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
}
else
{
@@ -217,7 +217,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (HttpRequestException e)
{
// force close progress box
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
// show error message
Context.API.ShowMsgError(
@@ -230,7 +230,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (Exception e)
{
// force close progress box
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
@@ -256,14 +256,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
}
- private static void CleanupProgressBoxEx(IProgressBoxEx prgBox)
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox?.Close();
- });
- }
-
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
From 122887e6a61f629a4574fe1ebfa62b7a115e9b2f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 16:37:52 +0800
Subject: [PATCH 024/200] Await close event from non-ui thread
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 10 ++++++++--
Flow.Launcher.Plugin/IProgressBoxEx.cs | 6 ++++--
.../PluginsManager.cs | 6 +++---
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index f5d34617b..00f4a8050 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
@@ -64,13 +65,18 @@ namespace Flow.Launcher.Core
}
}
- private new void Close()
+ public async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- Application.Current.Dispatcher.Invoke(Close);
+ await Application.Current.Dispatcher.InvokeAsync(Close);
}
+ Close();
+ }
+
+ private new void Close()
+ {
if (_isClosed)
{
return;
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 27b061895..50ee6eb55 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -1,4 +1,6 @@
-namespace Flow.Launcher.Plugin;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin;
///
/// Interface for progress box
@@ -16,5 +18,5 @@ public interface IProgressBoxEx
///
/// Close progress box.
///
- public void Close();
+ public Task CloseAsync();
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 0af2af5ec..f5399d53d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,7 +196,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (downloadCancelled)
return;
else
- prgBox?.Close();
+ await prgBox?.CloseAsync();
}
else
{
@@ -217,7 +217,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (HttpRequestException e)
{
// force close progress box
- prgBox?.Close();
+ await prgBox?.CloseAsync();
// show error message
Context.API.ShowMsgError(
@@ -230,7 +230,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (Exception e)
{
// force close progress box
- prgBox?.Close();
+ await prgBox?.CloseAsync();
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
From 6220b34aabc7043977ad7316aa0417e7d8e2b1c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 17:33:39 +0800
Subject: [PATCH 025/200] Fix dulplicated close event
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 00f4a8050..dc1f27404 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -70,6 +70,7 @@ namespace Flow.Launcher.Core
if (!Application.Current.Dispatcher.CheckAccess())
{
await Application.Current.Dispatcher.InvokeAsync(Close);
+ return;
}
Close();
From 501633435942fa701c53e25ec0b074df0cbbe3df Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 17:37:53 +0800
Subject: [PATCH 026/200] Avoid cancelling all pending requests on shared
HttpClient instance
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f5399d53d..081f8d489 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -153,7 +153,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (File.Exists(filePath))
File.Delete(filePath);
- using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+ using var cts = new CancellationTokenSource();
+ using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead, cts.Token).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
@@ -166,7 +167,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
if (prgBox != null)
{
- HttpClient.CancelPendingRequests();
+ cts.Cancel();
downloadCancelled = true;
}
})) != null)
From 381e64e69797256980d3353c150fa35fe7273dec Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:13:24 +0800
Subject: [PATCH 027/200] Move ProgressBoxEx to main project for better
development experience
---
{Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml | 0
{Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml.cs | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename {Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml (100%)
rename {Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml.cs (100%)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
similarity index 100%
rename from Flow.Launcher.Core/ProgressBoxEx.xaml
rename to Flow.Launcher/ProgressBoxEx.xaml
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
similarity index 100%
rename from Flow.Launcher.Core/ProgressBoxEx.xaml.cs
rename to Flow.Launcher/ProgressBoxEx.xaml.cs
From 20ffff6d1b8464d6aa20c7e32e12aac1e5abd6a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:30:11 +0800
Subject: [PATCH 028/200] Use api to call api functions
---
Flow.Launcher/ActionKeywords.xaml.cs | 2 +-
Flow.Launcher/App.xaml.cs | 4 +++-
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 4 ++--
Flow.Launcher/Helper/HotKeyMapper.cs | 2 +-
Flow.Launcher/PriorityChangeWindow.xaml.cs | 4 ++--
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 12 ++++++------
.../ViewModels/SettingsPaneProxyViewModel.cs | 2 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
10 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index ba47a4ded..c3966e618 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -44,7 +44,7 @@ namespace Flow.Launcher
else
{
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 4d1adc6cd..58da35e85 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -15,13 +15,15 @@ using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp
+ public partial class App : IDisposable, ISingleInstanceApp, IApp
{
+ public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8..47460ff7d 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -63,7 +63,7 @@ namespace Flow.Launcher
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
Close();
return;
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb..4589b45ec 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -43,13 +43,13 @@ namespace Flow.Launcher
{
if (String.IsNullOrEmpty(Key) || String.IsNullOrEmpty(Value))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
return;
}
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
return;
}
DialogResult = !update || originalKey != Key || originalValue != Value;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 8b30b8be1..b40406e42 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -46,7 +46,7 @@ internal static class HotKeyMapper
{
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
- MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs
index 2154b058d..fbe2a941d 100644
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs
@@ -24,7 +24,7 @@ namespace Flow.Launcher
this.pluginViewModel = pluginViewModel;
if (plugin == null)
{
- MessageBoxEx.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
+ App.API.ShowMsgBox(translater.GetTranslation("cannotFindSpecifiedPlugin"));
Close();
}
}
@@ -44,7 +44,7 @@ namespace Flow.Launcher
else
{
string msg = translater.GetTranslation("invalidPriority");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 6e81db5e0..05fb16f5c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -62,7 +62,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[RelayCommand]
private void AskClearLogFolderConfirmation()
{
- var confirmResult = MessageBoxEx.Show(
+ var confirmResult = App.API.ShowMsgBox(
InternationalizationManager.Instance.GetTranslation("clearlogfolderMessage"),
InternationalizationManager.Instance.GetTranslation("clearlogfolder"),
MessageBoxButton.YesNo
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 6d8af9a3f..fb57f499b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -42,11 +42,11 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
),
@@ -67,7 +67,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -88,11 +88,11 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
),
@@ -112,7 +112,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index 1c840fb27..e2f9e516c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -22,7 +22,7 @@ public partial class SettingsPaneProxyViewModel : BaseModel
private void OnTestProxyClicked()
{
var message = TestProxy();
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation(message));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation(message));
}
private string TestProxy()
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 8d8ccb780..980b2a811 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -49,7 +49,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
if (ThemeManager.Instance.BlurEnabled && value)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
return;
}
From 8b910500c6f3a2fe170cdc8261c6d0add722b744 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:43:33 +0800
Subject: [PATCH 029/200] Add IApp & AppExtensions for accessing the properties
& functions from anywhere in the application
---
Flow.Launcher.Core/AppExtensions.cs | 15 +++++++++++++++
Flow.Launcher.Core/IApp.cs | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 Flow.Launcher.Core/AppExtensions.cs
create mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
new file mode 100644
index 000000000..b02612d72
--- /dev/null
+++ b/Flow.Launcher.Core/AppExtensions.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core;
+
+///
+/// Extension properties and functions of the current application singleton object.
+///
+public static class AppExtensions
+{
+ ///
+ /// Gets the public API of the current application singleton object.
+ ///
+ public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
+}
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
new file mode 100644
index 000000000..233fd5ed1
--- /dev/null
+++ b/Flow.Launcher.Core/IApp.cs
@@ -0,0 +1,13 @@
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core
+{
+ ///
+ /// Interface for the current application singleton object exposing the properties
+ /// and functions that can be accessed from anywhere in the application.
+ ///
+ public interface IApp
+ {
+ public IPublicAPI PublicAPI { get; }
+ }
+}
From 88e84378daee2906bdbfa131ba4d012225464df1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:44:24 +0800
Subject: [PATCH 030/200] Use api in app extensions to call api functions
---
Flow.Launcher.Core/Configuration/Portable.cs | 20 +++++++++----------
.../Environments/AbstractPluginEnvironment.cs | 6 +++---
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 2 +-
.../Resource/Internationalization.cs | 2 +-
Flow.Launcher.Core/Resource/Theme.cs | 4 ++--
Flow.Launcher.Core/Updater.cs | 10 +++++-----
10 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index d7c73fb46..cb375c586 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -40,7 +40,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +64,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +95,13 @@ namespace Flow.Launcher.Core.Configuration
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +157,13 @@ namespace Flow.Launcher.Core.Configuration
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
+ if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +172,9 @@ namespace Flow.Launcher.Core.Configuration
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +186,7 @@ namespace Flow.Launcher.Core.Configuration
if (roamingLocationExists && portableLocationExists)
{
- MessageBoxEx.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 6d41e2383..cada05031 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -57,7 +57,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
EnvName,
Environment.NewLine
);
- if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +82,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
else
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +98,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 96c29646e..56bc20b4f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 0d6f109e0..1d43b815a 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 582a4407c..49bf4e958 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1da..9e1cf3b9d 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ namespace Flow.Launcher.Core.Plugin
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 7973c66ba..8cbeb7473 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -119,7 +119,7 @@ namespace Flow.Launcher.Core.Plugin
_ = Task.Run(() =>
{
- MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1505e84f8..a1cefabe3 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -124,7 +124,7 @@ namespace Flow.Launcher.Core.Resource
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (MessageBoxEx.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 1d8409306..8622d4caf 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -108,7 +108,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +118,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index b92d86568..8745d54b7 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -53,7 +53,7 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- MessageBoxEx.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +68,9 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show);
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show))
- MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
+ AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +83,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
From d36aef57e9bff40af03ab6143753b0cfd4b14348 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:48:13 +0800
Subject: [PATCH 031/200] Change ProgressBoxEx namespace
---
Flow.Launcher/ProgressBoxEx.xaml | 4 ++--
Flow.Launcher/ProgressBoxEx.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
index 4cce82221..3102cfb72 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml
+++ b/Flow.Launcher/ProgressBoxEx.xaml
@@ -1,9 +1,9 @@
Date: Thu, 9 Jan 2025 21:50:07 +0800
Subject: [PATCH 032/200] Move MessageBoxEx to main project for better
development experience
---
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml | 4 ++--
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml (98%)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs (99%)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher/MessageBoxEx.xaml
similarity index 98%
rename from Flow.Launcher.Core/MessageBoxEx.xaml
rename to Flow.Launcher/MessageBoxEx.xaml
index fff107a68..be12ca16c 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher/MessageBoxEx.xaml
@@ -1,9 +1,9 @@
Date: Thu, 9 Jan 2025 12:48:43 -0600
Subject: [PATCH 033/200] resolve link before using File.Replace
---
.../Storage/JsonStorage.cs | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 642250627..33bc1ff6c 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -31,11 +31,12 @@ namespace Flow.Launcher.Infrastructure.Storage
protected JsonStorage()
{
}
+
public JsonStorage(string filePath)
{
FilePath = filePath;
DirectoryPath = Path.GetDirectoryName(filePath) ?? throw new ArgumentException("Invalid file path");
-
+
Helper.ValidateDirectory(DirectoryPath);
}
@@ -97,6 +98,7 @@ namespace Flow.Launcher.Infrastructure.Storage
return default;
}
}
+
private void RestoreBackup()
{
Log.Info($"|JsonStorage.Load|Failed to load settings.json, {BackupFilePath} restored successfully");
@@ -179,25 +181,21 @@ namespace Flow.Launcher.Infrastructure.Storage
public void Save()
{
string serialized = JsonSerializer.Serialize(Data,
- new JsonSerializerOptions
- {
- WriteIndented = true
- });
+ new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(TempFilePath, serialized);
AtomicWriteSetting();
}
+
public async Task SaveAsync()
{
var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
- new JsonSerializerOptions
- {
- WriteIndented = true
- });
+ new JsonSerializerOptions { WriteIndented = true });
AtomicWriteSetting();
}
+
private void AtomicWriteSetting()
{
if (!File.Exists(FilePath))
@@ -206,9 +204,9 @@ namespace Flow.Launcher.Infrastructure.Storage
}
else
{
- File.Replace(TempFilePath, FilePath, BackupFilePath);
+ var finalFilePath = new FileInfo(FilePath).LinkTarget ?? FilePath;
+ File.Replace(TempFilePath, finalFilePath, BackupFilePath);
}
}
-
}
}
From ed7265d24457e2934a02ab3a1959a3222996219c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 13:06:37 +0800
Subject: [PATCH 034/200] Remove override close event
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index eff0bd80c..507710e90 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -10,7 +10,6 @@ namespace Flow.Launcher
public partial class ProgressBoxEx : Window, IProgressBoxEx
{
private readonly Action _forceClosed;
- private bool _isClosed;
private ProgressBoxEx(Action forceClosed)
{
@@ -76,17 +75,6 @@ namespace Flow.Launcher
Close();
}
- private new void Close()
- {
- if (_isClosed)
- {
- return;
- }
-
- base.Close();
- _isClosed = true;
- }
-
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
ForceClose();
@@ -104,13 +92,7 @@ namespace Flow.Launcher
private void ForceClose()
{
- if (_isClosed)
- {
- return;
- }
-
- base.Close();
- _isClosed = true;
+ Close();
_forceClosed?.Invoke();
}
}
From 297d1914127fd10d9ac230438e7a327d362dbc6f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 19:13:19 +0800
Subject: [PATCH 035/200] Use function to delegate the progress task
---
Flow.Launcher.Plugin/IProgressBoxEx.cs | 22 ------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 7 +-
Flow.Launcher/ProgressBoxEx.xaml.cs | 50 +++++++-----
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../PluginsManager.cs | 76 +++++++++----------
5 files changed, 76 insertions(+), 81 deletions(-)
delete mode 100644 Flow.Launcher.Plugin/IProgressBoxEx.cs
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
deleted file mode 100644
index 50ee6eb55..000000000
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Flow.Launcher.Plugin;
-
-///
-/// Interface for progress box
-///
-public interface IProgressBoxEx
-{
- ///
- /// Show progress box.
- ///
- ///
- /// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
- ///
- public void ReportProgress(double progress);
-
- ///
- /// Close progress box.
- ///
- public Task CloseAsync();
-}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 9cd45a1d3..c4bfd7033 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,8 +322,13 @@ namespace Flow.Launcher.Plugin
/// If there is issue when showing the message box, it will return null.
///
/// The caption of the message box.
+ ///
+ /// Time-consuming task function, whose input is the action to report progress.
+ /// The input of the action is the progress value which is a double value between 0 and 100.
+ /// If there are any exceptions, this action will be null.
+ ///
/// When user closes the progress box manually by button or esc key, this action will be called.
/// A progress box interface.
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 507710e90..37ee2b0cb 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -3,11 +3,10 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin;
namespace Flow.Launcher
{
- public partial class ProgressBoxEx : Window, IProgressBoxEx
+ public partial class ProgressBoxEx : Window
{
private readonly Action _forceClosed;
@@ -17,31 +16,48 @@ namespace Flow.Launcher
InitializeComponent();
}
- public static IProgressBoxEx Show(string caption, Action forceClosed = null)
+ public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null)
{
- if (!Application.Current.Dispatcher.CheckAccess())
- {
- return Application.Current.Dispatcher.Invoke(() => Show(caption, forceClosed));
- }
-
+ ProgressBoxEx prgBox = null;
try
{
- var prgBox = new ProgressBoxEx(forceClosed)
+ if (!Application.Current.Dispatcher.CheckAccess())
{
- Title = caption
- };
- prgBox.TitleTextBlock.Text = caption;
- prgBox.Show();
- return prgBox;
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ prgBox = new ProgressBoxEx(forceClosed)
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ });
+ }
+
+ await reportProgressAsync(prgBox.ReportProgress).ConfigureAwait(false);
}
catch (Exception e)
{
Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
- return null;
+
+ await reportProgressAsync(null).ConfigureAwait(false);
+ }
+ finally
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ await Application.Current.Dispatcher.InvokeAsync(async () =>
+ {
+ if (prgBox != null)
+ {
+ await prgBox.CloseAsync();
+ }
+ });
+ }
}
}
- public void ReportProgress(double progress)
+ private void ReportProgress(double progress)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
@@ -64,7 +80,7 @@ namespace Flow.Launcher
}
}
- public async Task CloseAsync()
+ private async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b403d6046..95d371fb0 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ namespace Flow.Launcher
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null) => ProgressBoxEx.Show(caption, forceClosed);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);
#endregion
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 081f8d489..c3ed04a4d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -144,7 +144,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- IProgressBoxEx prgBox = null;
var downloadCancelled = false;
try
{
@@ -162,42 +161,45 @@ namespace Flow.Launcher.Plugin.PluginsManager
var canReportProgress = totalBytes != -1;
var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- if (canReportProgress &&
- (prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
- {
- if (prgBox != null)
+ if (canReportProgress)
+ {
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
+ {
+ // cannot use progress box
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ }
+ else
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
+
+ while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
+ totalRead += read;
+
+ var progressValue = totalRead * 100 / totalBytes;
+
+ // check if user cancelled download before reporting progress
+ if (downloadCancelled)
+ return;
+ else
+ reportProgress(progressValue);
+ }
+ }
+ },
+ () =>
{
cts.Cancel();
downloadCancelled = true;
- }
- })) != null)
- {
- await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
-
- var buffer = new byte[8192];
- long totalRead = 0;
- int read;
-
- while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
- {
- await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
- totalRead += read;
-
- var progressValue = totalRead * 100 / totalBytes;
-
- // check if user cancelled download before reporting progress
- if (downloadCancelled)
- return;
- else
- prgBox.ReportProgress(progressValue);
- }
-
- // check if user cancelled download before closing progress box
- if (downloadCancelled)
- return;
- else
- await prgBox?.CloseAsync();
+ });
}
else
{
@@ -217,9 +219,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
catch (HttpRequestException e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
@@ -230,9 +229,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
catch (Exception e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
From cc921c7d291b45b4128cdb2b1423a2631a6ee422 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 19:17:54 +0800
Subject: [PATCH 036/200] Improve progress box when exception happens
---
.../PluginsManager.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index c3ed04a4d..b6495d8f2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -145,6 +145,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
var downloadCancelled = false;
+ var exceptionHappened = false;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -168,8 +169,10 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
if (reportProgress == null)
{
- // cannot use progress box
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
}
else
{
@@ -200,6 +203,11 @@ namespace Flow.Launcher.Plugin.PluginsManager
cts.Cancel();
downloadCancelled = true;
});
+
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!downloadCancelled))
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
}
else
{
From 4b38e0e714abf705e8f337dbcb26f29893105c7e Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 10 Jan 2025 13:11:35 -0600
Subject: [PATCH 037/200] properly dispose the filestream
---
Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 33bc1ff6c..507838d94 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -190,7 +190,7 @@ namespace Flow.Launcher.Infrastructure.Storage
public async Task SaveAsync()
{
- var tempOutput = File.OpenWrite(TempFilePath);
+ await using var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
new JsonSerializerOptions { WriteIndented = true });
AtomicWriteSetting();
From 2a1d502affe50f43aafd38e7ee3ff5435993cbef Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 10 Jan 2025 13:18:14 -0600
Subject: [PATCH 038/200] fix build error
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index ae4fd639d..f95266c7f 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -138,7 +138,7 @@ namespace Flow.Launcher.Core.Plugin
SetupJsonRPC();
try
{
- await RPC.InvokeAsync("reload", context);
+ await RPC.InvokeAsync("reload", Context);
}
catch (RemoteMethodNotFoundException e)
{
From df3cb58c6c2bac0f71e73a003f99b04a881d83d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 12:38:08 +0800
Subject: [PATCH 039/200] Improve code quality
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 37ee2b0cb..a04ed0576 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -46,12 +46,9 @@ namespace Flow.Launcher
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- await Application.Current.Dispatcher.InvokeAsync(async () =>
+ await Application.Current.Dispatcher.InvokeAsync(() =>
{
- if (prgBox != null)
- {
- await prgBox.CloseAsync();
- }
+ prgBox?.Close();
});
}
}
@@ -80,17 +77,6 @@ namespace Flow.Launcher
}
}
- private async Task CloseAsync()
- {
- if (!Application.Current.Dispatcher.CheckAccess())
- {
- await Application.Current.Dispatcher.InvokeAsync(Close);
- return;
- }
-
- Close();
- }
-
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
ForceClose();
From 029cb38c61855756cfcc4e75dc833c987bcbc50b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 13:19:45 +0800
Subject: [PATCH 040/200] Fix progress box action under ui thread
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index a04ed0576..7c55d62c0 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -33,6 +33,15 @@ namespace Flow.Launcher
prgBox.Show();
});
}
+ else
+ {
+ prgBox = new ProgressBoxEx(forceClosed)
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ }
await reportProgressAsync(prgBox.ReportProgress).ConfigureAwait(false);
}
@@ -51,6 +60,10 @@ namespace Flow.Launcher
prgBox?.Close();
});
}
+ else
+ {
+ prgBox?.Close();
+ }
}
}
From 8eb5a4dfcaa063d647f31e01211a4ef947344849 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 13:24:41 +0800
Subject: [PATCH 041/200] Improve HttpDownloadAsync function & Use it in
PluginManager plugin
---
.../JsonRPCV2Models/JsonRPCPublicAPI.cs | 7 +-
Flow.Launcher.Infrastructure/Http/Http.cs | 41 +++++++++-
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 +-
Flow.Launcher/PublicAPIInstance.cs | 4 +-
.../PluginsManager.cs | 80 +++++--------------
5 files changed, 67 insertions(+), 71 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index b8bfee591..a82cae5d2 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
@@ -121,10 +120,10 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
return _api.HttpGetStreamAsync(url, token);
}
- public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
+ public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null,
CancellationToken token = default)
{
- return _api.HttpDownloadAsync(url, filePath, token);
+ return _api.HttpDownloadAsync(url, filePath, reportProgress, token);
}
public void AddActionKeyword(string pluginId, string newActionKeyword)
@@ -162,13 +161,11 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
_api.OpenDirectory(DirectoryPath, FileNameOrFilePath);
}
-
public void OpenUrl(string url, bool? inPrivate = null)
{
_api.OpenUrl(url, inPrivate);
}
-
public void OpenAppUri(string appUri)
{
_api.OpenAppUri(appUri);
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 14b8eef4e..0b5d1b05a 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -83,15 +83,50 @@ namespace Flow.Launcher.Infrastructure.Http
}
}
- public static async Task DownloadAsync([NotNull] string url, [NotNull] string filePath, CancellationToken token = default)
+ public static async Task DownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default)
{
try
{
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
+
if (response.StatusCode == HttpStatusCode.OK)
{
- await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
- await response.Content.CopyToAsync(fileStream, token);
+ var totalBytes = response.Content.Headers.ContentLength ?? -1L;
+ var canReportProgress = totalBytes != -1;
+
+ if (canReportProgress && reportProgress != null)
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync(token);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
+ double progressValue = 0;
+
+ reportProgress(0);
+
+ while ((read = await contentStream.ReadAsync(buffer, token)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read), token);
+ totalRead += read;
+
+ progressValue = totalRead * 100.0 / totalBytes;
+
+ if (token.IsCancellationRequested)
+ return;
+ else
+ reportProgress(progressValue);
+ }
+
+ if (progressValue < 100)
+ reportProgress(100);
+ }
+ else
+ {
+ await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
+ await response.Content.CopyToAsync(fileStream, token);
+ }
}
else
{
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index c4bfd7033..8376fd07b 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -181,9 +181,13 @@ namespace Flow.Launcher.Plugin
///
/// URL to download file
/// path to save downloaded file
+ ///
+ /// Action to report progress. The input of the action is the progress value which is a double value between 0 and 100.
+ /// It will be called if url support range request and the reportProgress is not null.
+ ///
/// place to store file
/// Task showing the progress
- Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, CancellationToken token = default);
+ Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default);
///
/// Add ActionKeyword for specific plugin
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 95d371fb0..7706a64ba 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -164,8 +164,8 @@ namespace Flow.Launcher
public Task HttpGetStreamAsync(string url, CancellationToken token = default) =>
Http.GetStreamAsync(url);
- public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
- CancellationToken token = default) => Http.DownloadAsync(url, filePath, token);
+ public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null,
+ CancellationToken token = default) => Http.DownloadAsync(url, filePath, reportProgress, token);
public void AddActionKeyword(string pluginId, string newActionKeyword) =>
PluginManager.AddActionKeyword(pluginId, newActionKeyword);
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index b6495d8f2..aee76e65e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -17,8 +17,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
- private static readonly HttpClient HttpClient = new();
-
private const string zip = "zip";
private PluginInitContext Context { get; set; }
@@ -144,75 +142,37 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- var downloadCancelled = false;
var exceptionHappened = false;
try
{
+ using var cts = new CancellationTokenSource();
+
if (!plugin.IsFromLocalInstallPath)
{
if (File.Exists(filePath))
File.Delete(filePath);
- using var cts = new CancellationTokenSource();
- using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead, cts.Token).ConfigureAwait(false);
-
- response.EnsureSuccessStatusCode();
-
- var totalBytes = response.Content.Headers.ContentLength ?? -1L;
- var canReportProgress = totalBytes != -1;
-
var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- if (canReportProgress)
- {
- await Context.API.ShowProgressBoxAsync(prgBoxTitle,
- async (reportProgress) =>
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
{
- if (reportProgress == null)
- {
- // when reportProgress is null, it means there is expcetion with the progress box
- // so we record it with exceptionHappened and return so that progress box will close instantly
- exceptionHappened = true;
- return;
- }
- else
- {
- await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
-
- var buffer = new byte[8192];
- long totalRead = 0;
- int read;
-
- while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
- {
- await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
- totalRead += read;
-
- var progressValue = totalRead * 100 / totalBytes;
-
- // check if user cancelled download before reporting progress
- if (downloadCancelled)
- return;
- else
- reportProgress(progressValue);
- }
- }
- },
- () =>
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
+ }
+ else
{
- cts.Cancel();
- downloadCancelled = true;
- });
+ await Http.DownloadAsync(plugin.UrlDownload, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ }
+ }, cts.Cancel);
- // if exception happened while downloading and user does not cancel downloading,
- // we need to redownload the plugin
- if (exceptionHappened && (!downloadCancelled))
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- }
- else
- {
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- }
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!cts.IsCancellationRequested))
+ await Http.DownloadAsync(plugin.UrlDownload, filePath, null, cts.Token).ConfigureAwait(false);
}
else
{
@@ -220,7 +180,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
// check if user cancelled download before installing plugin
- if (downloadCancelled)
+ if (cts.IsCancellationRequested)
return;
else
Install(plugin, filePath);
From 32cac76c827681b436bd8bdc8de03e608181260c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 18:44:52 +0800
Subject: [PATCH 042/200] Improve Settings management
---
.../UserSettings/Settings.cs | 16 ++++++++++++++--
Flow.Launcher/App.xaml.cs | 8 ++++++--
.../ViewModel/SettingWindowViewModel.cs | 13 +++----------
3 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0bcc9368d..3e43e3d32 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text.Json.Serialization;
using System.Windows;
using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
@@ -13,6 +13,18 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public class Settings : BaseModel, IHotkeySettings
{
+ private FlowLauncherJsonStorage _storage;
+
+ public void Initialize(FlowLauncherJsonStorage storage)
+ {
+ _storage = storage;
+ }
+
+ public void Save()
+ {
+ _storage.Save();
+ }
+
private string language = "en";
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 58da35e85..9d7a0671e 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -14,6 +14,7 @@ using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -52,6 +53,10 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+
_portable.PreStartCleanUpAfterPortabilityUpdate();
Log.Info(
@@ -62,8 +67,7 @@ namespace Flow.Launcher
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_updater, _portable);
- _settings = _settingsVM.Settings;
+ _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 04dd6312b..95a1eb675 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,6 +1,5 @@
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
-using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -8,21 +7,17 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- private readonly FlowLauncherJsonStorage _storage;
-
public Updater Updater { get; }
public IPortable Portable { get; }
public Settings Settings { get; }
- public SettingWindowViewModel(Updater updater, IPortable portable)
+ public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
{
- _storage = new FlowLauncherJsonStorage();
-
+ Settings = settings;
Updater = updater;
Portable = portable;
- Settings = _storage.Load();
}
public async void UpdateApp()
@@ -30,14 +25,12 @@ public class SettingWindowViewModel : BaseModel
await Updater.UpdateAppAsync(App.API, false);
}
-
-
///
/// Save Flow settings. Plugins settings are not included.
///
public void Save()
{
- _storage.Save();
+ Settings.Save();
}
public double SettingWindowWidth
From 1b76a2bc1a1c3356b3bab5c3be61b3427b1de7fd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:45:36 +0800
Subject: [PATCH 043/200] Use dependency injection for all services
---
.../Flow.Launcher.Infrastructure.csproj | 1 +
.../PinyinAlphabet.cs | 8 ++-
Flow.Launcher.Infrastructure/StringMatcher.cs | 5 +-
Flow.Launcher/App.xaml.cs | 61 +++++++++++--------
Flow.Launcher/Flow.Launcher.csproj | 5 +-
Flow.Launcher/PublicAPIInstance.cs | 12 ++--
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +-
.../ViewModel/SettingWindowViewModel.cs | 11 ++--
8 files changed, 65 insertions(+), 43 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index 1475252ca..84b603161 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -54,6 +54,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 7d7235968..8eaa757be 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -6,6 +6,7 @@ using System.Text;
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure
{
@@ -129,7 +130,12 @@ namespace Flow.Launcher.Infrastructure
private Settings _settings;
- public void Initialize([NotNull] Settings settings)
+ public PinyinAlphabet()
+ {
+ Initialize(Ioc.Default.GetRequiredService());
+ }
+
+ private void Initialize([NotNull] Settings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index bd5dbdda9..7134fc760 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Plugin.SharedModels;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin.SharedModels;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -15,7 +16,7 @@ namespace Flow.Launcher.Infrastructure
public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = alphabet;
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9d7a0671e..8cd054148 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -4,6 +4,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.ExternalPlugins.Environments;
@@ -18,23 +19,18 @@ using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp, IApp
+ public partial class App : IDisposable, ISingleInstanceApp
{
- public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
- private MainViewModel _mainVM;
- private SettingWindowViewModel _settingsVM;
- private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo);
- private readonly Portable _portable = new Portable();
- private readonly PinyinAlphabet _alphabet = new PinyinAlphabet();
- private StringMatcher _stringMatcher;
[STAThread]
public static void Main()
@@ -53,37 +49,51 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ // Initialize settings
var storage = new FlowLauncherJsonStorage();
_settings = storage.Load();
_settings.Initialize(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
- _portable.PreStartCleanUpAfterPortabilityUpdate();
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
- Log.Info(
- "|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
+ Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
+
+ Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+
+ Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
+
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
- _alphabet.Initialize(_settings);
- _stringMatcher = new StringMatcher(_alphabet);
- StringMatcher.Instance = _stringMatcher;
- _stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
+ var stringMatcher = Ioc.Default.GetRequiredService();
+ StringMatcher.Instance = stringMatcher;
+ stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
InternationalizationManager.Instance.Settings = _settings;
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
PluginManager.LoadPlugins(_settings.PluginSettings);
- _mainVM = new MainViewModel(_settings);
- API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
+ API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -91,14 +101,15 @@ namespace Flow.Launcher
await PluginManager.InitializePluginsAsync(API);
await imageLoadertask;
- var window = new MainWindow(_settings, _mainVM);
+ var mainVM = Ioc.Default.GetRequiredService();
+ var window = new MainWindow(_settings, mainVM);
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = window;
Current.MainWindow.Title = Constant.FlowLauncher;
- HotKeyMapper.Initialize(_mainVM);
+ HotKeyMapper.Initialize(mainVM);
// main windows needs initialized before theme change because of blur settings
ThemeManager.Instance.Settings = _settings;
@@ -147,11 +158,11 @@ namespace Flow.Launcher
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
}
});
}
@@ -194,7 +205,7 @@ namespace Flow.Launcher
public void OnSecondAppStarted()
{
- _mainVM.Show();
+ Ioc.Default.GetRequiredService().Show();
}
}
}
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 4ec249c2b..cab3915d5 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
@@ -83,12 +83,13 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
all
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf24..50765294c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -25,7 +25,7 @@ using Flow.Launcher.Infrastructure.Storage;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher
{
@@ -33,15 +33,15 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly PinyinAlphabet _alphabet;
+ private readonly IAlphabet _alphabet;
#region Constructor
- public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
+ public PublicAPIInstance()
{
- _settingsVM = settingsVM;
- _mainVM = mainVM;
- _alphabet = alphabet;
+ _settingsVM = Ioc.Default.GetRequiredService();
+ _mainVM = Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3..f5141a8fa 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -25,6 +25,7 @@ using System.Windows.Input;
using System.ComponentModel;
using Flow.Launcher.Infrastructure.Image;
using System.Windows.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.ViewModel
{
@@ -58,13 +59,13 @@ namespace Flow.Launcher.ViewModel
#region Constructor
- public MainViewModel(Settings settings)
+ public MainViewModel()
{
_queryTextBeforeLeaveResults = "";
_queryText = "";
_lastQuery = new Query();
- Settings = settings;
+ Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
{
switch (args.PropertyName)
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 95a1eb675..7549db1a3 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -13,11 +14,11 @@ public class SettingWindowViewModel : BaseModel
public Settings Settings { get; }
- public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
+ public SettingWindowViewModel()
{
- Settings = settings;
- Updater = updater;
- Portable = portable;
+ Settings = Ioc.Default.GetRequiredService();
+ Updater = Ioc.Default.GetRequiredService();
+ Portable = Ioc.Default.GetRequiredService();
}
public async void UpdateApp()
From a748141b1e8d7342336068ef65cc0890eac63992 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:47:49 +0800
Subject: [PATCH 044/200] Use IPublicAPI instead
---
Flow.Launcher/App.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 8cd054148..9b86c6cc4 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -27,7 +27,7 @@ namespace Flow.Launcher
{
public partial class App : IDisposable, ISingleInstanceApp
{
- public static PublicAPIInstance API { get; private set; }
+ public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
@@ -93,7 +93,7 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
+ API = Ioc.Default.GetRequiredService();
Http.API = API;
Http.Proxy = _settings.Proxy;
From 3cb9d1dce4b606cc80fb3a7fc9e51da08237c1b8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 20:04:44 +0800
Subject: [PATCH 045/200] Remove IApp & AppExtensions and use dependency
injection instead
---
Flow.Launcher.Core/AppExtensions.cs | 15 ------------
Flow.Launcher.Core/Configuration/Portable.cs | 24 +++++++++++--------
.../Environments/AbstractPluginEnvironment.cs | 11 +++++----
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/IApp.cs | 13 ----------
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 3 ++-
.../Resource/Internationalization.cs | 3 ++-
Flow.Launcher.Core/Resource/Theme.cs | 7 ++++--
Flow.Launcher.Core/Updater.cs | 17 +++++++------
Flow.Launcher/App.xaml.cs | 2 ++
.../ViewModel/SettingWindowViewModel.cs | 10 ++++++--
14 files changed, 54 insertions(+), 59 deletions(-)
delete mode 100644 Flow.Launcher.Core/AppExtensions.cs
delete mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
deleted file mode 100644
index b02612d72..000000000
--- a/Flow.Launcher.Core/AppExtensions.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Windows;
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core;
-
-///
-/// Extension properties and functions of the current application singleton object.
-///
-public static class AppExtensions
-{
- ///
- /// Gets the public API of the current application singleton object.
- ///
- public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
-}
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index cb375c586..069154364 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,11 +9,15 @@ using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
///
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
///
@@ -40,7 +44,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +68,7 @@ namespace Flow.Launcher.Core.Configuration
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +99,13 @@ namespace Flow.Launcher.Core.Configuration
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +161,13 @@ namespace Flow.Launcher.Core.Configuration
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => API.ShowMsgBox(s));
- if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
+ if (API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +176,9 @@ namespace Flow.Launcher.Core.Configuration
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => API.ShowMsgBox(s));
- AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
+ API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +190,7 @@ namespace Flow.Launcher.Core.Configuration
if (roamingLocationExists && portableLocationExists)
{
- AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index cada05031..451df6147 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -8,11 +8,14 @@ using System.Linq;
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
+ protected readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
internal abstract string Language { get; }
internal abstract string EnvName { get; }
@@ -25,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal virtual string FileDialogFilter => string.Empty;
- internal abstract string PluginsSettingsFilePath { get; set; }
+ internal abstract string PluginsSettingsFilePath { get; set; }
internal List PluginMetadataList;
@@ -57,7 +60,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
EnvName,
Environment.NewLine
);
- if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +85,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
}
else
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +101,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 56bc20b4f..607c19062 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 1d43b815a..399f7cc03 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 49bf4e958..e8cb72e11 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
deleted file mode 100644
index 233fd5ed1..000000000
--- a/Flow.Launcher.Core/IApp.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core
-{
- ///
- /// Interface for the current application singleton object exposing the properties
- /// and functions that can be accessed from anywhere in the application.
- ///
- public interface IApp
- {
- public IPublicAPI PublicAPI { get; }
- }
-}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 9e1cf3b9d..a776c10ab 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ namespace Flow.Launcher.Core.Plugin
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 8cbeb7473..4827cf69d 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins.Environments;
#pragma warning disable IDE0005
using Flow.Launcher.Infrastructure.Logger;
@@ -119,7 +120,7 @@ namespace Flow.Launcher.Core.Plugin
_ = Task.Run(() =>
{
- AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ Ioc.Default.GetRequiredService().ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index a1cefabe3..de066dda1 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -11,6 +11,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Globalization;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
@@ -124,7 +125,7 @@ namespace Flow.Launcher.Core.Resource
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (Ioc.Default.GetRequiredService().ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 8622d4caf..2749da532 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -11,6 +11,8 @@ using System.Windows.Media.Effects;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
{
@@ -22,6 +24,7 @@ namespace Flow.Launcher.Core.Resource
private const int ShadowExtraMargin = 32;
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
private readonly List _themeDirectories = new List();
private ResourceDictionary _oldResource;
private string _oldTheme;
@@ -108,7 +111,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +121,7 @@ namespace Flow.Launcher.Core.Resource
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 8745d54b7..373418055 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,14 +17,17 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core
{
public class Updater
{
- public string GitHubRepository { get; }
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
- public Updater(string gitHubRepository)
+ public string GitHubRepository { get; set; }
+
+ public void Initialize(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
}
@@ -53,7 +56,7 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +71,9 @@ namespace Flow.Launcher.Core
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
- AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
+ API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +86,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9b86c6cc4..0d6d9855c 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,6 +74,8 @@ namespace Flow.Launcher
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+ Ioc.Default.GetRequiredService().Initialize();
+
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 7549db1a3..bbd47e731 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -8,15 +8,21 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; }
+ public Updater Updater { get; private set; }
- public IPortable Portable { get; }
+ public IPortable Portable { get; private set; }
public Settings Settings { get; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
+ }
+
+ public void Initialize()
+ {
+ // We don not initialize Updater and Portable in the constructor because we want to avoid
+ // recrusive dependency injection
Updater = Ioc.Default.GetRequiredService();
Portable = Ioc.Default.GetRequiredService();
}
From 2a423f09bb3fe6c3dfb6dd9f03cce4ce410c5936 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 09:36:14 +0800
Subject: [PATCH 046/200] Improve code quality
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 7134fc760..b3a265e29 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -8,13 +8,13 @@ namespace Flow.Launcher.Infrastructure
{
public class StringMatcher
{
- private readonly MatchOption _defaultMatchOption = new MatchOption();
+ private readonly MatchOption _defaultMatchOption = new();
public SearchPrecisionScore UserSettingSearchPrecision { get; set; }
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
_alphabet = Ioc.Default.GetRequiredService();
}
@@ -242,16 +242,16 @@ namespace Flow.Launcher.Infrastructure
return false;
}
- private bool IsAcronymChar(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymChar(string stringToCompare, int compareStringIndex)
=> char.IsUpper(stringToCompare[compareStringIndex]) ||
compareStringIndex == 0 || // 0 index means char is the start of the compare string, which is an acronym
char.IsWhiteSpace(stringToCompare[compareStringIndex - 1]);
- private bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
=> stringToCompare[compareStringIndex] >= 0 && stringToCompare[compareStringIndex] <= 9;
// To get the index of the closest space which preceeds the first matching index
- private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
+ private static int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
{
var closestSpaceIndex = -1;
From ff110b3c49ec139da1222e3ffcb210596eb4642e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:01:50 +0800
Subject: [PATCH 047/200] Fix test project build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29..5822057a2 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- public StringMatcher()
+ public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = Ioc.Default.GetRequiredService();
+ _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From c3f71c213e8b24870292f4489515558850c9c5b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:18:35 +0800
Subject: [PATCH 048/200] Revert "Fix test project build issue"
This reverts commit ff110b3c49ec139da1222e3ffcb210596eb4642e.
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 5822057a2..b3a265e29 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ namespace Flow.Launcher.Infrastructure
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
- _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From 3bebb690935e4b99a508f5a9e98593760f45360c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:21:14 +0800
Subject: [PATCH 049/200] Fix unitest build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 6 +++++
Flow.Launcher.Test/FuzzyMatcherTest.cs | 22 ++++++++++---------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29..f5f02cbfc 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -19,6 +19,12 @@ namespace Flow.Launcher.Infrastructure
_alphabet = Ioc.Default.GetRequiredService();
}
+ // This is a workaround to allow unit tests to set the instance
+ public StringMatcher(IAlphabet alphabet)
+ {
+ _alphabet = alphabet;
+ }
+
public static StringMatcher Instance { get; internal set; }
public static MatchResult FuzzySearch(string query, string stringToCompare)
diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs
index d7f143218..d97ce227c 100644
--- a/Flow.Launcher.Test/FuzzyMatcherTest.cs
+++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs
@@ -21,6 +21,8 @@ namespace Flow.Launcher.Test
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
private const string VisualStudioCode = "Visual Studio Code";
+ private readonly IAlphabet alphabet = null;
+
public List GetSearchStrings()
=> new List
{
@@ -59,7 +61,7 @@ namespace Flow.Launcher.Test
};
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in sources)
{
results.Add(new Result
@@ -81,7 +83,7 @@ namespace Flow.Launcher.Test
public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(string searchString)
{
var compareString = "Can have rum only in my glass";
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore;
Assert.True(scoreResult == 0);
@@ -97,7 +99,7 @@ namespace Flow.Launcher.Test
string searchTerm)
{
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in GetSearchStrings())
{
results.Add(new Result
@@ -147,7 +149,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString, int expectedScore)
{
// When, Given
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
// Should
@@ -181,7 +183,7 @@ namespace Flow.Launcher.Test
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -232,7 +234,7 @@ namespace Flow.Launcher.Test
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -260,7 +262,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -293,7 +295,7 @@ namespace Flow.Launcher.Test
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
+ var matcher = new StringMatcher(alphabet) { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -323,7 +325,7 @@ namespace Flow.Launcher.Test
string secondName, string secondDescription, string secondExecutableName)
{
// Act
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore;
var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore;
var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore;
@@ -358,7 +360,7 @@ namespace Flow.Launcher.Test
public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString, string compareString,
int desiredScore)
{
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var score = matcher.FuzzyMatch(queryString, compareString).Score;
Assert.IsTrue(score == desiredScore,
$@"Query: ""{queryString}""
From 8d8384965ea5d39c62d7ce2b865114555b393146 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 12:00:45 +0800
Subject: [PATCH 050/200] Improve dependency injection in updater & settings
view model & settings page
---
Flow.Launcher.Core/Updater.cs | 20 ++++++++--------
Flow.Launcher/App.xaml.cs | 7 +++---
.../CustomQueryHotkeySetting.xaml.cs | 5 +---
Flow.Launcher/PublicAPIInstance.cs | 20 +++++++++++-----
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../SettingsPaneGeneralViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 5 ++--
Flow.Launcher/SettingWindow.xaml.cs | 18 ++++++++++-----
.../ViewModel/SettingWindowViewModel.cs | 23 ++-----------------
9 files changed, 46 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 373418055..7a25447b4 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -34,14 +34,14 @@ namespace Flow.Launcher.Core
private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);
- public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
+ public async Task UpdateAppAsync(bool silentUpdate = true)
{
await UpdateLock.WaitAsync().ConfigureAwait(false);
try
{
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("pleaseWait"),
- api.GetTranslation("update_flowlauncher_update_check"));
+ API.ShowMsg(API.GetTranslation("pleaseWait"),
+ API.GetTranslation("update_flowlauncher_update_check"));
using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false);
@@ -56,13 +56,13 @@ namespace Flow.Launcher.Core
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(API.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"),
- api.GetTranslation("update_flowlauncher_updating"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_update_found"),
+ API.GetTranslation("update_flowlauncher_updating"));
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);
@@ -73,7 +73,7 @@ namespace Flow.Launcher.Core
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
- API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ API.ShowMsgBox(string.Format(API.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -86,7 +86,7 @@ namespace Flow.Launcher.Core
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, API.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
@@ -99,8 +99,8 @@ namespace Flow.Launcher.Core
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"),
- api.GetTranslation("update_flowlauncher_check_connection"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_fail"),
+ API.GetTranslation("update_flowlauncher_check_connection"));
}
finally
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 0d6d9855c..9384aae3d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,8 +74,6 @@ namespace Flow.Launcher
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
- Ioc.Default.GetRequiredService().Initialize();
-
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
@@ -96,6 +94,7 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
API = Ioc.Default.GetRequiredService();
+ ((PublicAPIInstance)API).Initialize();
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -160,11 +159,11 @@ namespace Flow.Launcher
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
}
});
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 47460ff7d..eab2705d0 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -6,20 +6,17 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.Core;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- private SettingWindow _settingWidow;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
public Settings Settings { get; }
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
+ public CustomQueryHotkeySetting(Settings settings)
{
- _settingWidow = settingWidow;
Settings = settings;
InitializeComponent();
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 50765294c..54e97f6c6 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -26,6 +26,7 @@ using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -33,19 +34,26 @@ namespace Flow.Launcher
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly IAlphabet _alphabet;
- #region Constructor
+ private Updater _updater;
+
+ #region Constructor & Initialization
public PublicAPIInstance()
{
_settingsVM = Ioc.Default.GetRequiredService();
_mainVM = Ioc.Default.GetRequiredService();
- _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
+ public void Initialize()
+ {
+ // We need to initialize Updater not in the constructor because we want to avoid
+ // recrusive dependency injection
+ _updater = Ioc.Default.GetRequiredService();
+ }
+
#endregion
#region Public API
@@ -78,14 +86,14 @@ namespace Flow.Launcher
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _settingsVM.UpdateApp();
+ public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
public void SaveAppAllSettings()
{
PluginManager.Save();
_mainVM.Save();
_settingsVM.Save();
- ImageLoader.Save();
+ _ = ImageLoader.Save();
}
public Task ReloadAllPluginData() => PluginManager.ReloadDataAsync();
@@ -105,7 +113,7 @@ namespace Flow.Launcher
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
+ SettingWindow sw = SingletonWindowOpener.Open();
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 05fb16f5c..cb434f399 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -96,7 +96,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
}
[RelayCommand]
- private Task UpdateApp() => _updater.UpdateAppAsync(App.API, false);
+ private Task UpdateApp() => _updater.UpdateAppAsync(false);
private void ClearLogFolder()
{
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3d94355e6..4e498ba23 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -160,7 +160,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
private void UpdateApp()
{
- _ = _updater.UpdateAppAsync(App.API, false);
+ _ = _updater.UpdateAppAsync(false);
}
public bool AutoUpdates
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index fb57f499b..b13aaefe3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -7,7 +7,6 @@ using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Flow.Launcher.Core;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -71,7 +70,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings);
+ var window = new CustomQueryHotkeySetting(Settings);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -79,7 +78,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings).ShowDialog();
+ new CustomQueryHotkeySetting(Settings).ShowDialog();
}
[RelayCommand]
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cb3f1e4a1..ab639e987 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -3,6 +3,7 @@ using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Helper;
@@ -17,16 +18,21 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
+ private readonly Updater _updater;
+ private readonly IPortable _portable;
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
+ public SettingWindow()
{
+ var viewModel = Ioc.Default.GetRequiredService();
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
- _api = api;
+ _updater = Ioc.Default.GetRequiredService();
+ _portable = Ioc.Default.GetRequiredService();
+ _api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
}
@@ -125,7 +131,7 @@ public partial class SettingWindow
WindowState = _settings.SettingWindowState;
}
- private bool IsPositionValid(double top, double left)
+ private static bool IsPositionValid(double top, double left)
{
foreach (var screen in Screen.AllScreens)
{
@@ -145,7 +151,7 @@ public partial class SettingWindow
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
- var left = (dip2.X - this.ActualWidth) / 2 + dip1.X;
+ var left = (dip2.X - ActualWidth) / 2 + dip1.X;
return left;
}
@@ -154,13 +160,13 @@ public partial class SettingWindow
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
- var top = (dip2.Y - this.ActualHeight) / 2 + dip1.Y - 20;
+ var top = (dip2.Y - ActualHeight) / 2 + dip1.Y - 20;
return top;
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
+ var paneData = new PaneData(_settings, _updater, _portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index bbd47e731..37276a1ad 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,37 +1,18 @@
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel;
-public class SettingWindowViewModel : BaseModel
+public partial class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; private set; }
-
- public IPortable Portable { get; private set; }
-
- public Settings Settings { get; }
+ public Settings Settings { get; init; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
}
- public void Initialize()
- {
- // We don not initialize Updater and Portable in the constructor because we want to avoid
- // recrusive dependency injection
- Updater = Ioc.Default.GetRequiredService();
- Portable = Ioc.Default.GetRequiredService();
- }
-
- public async void UpdateApp()
- {
- await Updater.UpdateAppAsync(App.API, false);
- }
-
///
/// Save Flow settings. Plugins settings are not included.
///
From abe943b69339963dff909ecf5c8d9aaa6dc391ce Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 18 Jan 2025 18:39:44 +0800
Subject: [PATCH 051/200] Fix system language code fetch issue
---
.../Resource/Internationalization.cs | 58 +++++++++----------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 70f23c897..13efdda56 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -23,19 +23,45 @@ namespace Flow.Launcher.Core.Resource
private const string Extension = ".xaml";
private readonly List _languageDirectories = new List();
private readonly List _oldResources = new List();
+ private readonly string SystemLanguageCode;
public Internationalization()
{
AddFlowLauncherLanguageDirectory();
+ SystemLanguageCode = GetSystemLanguageCode();
}
-
private void AddFlowLauncherLanguageDirectory()
{
var directory = Path.Combine(Constant.ProgramDirectory, Folder);
_languageDirectories.Add(directory);
}
+ private static string GetSystemLanguageCode()
+ {
+ var availableLanguages = AvailableLanguages.GetAvailableLanguages();
+
+ // Retrieve the language identifiers for the current culture
+ var currentCulture = CultureInfo.CurrentCulture;
+ var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
+ var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
+ var fullName = currentCulture.Name;
+
+ // Try to find a match in the available languages list
+ foreach (var language in availableLanguages)
+ {
+ var languageCode = language.LanguageCode;
+
+ if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
+ {
+ return languageCode;
+ }
+ }
+
+ return DefaultLanguageCode;
+ }
internal void AddPluginLanguageDirectories(IEnumerable plugins)
{
@@ -74,7 +100,7 @@ namespace Flow.Launcher.Core.Resource
var isSystem = false;
if (languageCode == Constant.SystemLanguageCode)
{
- languageCode = GetSystemLanguageCode();
+ languageCode = SystemLanguageCode;
isSystem = true;
}
@@ -178,36 +204,10 @@ namespace Flow.Launcher.Core.Resource
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
+ list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(SystemLanguageCode)));
return list;
}
- private string GetSystemLanguageCode()
- {
- var availableLanguages = AvailableLanguages.GetAvailableLanguages();
-
- // Retrieve the language identifiers for the current culture
- var currentCulture = CultureInfo.CurrentCulture;
- var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
- var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
- var fullName = currentCulture.Name;
-
- // Try to find a match in the available languages list
- foreach (var language in availableLanguages)
- {
- var languageCode = language.LanguageCode;
-
- if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
- {
- return languageCode;
- }
- }
-
- return DefaultLanguageCode;
- }
-
public string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
From 1bf045f3e729f39e835bc1a6b3e7f9416a9c5bda Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 19 Jan 2025 15:15:02 +0800
Subject: [PATCH 052/200] Make fileMode usage between progress and non-progress
paths consistent
---
Flow.Launcher.Infrastructure/Http/Http.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 0b5d1b05a..0b3f2be65 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -97,7 +97,7 @@ namespace Flow.Launcher.Infrastructure.Http
if (canReportProgress && reportProgress != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync(token);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+ await using var fileStream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 8192, true);
var buffer = new byte[8192];
long totalRead = 0;
From c32435f2ed741249289d573c5092bbc0e8cb036a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 19 Jan 2025 15:44:26 +0800
Subject: [PATCH 053/200] Use api to call download function & Add message box
for all download operations
---
.../PluginsManager.cs | 129 ++++++++++--------
1 file changed, 71 insertions(+), 58 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index aee76e65e..ce51e8700 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -142,37 +142,15 @@ namespace Flow.Launcher.Plugin.PluginsManager
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- var exceptionHappened = false;
try
{
using var cts = new CancellationTokenSource();
if (!plugin.IsFromLocalInstallPath)
{
- if (File.Exists(filePath))
- File.Delete(filePath);
-
- var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- await Context.API.ShowProgressBoxAsync(prgBoxTitle,
- async (reportProgress) =>
- {
- if (reportProgress == null)
- {
- // when reportProgress is null, it means there is expcetion with the progress box
- // so we record it with exceptionHappened and return so that progress box will close instantly
- exceptionHappened = true;
- return;
- }
- else
- {
- await Http.DownloadAsync(plugin.UrlDownload, filePath, reportProgress, cts.Token).ConfigureAwait(false);
- }
- }, cts.Cancel);
-
- // if exception happened while downloading and user does not cancel downloading,
- // we need to redownload the plugin
- if (exceptionHappened && (!cts.IsCancellationRequested))
- await Http.DownloadAsync(plugin.UrlDownload, filePath, null, cts.Token).ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}",
+ plugin.UrlDownload, filePath, cts);
}
else
{
@@ -221,6 +199,34 @@ namespace Flow.Launcher.Plugin.PluginsManager
}
}
+ private async Task DeleteFileAndDownloadMsgBoxAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts)
+ {
+ if (File.Exists(filePath))
+ File.Delete(filePath);
+
+ var exceptionHappened = false;
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
+ {
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
+ }
+ else
+ {
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ }
+ }, cts.Cancel);
+
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!cts.IsCancellationRequested))
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath).ConfigureAwait(false);
+ }
+
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
@@ -308,43 +314,48 @@ namespace Flow.Launcher.Plugin.PluginsManager
_ = Task.Run(async delegate
{
+ using var cts = new CancellationTokenSource();
+
if (!x.PluginNewUserPlugin.IsFromLocalInstallPath)
{
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
-
- await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}",
+ x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
}
else
{
downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath;
}
-
- PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
- downloadToFilePath);
-
- if (Settings.AutoRestartAfterChanging)
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
{
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(
- Context.API.GetTranslation(
- "plugin_pluginsmanager_update_success_restart"),
- x.Name));
- Context.API.RestartApp();
+ return;
}
else
{
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(
- Context.API.GetTranslation(
- "plugin_pluginsmanager_update_success_no_restart"),
- x.Name));
+ PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ downloadToFilePath);
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(
+ Context.API.GetTranslation(
+ "plugin_pluginsmanager_update_success_restart"),
+ x.Name));
+ Context.API.RestartApp();
+ }
+ else
+ {
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(
+ Context.API.GetTranslation(
+ "plugin_pluginsmanager_update_success_no_restart"),
+ x.Name));
+ }
}
}).ContinueWith(t =>
{
@@ -405,16 +416,18 @@ namespace Flow.Launcher.Plugin.PluginsManager
try
{
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
+ using var cts = new CancellationTokenSource();
- await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.PluginNewUserPlugin.Name}",
+ plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
- downloadToFilePath);
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ return;
+ else
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
+ downloadToFilePath);
}
catch (Exception ex)
{
From d21b9362cf098c99030ba8a91fd545cf418c2991 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Mon, 20 Jan 2025 09:14:28 -0600
Subject: [PATCH 054/200] do not try catch the error for jsonrpc v2
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 45 ++++++--------------
1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 5a6633525..305b28150 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -26,54 +26,33 @@ namespace Flow.Launcher.Core.Plugin
protected override async Task ExecuteResultAsync(JsonRPCResult result)
{
- try
- {
- var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
- argument: result.JsonRPCAction.Parameters);
+ var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
+ argument: result.JsonRPCAction.Parameters);
- return res.Hide;
- }
- catch
- {
- return false;
- }
+ return res.Hide;
}
private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
public override List LoadContextMenus(Result selectedResult)
{
- try
- {
- var res = JTF.Run(() => RPC.InvokeWithCancellationAsync("context_menu",
- new object[] { selectedResult.ContextData }));
+ var res = JTF.Run(() => RPC.InvokeWithCancellationAsync("context_menu",
+ new object[] { selectedResult.ContextData }));
- var results = ParseResults(res);
+ var results = ParseResults(res);
- return results;
- }
- catch
- {
- return new List();
- }
+ return results;
}
public override async Task> QueryAsync(Query query, CancellationToken token)
{
- try
- {
- var res = await RPC.InvokeWithCancellationAsync("query",
- new object[] { query, Settings.Inner },
- token);
+ var res = await RPC.InvokeWithCancellationAsync("query",
+ new object[] { query, Settings.Inner },
+ token);
- var results = ParseResults(res);
+ var results = ParseResults(res);
- return results;
- }
- catch
- {
- return new List();
- }
+ return results;
}
From 5d164293b915d9c5d924b739ea3e0f13ad386542 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 20 Jan 2025 22:39:42 +0000
Subject: [PATCH 055/200] Bump FSharp.Core from 9.0.100 to 9.0.101
Bumps [FSharp.Core](https://github.com/dotnet/fsharp) from 9.0.100 to 9.0.101.
- [Release notes](https://github.com/dotnet/fsharp/releases)
- [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md)
- [Commits](https://github.com/dotnet/fsharp/commits)
---
updated-dependencies:
- dependency-name: FSharp.Core
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 8aeca4699..df2f4d2cb 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -54,7 +54,7 @@
-
+
From 198442621a94de8aabf26e56d58dec751080c294 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 21 Jan 2025 14:37:14 +0800
Subject: [PATCH 056/200] Add support for record key
---
Flow.Launcher.Plugin/Result.cs | 17 +++++++++++++++
Flow.Launcher/Storage/TopMostRecord.cs | 18 ++++++++++++----
Flow.Launcher/Storage/UserSelectedRecord.cs | 24 ++++++++++++++++-----
3 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index c6ca81cf3..bb005752e 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -185,6 +185,16 @@ namespace Flow.Launcher.Plugin
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
};
}
@@ -252,6 +262,13 @@ namespace Flow.Launcher.Plugin
///
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.
+ /// If the plugin does not specific this, FL just uses Title and SubTitle to identify this result.
+ ///
+ public string RecordKey { get; set; } = string.Empty;
+
///
/// Info of the preview section of a
///
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index cbd0b88fc..05cf01401 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -33,7 +33,8 @@ namespace Flow.Launcher.Storage
{
PluginID = result.PluginID,
Title = result.Title,
- SubTitle = result.SubTitle
+ SubTitle = result.SubTitle,
+ RecordKey = result.RecordKey
};
records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
@@ -49,12 +50,21 @@ namespace Flow.Launcher.Storage
public string Title { get; set; }
public string SubTitle { get; set; }
public string PluginID { get; set; }
+ public string RecordKey { get; set; }
public bool Equals(Result r)
{
- return Title == r.Title
- && SubTitle == r.SubTitle
- && PluginID == r.PluginID;
+ if (string.IsNullOrEmpty(RecordKey) || string.IsNullOrEmpty(r.RecordKey))
+ {
+ return Title == r.Title
+ && SubTitle == r.SubTitle
+ && PluginID == r.PluginID;
+ }
+ else
+ {
+ return RecordKey == r.RecordKey
+ && PluginID == r.PluginID;
+ }
}
}
}
diff --git a/Flow.Launcher/Storage/UserSelectedRecord.cs b/Flow.Launcher/Storage/UserSelectedRecord.cs
index d6405005d..6da36747d 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -15,7 +15,6 @@ namespace Flow.Launcher.Storage
[JsonInclude, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Dictionary records { get; private set; }
-
public UserSelectedRecord()
{
recordsWithQuery = new Dictionary();
@@ -45,8 +44,15 @@ namespace Flow.Launcher.Storage
private static int GenerateResultHashCode(Result result)
{
- int hashcode = GenerateStaticHashCode(result.Title);
- return GenerateStaticHashCode(result.SubTitle, hashcode);
+ if (string.IsNullOrEmpty(result.RecordKey))
+ {
+ int hashcode = GenerateStaticHashCode(result.Title);
+ return GenerateStaticHashCode(result.SubTitle, hashcode);
+ }
+ else
+ {
+ return GenerateStaticHashCode(result.RecordKey);
+ }
}
private static int GenerateQueryAndResultHashCode(Query query, Result result)
@@ -58,8 +64,16 @@ namespace Flow.Launcher.Storage
int hashcode = GenerateStaticHashCode(query.ActionKeyword);
hashcode = GenerateStaticHashCode(query.Search, hashcode);
- hashcode = GenerateStaticHashCode(result.Title, hashcode);
- hashcode = GenerateStaticHashCode(result.SubTitle, hashcode);
+
+ if (string.IsNullOrEmpty(result.RecordKey))
+ {
+ hashcode = GenerateStaticHashCode(result.Title, hashcode);
+ hashcode = GenerateStaticHashCode(result.SubTitle, hashcode);
+ }
+ else
+ {
+ hashcode = GenerateStaticHashCode(result.RecordKey, hashcode);
+ }
return hashcode;
}
From ed399371976b60436eeb9042c59696859eed3caf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 21 Jan 2025 16:19:28 +0800
Subject: [PATCH 057/200] Initialize App.API earlier & Improve code quality
---
Flow.Launcher/App.xaml.cs | 5 ++---
Flow.Launcher/PublicAPIInstance.cs | 13 ++-----------
2 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9384aae3d..a64c9e750 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -70,6 +70,8 @@ namespace Flow.Launcher
).Build();
Ioc.Default.ConfigureServices(host.Services);
+ API = Ioc.Default.GetRequiredService();
+
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
@@ -93,9 +95,6 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService();
- ((PublicAPIInstance)API).Initialize();
-
Http.API = API;
Http.Proxy = _settings.Proxy;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 54e97f6c6..0329d6973 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -35,9 +35,7 @@ namespace Flow.Launcher
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private Updater _updater;
-
- #region Constructor & Initialization
+ #region Constructor
public PublicAPIInstance()
{
@@ -47,13 +45,6 @@ namespace Flow.Launcher
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
- public void Initialize()
- {
- // We need to initialize Updater not in the constructor because we want to avoid
- // recrusive dependency injection
- _updater = Ioc.Default.GetRequiredService();
- }
-
#endregion
#region Public API
@@ -86,7 +77,7 @@ namespace Flow.Launcher
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
+ public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
public void SaveAppAllSettings()
{
From f9983b587712bdc439022f4ac19bda46133d9ab8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 22 Jan 2025 12:25:56 +0800
Subject: [PATCH 058/200] Move dependency injection codes to constructor
---
Flow.Launcher/App.xaml.cs | 47 +++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index a64c9e750..d983ab000 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -30,7 +30,31 @@ namespace Flow.Launcher
public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
- private Settings _settings;
+ private readonly Settings _settings;
+
+ public App()
+ {
+ // Initialize settings
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
+ }
[STAThread]
public static void Main()
@@ -49,27 +73,6 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- // Initialize settings
- var storage = new FlowLauncherJsonStorage();
- _settings = storage.Load();
- _settings.Initialize(storage);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
- // Configure the dependency injection container
- var host = Host.CreateDefaultBuilder()
- .UseContentRoot(AppContext.BaseDirectory)
- .ConfigureServices(services => services
- .AddSingleton(_ => _settings)
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- ).Build();
- Ioc.Default.ConfigureServices(host.Services);
-
API = Ioc.Default.GetRequiredService();
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
From fec553c87ca451d2d5cac3e1e71998e702fe8b8c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 24 Jan 2025 12:11:48 +0800
Subject: [PATCH 059/200] Improve uninstaller check function
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 39 +++++++++++++++++---
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index e311a0b94..5ccccc24e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -41,9 +41,13 @@ namespace Flow.Launcher.Plugin.Program
"uninst000.exe",
"uninstall.exe"
};
- // For cases when the uninstaller is named like "Uninstall Program Name.exe"
- private const string CommonUninstallerPrefix = "uninstall";
- private const string CommonUninstallerSuffix = ".exe";
+ private static readonly string[] commonUninstallerPrefixs =
+ {
+ "uninstall",
+ "卸载"
+ };
+ private const string ExeUninstallerSuffix = ".exe";
+ private const string InkUninstallerSuffix = ".lnk";
static Main()
{
@@ -96,10 +100,33 @@ namespace Flow.Launcher.Plugin.Program
{
if (!_settings.HideUninstallers) return true;
if (program is not Win32 win32) return true;
+
+ // First check the executable path
var fileName = Path.GetFileName(win32.ExecutablePath);
- return !commonUninstallerNames.Contains(fileName, StringComparer.OrdinalIgnoreCase) &&
- !(fileName.StartsWith(CommonUninstallerPrefix, StringComparison.OrdinalIgnoreCase) &&
- fileName.EndsWith(CommonUninstallerSuffix, StringComparison.OrdinalIgnoreCase));
+ // For cases when the uninstaller is named like "uninst.exe"
+ if (commonUninstallerNames.Contains(fileName, StringComparer.OrdinalIgnoreCase)) return false;
+ // For cases when the uninstaller is named like "Uninstall Program Name.exe"
+ foreach (var prefix in commonUninstallerPrefixs)
+ {
+ if (fileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
+ fileName.EndsWith(ExeUninstallerSuffix, StringComparison.OrdinalIgnoreCase))
+ return false;
+ }
+
+ // Second check the ink path
+ if (!string.IsNullOrEmpty(win32.LnkResolvedPath))
+ {
+ var inkFileName = Path.GetFileName(win32.FullPath);
+ // For cases when the uninstaller is named like "Uninstall Program Name.ink"
+ foreach (var prefix in commonUninstallerPrefixs)
+ {
+ if (inkFileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
+ inkFileName.EndsWith(InkUninstallerSuffix, StringComparison.OrdinalIgnoreCase))
+ return false;
+ }
+ }
+
+ return true;
}
public async Task InitAsync(PluginInitContext context)
From 71dad9f35616b0d0f6f2a3df4c7dca5791ec17ba Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 24 Jan 2025 18:35:11 +0800
Subject: [PATCH 060/200] Add support for more uninstaller prefixs
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 27 ++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 5ccccc24e..511794f89 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -43,8 +43,31 @@ namespace Flow.Launcher.Plugin.Program
};
private static readonly string[] commonUninstallerPrefixs =
{
- "uninstall",
- "卸载"
+ "uninstall",//en
+ "卸载",//zh-cn
+ "卸載",//zh-tw
+ "видалити",//uk-UA
+ "удалить",//ru
+ "désinstaller",//fr
+ "アンインストール",//ja
+ "deïnstalleren",//nl
+ "odinstaluj",//pl
+ "afinstallere",//da
+ "deinstallieren",//de
+ "삭제",//ko
+ "деинсталирај",//sr
+ "desinstalar",//pt-pt
+ "desinstalar",//pt-br
+ "desinstalar",//es
+ "desinstalar",//es-419
+ "disinstallare",//it
+ "avinstallere",//nb-NO
+ "odinštalovať",//sk
+ "kaldır",//tr
+ "odinstalovat",//cs
+ "إلغاء التثبيت",//ar
+ "gỡ bỏ",//vi-vn
+ "הסרה"//he
};
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
From 0c7dc07c743df01bce72c001061ede34b9b0fc08 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 26 Jan 2025 09:34:07 +1100
Subject: [PATCH 061/200] fix typo
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 511794f89..00b97e114 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -136,7 +136,7 @@ namespace Flow.Launcher.Plugin.Program
return false;
}
- // Second check the ink path
+ // Second check the lnk path
if (!string.IsNullOrEmpty(win32.LnkResolvedPath))
{
var inkFileName = Path.GetFileName(win32.FullPath);
From 0e700cdfcc5aced08e75e19c38f33836d7276628 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sun, 26 Jan 2025 10:42:32 +1100
Subject: [PATCH 062/200] rename GetSystemLanguageCode method + add comment
---
Flow.Launcher.Core/Resource/Internationalization.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 13efdda56..ef38e8be0 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -28,7 +28,7 @@ namespace Flow.Launcher.Core.Resource
public Internationalization()
{
AddFlowLauncherLanguageDirectory();
- SystemLanguageCode = GetSystemLanguageCode();
+ SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
private void AddFlowLauncherLanguageDirectory()
@@ -37,11 +37,13 @@ namespace Flow.Launcher.Core.Resource
_languageDirectories.Add(directory);
}
- private static string GetSystemLanguageCode()
+ private static string GetSystemLanguageCodeAtStartup()
{
var availableLanguages = AvailableLanguages.GetAvailableLanguages();
- // Retrieve the language identifiers for the current culture
+ // Retrieve the language identifiers for the current culture.
+ // ChangeLanguage method overrides the CultureInfo.CurrentCulture, so this needs to
+ // be called at startup in order to get the correct lang code of system.
var currentCulture = CultureInfo.CurrentCulture;
var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
From 1562c88ea71a0f56033553016682a51bc019d590 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:07:40 +0800
Subject: [PATCH 063/200] Improve context menu item action response
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++++
Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 1 +
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 ++
3 files changed, 7 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3..b12e97e0b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1273,6 +1273,8 @@ namespace Flow.Launcher.ViewModel
{
_topMostRecord.Remove(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ App.API.BackToQueryResults();
+ App.API.ReQuery();
return false;
}
};
@@ -1289,6 +1291,8 @@ namespace Flow.Launcher.ViewModel
{
_topMostRecord.AddOrUpdate(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ App.API.BackToQueryResults();
+ App.API.ReQuery();
return false;
}
};
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index feccc74c8..3f3b7cb58 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -242,6 +242,7 @@ namespace Flow.Launcher.Plugin.Explorer
var name = "Plugin: Folder";
var message = $"File not found: {e.Message}";
Context.API.ShowMsgError(name, message);
+ return false;
}
return true;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 00b97e114..6ba7047f2 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -264,6 +264,8 @@ namespace Flow.Launcher.Plugin.Program
Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_success"),
Context.API.GetTranslation(
"flowlauncher_plugin_program_disable_dlgtitle_success_message"));
+ Context.API.BackToQueryResults();
+ Context.API.ReQuery();
return false;
},
IcoPath = "Images/disable.png",
From ae5186dacfad5fd354867b1ec254edaa913e0a52 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:21:30 +0800
Subject: [PATCH 064/200] Remove context menu cache
---
Flow.Launcher/ViewModel/MainViewModel.cs | 15 +--------------
1 file changed, 1 insertion(+), 14 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index b12e97e0b..2d232ebdd 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -34,8 +34,6 @@ namespace Flow.Launcher.ViewModel
private bool _isQueryRunning;
private Query _lastQuery;
- private Result lastContextMenuResult = new Result();
- private List lastContextMenuResults = new List();
private string _queryTextBeforeLeaveResults;
private readonly FlowLauncherJsonStorage _historyItemsStorage;
@@ -986,19 +984,10 @@ namespace Flow.Launcher.ViewModel
if (selected != null) // SelectedItem returns null if selection is empty.
{
List results;
- if (selected == lastContextMenuResult)
- {
- results = lastContextMenuResults;
- }
- else
- {
+
results = PluginManager.GetContextMenusForPlugin(selected);
- lastContextMenuResults = results;
- lastContextMenuResult = selected;
results.Add(ContextMenuTopMost(selected));
results.Add(ContextMenuPluginInfo(selected.PluginID));
- }
-
if (!string.IsNullOrEmpty(query))
{
@@ -1381,8 +1370,6 @@ namespace Flow.Launcher.ViewModel
lastHistoryIndex = 1;
// Trick for no delay
MainWindowOpacity = 0;
- lastContextMenuResult = new Result();
- lastContextMenuResults = new List();
if (ExternalPreviewVisible)
CloseExternalPreview();
From 00de8611e1996d724c48672b5712c4db8f071b63 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:37:41 +0800
Subject: [PATCH 065/200] Remove useless obsolete constructor
---
Flow.Launcher.Plugin/Query.cs | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index b41675a1a..e182491c2 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json.Serialization;
+using System.Text.Json.Serialization;
namespace Flow.Launcher.Plugin
{
@@ -9,15 +6,6 @@ namespace Flow.Launcher.Plugin
{
public Query() { }
- [Obsolete("Use the default Query constructor.")]
- public Query(string rawQuery, string search, string[] terms, string[] searchTerms, string actionKeyword = "")
- {
- Search = search;
- RawQuery = rawQuery;
- SearchTerms = searchTerms;
- ActionKeyword = actionKeyword;
- }
-
///
/// Raw query, this includes action keyword if it has
/// We didn't recommend use this property directly. You should always use Search property.
From 95c8475c436b687822ddee2b342da5e4945225b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:45:58 +0800
Subject: [PATCH 066/200] Fix null exception when result is from context menu &
Add documents
---
Flow.Launcher/Storage/TopMostRecord.cs | 2 ++
Flow.Launcher/Storage/UserSelectedRecord.cs | 2 ++
Flow.Launcher/ViewModel/MainViewModel.cs | 14 +++++++++-----
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index cbd0b88fc..e76c57493 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,6 +12,8 @@ namespace Flow.Launcher.Storage
internal bool IsTopMost(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to check if the result is top most
if (records.IsEmpty || result.OriginQuery == null ||
!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
diff --git a/Flow.Launcher/Storage/UserSelectedRecord.cs b/Flow.Launcher/Storage/UserSelectedRecord.cs
index d6405005d..4f62d2b08 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -51,6 +51,8 @@ namespace Flow.Launcher.Storage
private static int GenerateQueryAndResultHashCode(Query query, Result result)
{
+ // query is null when user select the context menu item directly of one item from query list
+ // so we only need to consider the result
if (query == null)
{
return GenerateResultHashCode(result);
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2d232ebdd..5c3251bfc 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -396,11 +396,15 @@ namespace Flow.Launcher.ViewModel
})
.ConfigureAwait(false);
-
if (SelectedIsFromQueryResults())
{
_userSelectedRecord.Add(result);
- _history.Add(result.OriginQuery.RawQuery);
+ // origin query is null when user select the context menu item directly of one item from query list
+ // so we don't want to add it to history
+ if (result.OriginQuery != null)
+ {
+ _history.Add(result.OriginQuery.RawQuery);
+ }
lastHistoryIndex = 1;
}
@@ -985,9 +989,9 @@ namespace Flow.Launcher.ViewModel
{
List results;
- results = PluginManager.GetContextMenusForPlugin(selected);
- results.Add(ContextMenuTopMost(selected));
- results.Add(ContextMenuPluginInfo(selected.PluginID));
+ results = PluginManager.GetContextMenusForPlugin(selected);
+ results.Add(ContextMenuTopMost(selected));
+ results.Add(ContextMenuPluginInfo(selected.PluginID));
if (!string.IsNullOrEmpty(query))
{
From 80f54ba0de3b55c6ef1cac360078dddd9a1e07a4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:51:12 +0800
Subject: [PATCH 067/200] Fix more possible origin query null exception &
Remove useless load function
---
Flow.Launcher/Storage/TopMostRecord.cs | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index e76c57493..a2af6fe92 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -26,11 +26,25 @@ namespace Flow.Launcher.Storage
internal void Remove(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to remove the record
+ if (result.OriginQuery == null)
+ {
+ return;
+ }
+
records.Remove(result.OriginQuery.RawQuery, out _);
}
internal void AddOrUpdate(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to add or update the record
+ if (result.OriginQuery == null)
+ {
+ return;
+ }
+
var record = new Record
{
PluginID = result.PluginID,
@@ -39,11 +53,6 @@ namespace Flow.Launcher.Storage
};
records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
-
- public void Load(Dictionary dictionary)
- {
- records = new ConcurrentDictionary(dictionary);
- }
}
public class Record
From 1c7e29013e96efb1abecdb3bb9f1a2043017b49c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:11:27 +0800
Subject: [PATCH 068/200] Fix setting window freeze issue & Improve singleton
window opener
---
Flow.Launcher/Helper/SingletonWindowOpener.cs | 21 +++++++++++++++----
Flow.Launcher/SettingWindow.xaml.cs | 4 ++--
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Helper/SingletonWindowOpener.cs b/Flow.Launcher/Helper/SingletonWindowOpener.cs
index b5c2d8b55..5282b61f9 100644
--- a/Flow.Launcher/Helper/SingletonWindowOpener.cs
+++ b/Flow.Launcher/Helper/SingletonWindowOpener.cs
@@ -10,16 +10,29 @@ public static class SingletonWindowOpener
{
var window = Application.Current.Windows.OfType().FirstOrDefault(x => x.GetType() == typeof(T))
?? (T)Activator.CreateInstance(typeof(T), args);
-
+
// Fix UI bug
// Add `window.WindowState = WindowState.Normal`
// If only use `window.Show()`, Settings-window doesn't show when minimized in taskbar
// Not sure why this works tho
// Probably because, when `.Show()` fails, `window.WindowState == Minimized` (not `Normal`)
// https://stackoverflow.com/a/59719760/4230390
- window.WindowState = WindowState.Normal;
- window.Show();
-
+ // Ensure the window is not minimized before showing it
+ if (window.WindowState == WindowState.Minimized)
+ {
+ window.WindowState = WindowState.Normal;
+ }
+
+ // Ensure the window is visible
+ if (!window.IsVisible)
+ {
+ window.Show();
+ }
+ else
+ {
+ window.Activate(); // Bring the window to the foreground if already open
+ }
+
window.Focus();
return (T)window;
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cb3f1e4a1..d5b303516 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -34,11 +34,11 @@ public partial class SettingWindow
private void OnLoaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
- // Fix (workaround) for the window freezes after lock screen (Win+L)
+ // Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
- hwndTarget.RenderMode = RenderMode.Default;
+ hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
InitializePosition();
}
From 23a1e5bc5853d2f6a4ba0e83c1c36ac960da40d9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:39:12 +0800
Subject: [PATCH 069/200] Initialize public api instance in constructor so that
we can use App.API all the time
---
Flow.Launcher/App.xaml.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index d983ab000..f800ccd5d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -54,6 +54,9 @@ namespace Flow.Launcher
.AddSingleton()
).Build();
Ioc.Default.ConfigureServices(host.Services);
+
+ // Initialize the public API first
+ API = Ioc.Default.GetRequiredService();
}
[STAThread]
@@ -73,8 +76,6 @@ namespace Flow.Launcher
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- API = Ioc.Default.GetRequiredService();
-
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
From ed16d340cb1c43464b9046a2672edc5d189c01bc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:40:24 +0800
Subject: [PATCH 070/200] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 6 +++---
Flow.Launcher.Infrastructure/Http/Http.cs | 3 ++-
Flow.Launcher/App.xaml.cs | 3 +--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a776c10ab..0e8a4b776 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,6 +14,7 @@ using ISavable = Flow.Launcher.Plugin.ISavable;
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Plugin
{
@@ -28,7 +29,7 @@ namespace Flow.Launcher.Core.Plugin
public static readonly HashSet GlobalPlugins = new();
public static readonly Dictionary NonGlobalPlugins = new();
- public static IPublicAPI API { private set; get; }
+ public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService();
private static PluginsSettings Settings;
private static List _metadatas;
@@ -158,9 +159,8 @@ namespace Flow.Launcher.Core.Plugin
/// Call initialize for all plugins
///
/// return the list of failed to init plugins or null for none
- public static async Task InitializePluginsAsync(IPublicAPI api)
+ public static async Task InitializePluginsAsync()
{
- API = api;
var failedPlugins = new ConcurrentQueue();
var InitTasks = AllPlugins.Select(pair => Task.Run(async delegate
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 14b8eef4e..3711a6b0d 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -8,6 +8,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Threading;
using Flow.Launcher.Plugin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure.Http
{
@@ -17,7 +18,7 @@ namespace Flow.Launcher.Infrastructure.Http
private static HttpClient client = new HttpClient();
- public static IPublicAPI API { get; set; }
+ private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
static Http()
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index f800ccd5d..5f7f097e0 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -99,10 +99,9 @@ namespace Flow.Launcher
PluginManager.LoadPlugins(_settings.PluginSettings);
- Http.API = API;
Http.Proxy = _settings.Proxy;
- await PluginManager.InitializePluginsAsync(API);
+ await PluginManager.InitializePluginsAsync();
await imageLoadertask;
var mainVM = Ioc.Default.GetRequiredService();
From 6a2389f4b8c95d87ee72041a0e78812333fe3fd3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 10:45:05 +0800
Subject: [PATCH 071/200] Fix test project build issue
---
Flow.Launcher.Infrastructure/Http/Http.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 3711a6b0d..78545a87b 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -18,8 +18,6 @@ namespace Flow.Launcher.Infrastructure.Http
private static HttpClient client = new HttpClient();
- private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
-
static Http()
{
// need to be added so it would work on a win10 machine
@@ -79,7 +77,7 @@ namespace Flow.Launcher.Infrastructure.Http
}
catch (UriFormatException e)
{
- API.ShowMsg("Please try again", "Unable to parse Http Proxy");
+ Ioc.Default.GetRequiredService().ShowMsg("Please try again", "Unable to parse Http Proxy");
Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
}
}
From 70c8ea18fc59fc743142e1b9c53b6c062a89138d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:11:27 +0800
Subject: [PATCH 072/200] Fix setting window freeze issue & Improve singleton
window opener
---
Flow.Launcher/Helper/SingletonWindowOpener.cs | 21 +++++++++++++++----
Flow.Launcher/SettingWindow.xaml.cs | 4 ++--
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Helper/SingletonWindowOpener.cs b/Flow.Launcher/Helper/SingletonWindowOpener.cs
index b5c2d8b55..5282b61f9 100644
--- a/Flow.Launcher/Helper/SingletonWindowOpener.cs
+++ b/Flow.Launcher/Helper/SingletonWindowOpener.cs
@@ -10,16 +10,29 @@ public static class SingletonWindowOpener
{
var window = Application.Current.Windows.OfType().FirstOrDefault(x => x.GetType() == typeof(T))
?? (T)Activator.CreateInstance(typeof(T), args);
-
+
// Fix UI bug
// Add `window.WindowState = WindowState.Normal`
// If only use `window.Show()`, Settings-window doesn't show when minimized in taskbar
// Not sure why this works tho
// Probably because, when `.Show()` fails, `window.WindowState == Minimized` (not `Normal`)
// https://stackoverflow.com/a/59719760/4230390
- window.WindowState = WindowState.Normal;
- window.Show();
-
+ // Ensure the window is not minimized before showing it
+ if (window.WindowState == WindowState.Minimized)
+ {
+ window.WindowState = WindowState.Normal;
+ }
+
+ // Ensure the window is visible
+ if (!window.IsVisible)
+ {
+ window.Show();
+ }
+ else
+ {
+ window.Activate(); // Bring the window to the foreground if already open
+ }
+
window.Focus();
return (T)window;
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 4cc125fa4..bdc7675ef 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -35,11 +35,11 @@ public partial class SettingWindow
private void OnLoaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
- // Fix (workaround) for the window freezes after lock screen (Win+L)
+ // Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
- hwndTarget.RenderMode = RenderMode.Default;
+ hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
InitializePosition();
}
From f9518c073df83ec24c8c7f979ed4cda87c117449 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Mon, 27 Jan 2025 16:39:07 +1100
Subject: [PATCH 073/200] New Crowdin updates (#3062)
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations resources.resx (Portuguese)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Arabic)
[ci skip]
* New translations en.xaml (Czech)
[ci skip]
* New translations en.xaml (Danish)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Italian)
[ci skip]
* New translations en.xaml (Japanese)
[ci skip]
* New translations en.xaml (Korean)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (Turkish)
[ci skip]
* New translations en.xaml (Ukrainian)
[ci skip]
* New translations en.xaml (Chinese Simplified)
[ci skip]
* New translations en.xaml (Chinese Traditional)
[ci skip]
* New translations en.xaml (Vietnamese)
[ci skip]
* New translations en.xaml (Portuguese, Brazilian)
[ci skip]
* New translations en.xaml (Norwegian Bokmal)
[ci skip]
* New translations en.xaml (Serbian (Latin))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish, Latin America)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Arabic)
[ci skip]
* New translations en.xaml (Czech)
[ci skip]
* New translations en.xaml (Danish)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Italian)
[ci skip]
* New translations en.xaml (Japanese)
[ci skip]
* New translations en.xaml (Korean)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (Turkish)
[ci skip]
* New translations en.xaml (Ukrainian)
[ci skip]
* New translations en.xaml (Chinese Simplified)
[ci skip]
* New translations en.xaml (Chinese Traditional)
[ci skip]
* New translations en.xaml (Vietnamese)
[ci skip]
* New translations en.xaml (Portuguese, Brazilian)
[ci skip]
* New translations en.xaml (Norwegian Bokmal)
[ci skip]
* New translations en.xaml (Serbian (Latin))
[ci skip]
* New translations en.xaml (Spanish, Latin America)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
---------
Co-authored-by: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
---
Flow.Launcher/Languages/ar.xaml | 2 +
Flow.Launcher/Languages/cs.xaml | 2 +
Flow.Launcher/Languages/da.xaml | 2 +
Flow.Launcher/Languages/de.xaml | 18 +-
Flow.Launcher/Languages/es-419.xaml | 2 +
Flow.Launcher/Languages/es.xaml | 6 +-
Flow.Launcher/Languages/fr.xaml | 2 +
Flow.Launcher/Languages/he.xaml | 458 +++
Flow.Launcher/Languages/it.xaml | 2 +
Flow.Launcher/Languages/ja.xaml | 2 +
Flow.Launcher/Languages/ko.xaml | 2 +
Flow.Launcher/Languages/nb.xaml | 2 +
Flow.Launcher/Languages/nl.xaml | 2 +
Flow.Launcher/Languages/pl.xaml | 4 +-
Flow.Launcher/Languages/pt-br.xaml | 2 +
Flow.Launcher/Languages/pt-pt.xaml | 2 +
Flow.Launcher/Languages/ru.xaml | 11 +-
Flow.Launcher/Languages/sk.xaml | 3 +-
Flow.Launcher/Languages/sr.xaml | 2 +
Flow.Launcher/Languages/tr.xaml | 2 +
Flow.Launcher/Languages/uk-UA.xaml | 2 +
Flow.Launcher/Languages/vi.xaml | 2 +
Flow.Launcher/Languages/zh-cn.xaml | 2 +
Flow.Launcher/Languages/zh-tw.xaml | 2 +
Flow.Launcher/Properties/Resources.he-IL.resx | 130 +
.../Languages/de.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/he.xaml | 28 +
.../Languages/de.xaml | 4 +-
.../Languages/he.xaml | 15 +
.../Languages/de.xaml | 22 +-
.../Languages/he.xaml | 165 ++
.../Languages/ru.xaml | 10 +-
.../Languages/de.xaml | 4 +-
.../Languages/he.xaml | 9 +
.../Languages/he.xaml | 63 +
.../Languages/de.xaml | 10 +-
.../Languages/he.xaml | 11 +
.../Languages/de.xaml | 2 +-
.../Languages/fr.xaml | 2 +-
.../Languages/he.xaml | 95 +
.../Languages/he.xaml | 17 +
.../Languages/ru.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/he.xaml | 63 +
.../Languages/de.xaml | 10 +-
.../Languages/he.xaml | 17 +
.../Languages/ar.xaml | 3 +-
.../Languages/cs.xaml | 3 +-
.../Languages/da.xaml | 3 +-
.../Languages/de.xaml | 23 +-
.../Languages/es-419.xaml | 3 +-
.../Languages/es.xaml | 3 +-
.../Languages/fr.xaml | 5 +-
.../Languages/he.xaml | 52 +
.../Languages/it.xaml | 3 +-
.../Languages/ja.xaml | 3 +-
.../Languages/ko.xaml | 3 +-
.../Languages/nb.xaml | 3 +-
.../Languages/nl.xaml | 3 +-
.../Languages/pl.xaml | 3 +-
.../Languages/pt-br.xaml | 3 +-
.../Languages/pt-pt.xaml | 3 +-
.../Languages/ru.xaml | 5 +-
.../Languages/sk.xaml | 3 +-
.../Languages/sr.xaml | 3 +-
.../Languages/tr.xaml | 3 +-
.../Languages/uk-UA.xaml | 3 +-
.../Languages/vi.xaml | 3 +-
.../Languages/zh-cn.xaml | 3 +-
.../Languages/zh-tw.xaml | 3 +-
.../Properties/Resources.de-DE.resx | 40 +-
.../Properties/Resources.he-IL.resx | 2514 +++++++++++++++++
.../Properties/Resources.pt-PT.resx | 44 +-
74 files changed, 3835 insertions(+), 129 deletions(-)
create mode 100644 Flow.Launcher/Languages/he.xaml
create mode 100644 Flow.Launcher/Properties/Resources.he-IL.resx
create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index b096e7489..fa5c968d4 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -65,6 +65,8 @@
حفظ الاستعلام الأخير
اختيار الاستعلام الأخير
تفريغ الاستعلام الأخير
+ Preserve Last Action Keyword
+ Select Last Action Keyword
ارتفاع ثابت للنافذة
ارتفاع النافذة غير قابل للتعديل عن طريق السحب.
الحد الأقصى للنتائج المعروضة
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 8bc572c11..05adf095b 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -65,6 +65,8 @@
Zachovat poslední dotaz
Vybrat poslední dotaz
Smazat poslední dotaz
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Počet zobrazených výsledků
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index f8e3ea4a5..36970ad53 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -65,6 +65,8 @@
Preserve Last Query
Select last Query
Empty last Query
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Maksimum antal resultater vist
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 600d96e25..7f2e2bd8d 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -65,6 +65,8 @@
Letzte Abfrage beibehalten
Letzte Abfrage auswählen
Letzte Abfrage leeren
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Feste Fensterhöhe
Die Fensterhöhe ist durch Ziehen nicht anpassbar.
Maximal gezeigte Ergebnisse
@@ -77,7 +79,7 @@
Einstellung für Neuer Tab, Neues Fenster, Privater Modus.
Python-Pfad
Node.js-Pfad
- Bitte wählen Sie das Programm Node.js aus
+ Bitte wählen Sie die ausführbare Datei Node.js aus
Bitte wählen Sie pythonw.exe aus
Tippen immer im englischen Modus starten
Ändern Sie Ihre Eingabemethode temporär in den englischen Modus, wenn Sie Flow aktivieren.
@@ -166,8 +168,8 @@
Individuell anpassen
Fenstermodus
Opazität
- Theme {0} ist nicht vorhanden, Fallback auf Standard-Theme
- Theme {0} konnte nicht geladen werden, Fallback auf Standard-Theme
+ Theme {0} ist nicht vorhanden, Fallback auf Default-Theme
+ Theme {0} konnte nicht geladen werden, Fallback auf Default-Theme
Theme-Ordner
Theme-Ordner öffnen
Farbschema
@@ -175,7 +177,7 @@
Hell
Dunkel
Soundeffekt
- Einen kleinen Sound abspielen, wenn das Suchfenster geöffnet wird
+ Einen kurzen Sound abspielen, wenn das Suchfenster geöffnet wird
Lautstärke der Soundeffekte
Lautstärke des Soundeffekts anpassen
Windows Media Player ist nicht verfügbar und ist für die Lautstärkeregelung von Flow erforderlich. Bitte überprüfen Sie Ihre Installation, wenn Sie die Lautstärke anpassen müssen.
@@ -287,8 +289,8 @@
Versionshinweise
Tipps zur Nutzung
DevTools
- Ordner Einstellungen
- Ordner Logs
+ Ordner »Settings«
+ Ordner »Logs«
Logs löschen
Sind Sie sicher, dass Sie alle Logs löschen wollen?
Assistent
@@ -411,8 +413,8 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
Willkommen bei Flow Launcher
Hallo, dies ist das erste Mal, dass Sie Flow Launcher ausführen!
Bevor Sie beginnen, hilft dieser Assistent bei der Einrichtung von Flow Launcher. Sie können dies überspringen, wenn Sie möchten. Bitte wählen Sie eine Sprache
- Suchen und führen Sie alle Dateien und Anwendungen auf Ihrem PC aus
- Suchen Sie alles in Anwendungen, Dateien, Lesezeichen, YouTube, Twitter und vielem mehr. Alles bequem über Ihre Tastatur, ohne die Maus zu berühren.
+ Alle Dateien und Anwendungen auf Ihrem PC suchen und ausführen
+ Durchsuchen Sie alles von Anwendungen, Dateien, Lesezeichen, YouTube, Twitter und vielem mehr. Alles bequem über Ihre Tastatur, ohne die Maus zu berühren.
Flow Launcher startet mit dem unten stehenden Hotkey, probieren Sie ihn gleich aus. Um ihn zu ändern, klicken Sie auf die Eingabe und drücken Sie den gewünschten Hotkey auf der Tastatur.
Hotkeys
Aktions-Schlüsselwort und Befehle
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 9a682269c..0556c59ae 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -65,6 +65,8 @@
Conservar última consulta
Seleccionar última consulta
Borrar última consulta
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 328d98d41..bf22aea48 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -65,6 +65,8 @@
Mantener la última consulta
Seleccionar la última consulta
Limpiar la última consulta
+ Conservar palabra clave de última acción
+ Seleccionar palabra clave de última acción
Altura de la ventana fija
La altura de la ventana no se puede ajustar arrastrando el ratón.
Número máximo de resultados mostrados
@@ -218,7 +220,7 @@
Abrir menú contextual nativo
Abrir ventana de configuración
Copiar ruta del archivo
- Cambia a Modo Juego
+ Cambiar a Modo Juego
Cambiar historial
Abrir carpeta contenedora
Ejecutar como administrador
@@ -293,7 +295,7 @@
¿Está seguro de que desea eliminar todos los registros?
Asistente
Ubicación de datos del usuario
- La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portátil o no.
+ La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portable o no.
Abrir carpeta
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index b171dcc9e..e978e91ec 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -65,6 +65,8 @@
Conserver la dernière recherche
Sélectionner la dernière recherche
Ne pas afficher la dernière recherche
+ Conserver le mot clé de la dernière action
+ Sélectionnez le mot clé de la dernière action
Hauteur de fenêtre fixe
La hauteur de la fenêtre n'est pas réglable par glissement.
Résultats maximums à afficher
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
new file mode 100644
index 000000000..eeb33da17
--- /dev/null
+++ b/Flow.Launcher/Languages/he.xaml
@@ -0,0 +1,458 @@
+
+
+
+
+ Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
+ {2}{2}
+ Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
+
+ אנא בחר את קובץ ההפעלה {0}
+ לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).
+ נכשל בהפעלת תוספים
+ תוספים: {0} - נכשלים בטעינה ויהיו מושבתים, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
+
+
+ רישום מקש הקיצור "{0}" נכשל. ייתכן שמקש הקיצור נמצא בשימוש על ידי תוכנה אחרת. שנה למקש קיצור אחר, או צא מהתוכנה האחרת.
+ Flow Launcher
+ לא ניתן היה להפעיל את {0}
+ פורמט קובץ תוסף Flow Launcher לא חוקי
+ הגדר כגבוה ביותר בשאילתה זו
+ בטל העלאה בשאילתה זו
+ בצע שאילתה: {0}
+ Last execution time: {0}
+ פתח
+ הגדרות
+ אודות
+ יציאה
+ סגור
+ העתק
+ גזור
+ הדבק
+ Undo
+ בחר הכל
+ קובץ
+ תיקייה
+ טקסט
+ מצב משחק
+ השהה את השימוש במקשי קיצור.
+ Position Reset
+ Reset search window position
+
+
+ הגדרות
+ כללי
+ מצב נייד
+ אחסן את כל ההגדרות ונתוני המשתמש בתיקייה אחת (שימושי בשימוש עם כוננים נשלפים או שירותי ענן).
+ הפעל את Flow Launcher בעת הפעלת Window
+ שגיאה בהגדרת ההפעלה בעת הפעלת windows
+ הסתר את Flow Launcher כאשר הוא אינו החלון הפעיל
+ אל תציג התראות על גרסה חדשה
+ מיקום חלון החיפוש
+ זכור את המיקום האחרון
+ Monitor with Mouse Cursor
+ Monitor with Focused Window
+ צג ראשי
+ צג מותאם אישית
+ Search Window Position on Monitor
+ Center
+ Center Top
+ Left Top
+ Right Top
+ Custom Position
+ שפה
+ Last Query Style
+ Show/Hide previous results when Flow Launcher is reactivated.
+ Preserve Last Query
+ Select last Query
+ Empty last Query
+ Preserve Last Action Keyword
+ Select Last Action Keyword
+ Fixed Window Height
+ The window height is not adjustable by dragging.
+ Maximum results shown
+ You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
+ Ignore hotkeys in fullscreen mode
+ Disable Flow Launcher activation when a full screen application is active (Recommended for games).
+ Default File Manager
+ Select the file manager to use when opening the folder.
+ Default Web Browser
+ Setting for New Tab, New Window, Private Mode.
+ Python Path
+ Node.js Path
+ Please select the Node.js executable
+ Please select pythonw.exe
+ Always Start Typing in English Mode
+ Temporarily change your input method to English mode when activating Flow.
+ Auto Update
+ Select
+ Hide Flow Launcher on startup
+ Flow Launcher search window is hidden in the tray after starting up.
+ Hide tray icon
+ When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.
+ Query Search Precision
+ Changes minimum match score required for results.
+ None
+ Low
+ Regular
+ Search with Pinyin
+ Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
+ Always Preview
+ Always open preview panel when Flow activates. Press {0} to toggle preview.
+ Shadow effect is not allowed while current theme has blur effect enabled
+
+
+ Search Plugin
+ Ctrl+F to search plugins
+ No results found
+ Please try a different search.
+ Plugin
+ תוספים
+ מצא תוספים נוספים
+ On
+ Off
+ Action keyword Setting
+ Action keyword
+ Current action keyword
+ New action keyword
+ Change Action Keywords
+ Current Priority
+ New Priority
+ Priority
+ Change Plugin Results Priority
+ Plugin Directory
+ by
+ Init time:
+ Query time:
+ Version
+ Website
+ Uninstall
+
+
+
+ חנות תוספים
+ New Release
+ Recently Updated
+ תוספים
+ Installed
+ רענן
+ התקן
+ Uninstall
+ עדכון
+ Plugin already installed
+ New Version
+ This plugin has been updated within the last 7 days
+ New Update is Available
+
+
+
+
+ ערכת נושא
+ Appearance
+ גלריית ערכות נושא
+ How to create a theme
+ Hi There
+ Explorer
+ Search for files, folders and file contents
+ WebSearch
+ Search the web with different search engine support
+ Program
+ Launch programs as admin or a different user
+ ProcessKiller
+ Terminate unwanted processes
+ Search Bar Height
+ Item Height
+ Query Box Font
+ Result Title Font
+ Result Subtitle Font
+ Reset
+ Customize
+ Window Mode
+ Opacity
+ Theme {0} not exists, fallback to default theme
+ Fail to load theme {0}, fallback to default theme
+ Theme Folder
+ Open Theme Folder
+ Color Scheme
+ System Default
+ בהיר
+ כהה
+ Sound Effect
+ Play a small sound when the search window opens
+ Sound Effect Volume
+ Adjust the volume of the sound effect
+ Windows Media Player is unavailable and is required for Flow's volume adjustment. Please check your installation if you need to adjust volume.
+ Animation
+ Use Animation in UI
+ Animation Speed
+ The speed of the UI animation
+ Slow
+ Medium
+ Fast
+ Custom
+ Clock
+ Date
+ This theme supports two(light/dark) modes.
+ This theme supports Blur Transparent Background.
+
+
+
+ Hotkey
+ Hotkeys
+ Open Flow Launcher
+ Enter shortcut to show/hide Flow Launcher.
+ Toggle Preview
+ Enter shortcut to show/hide preview in search window.
+ Hotkey Presets
+ List of currently registered hotkeys
+ Open Result Modifier Key
+ Select a modifier key to open selected result via keyboard.
+ Show Hotkey
+ Show result selection hotkey with results.
+ Auto Complete
+ Runs autocomplete for the selected items.
+ Select Next Item
+ Select Previous Item
+ Next Page
+ Previous Page
+ Cycle Previous Query
+ Cycle Next Query
+ Open Context Menu
+ Open Native Context Menu
+ Open Setting Window
+ Copy File Path
+ Toggle Game Mode
+ Toggle History
+ Open Containing Folder
+ Run As Admin
+ Refresh Search Results
+ Reload Plugins Data
+ Quick Adjust Window Width
+ Quick Adjust Window Height
+ Use when require plugins to reload and update their existing data.
+ You can add one more hotkey for this function.
+ Custom Query Hotkeys
+ Custom Query Shortcuts
+ Built-in Shortcuts
+ שאילתה
+ Shortcut
+ Expansion
+ Description
+ מחק
+ ערוך
+ הוסף
+ None
+ אנא בחר פריט
+ Are you sure you want to delete {0} plugin hotkey?
+ Are you sure you want to delete shortcut: {0} with expansion {1}?
+ Get text from clipboard.
+ Get path from active explorer.
+ Query window shadow effect
+ Shadow effect has a substantial usage of GPU. Not recommended if your computer performance is limited.
+ Window Width Size
+ You can also quickly adjust this by using Ctrl+[ and Ctrl+].
+ Use Segoe Fluent Icons
+ Use Segoe Fluent Icons for query results where supported
+ Press Key
+
+
+ HTTP Proxy
+ Enable HTTP Proxy
+ HTTP Server
+ Port
+ User Name
+ Password
+ Test Proxy
+ שמור
+ Server field can't be empty
+ Port field can't be empty
+ Invalid port format
+ Proxy configuration saved successfully
+ Proxy configured correctly
+ Proxy connection failed
+
+
+ אודות
+ Website
+ GitHub
+ Docs
+ Version
+ Icons
+ You have activated Flow Launcher {0} times
+ Check for Updates
+ Become A Sponsor
+ New version {0} is available, would you like to restart Flow Launcher to use the update?
+ בדיקת העדכונים נכשלה, אנא בדוק את הגדרות החיבור ואת הגדרות ה-Proxy שלך לכתובת api.github.com.
+
+ Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com,
+ or go to https://github.com/Flow-Launcher/Flow.Launcher/releases to download updates manually.
+
+ Release Notes
+ Usage Tips
+ DevTools
+ Setting Folder
+ Log Folder
+ Clear Logs
+ Are you sure you want to delete all logs?
+ אשף
+ User Data Location
+ User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
+ Open Folder
+
+
+ Select File Manager
+ Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
+ For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
+ File Manager
+ Profile Name
+ File Manager Path
+ Arg For Folder
+ Arg For File
+
+
+ Default Web Browser
+ The default setting follows the OS default browser setting. If specified separately, flow uses that browser.
+ Browser
+ Browser Name
+ Browser Path
+ New Window
+ New Tab
+ Private Mode
+
+
+ Change Priority
+ Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number
+ Please provide an valid integer for Priority!
+
+
+ Old Action Keyword
+ New Action Keyword
+ ביטול
+ בוצע
+ Can't find specified plugin
+ New Action Keyword can't be empty
+ This new Action Keyword is already assigned to another plugin, please choose a different one
+ הצליח
+ הושלם בהצלחה
+ Enter the action keyword you like to use to start the plugin. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Custom Query Hotkey
+ Press a custom hotkey to open Flow Launcher and input the specified query automatically.
+ תצוגה מקדימה
+ Hotkey is unavailable, please select a new hotkey
+ Invalid plugin hotkey
+ עדכון
+ Binding Hotkey
+ Current hotkey is unavailable.
+ This hotkey is reserved for "{0}" and can't be used. Please choose another hotkey.
+ This hotkey is already in use by "{0}". If you press "Overwrite", it will be removed from "{0}".
+ Press the keys you want to use for this function.
+
+
+ Custom Query Shortcut
+ Enter a shortcut that automatically expands to the specified query.
+ A shortcut is expanded when it exactly matches the query.
+
+If you add an '@' prefix while inputting a shortcut, it matches any position in the query. Builtin shortcuts match any position in a query.
+
+ Shortcut already exists, please enter a new Shortcut or edit the existing one.
+ Shortcut and/or its expansion is empty.
+
+
+ שמור
+ Overwrite
+ ביטול
+ Reset
+ מחק
+ OK
+ Yes
+ No
+
+
+ Version
+ זמן
+ Please tell us how application crashed so we can fix it
+ שלח דיווח
+ ביטול
+ כללי
+ חריגים
+ Exception Type
+ Source
+ Stack Trace
+ Sending
+ Report sent successfully
+ Failed to send report
+ Flow Launcher got an error
+
+
+ Please wait...
+
+
+ Checking for new update
+ You already have the latest Flow Launcher version
+ Update found
+ Updating...
+
+ Flow Launcher was not able to move your user profile data to the new update version.
+ Please manually move your profile data folder from {0} to {1}
+
+ עדכון חדש
+ New Flow Launcher release {0} is now available
+ An error occurred while trying to install software updates
+ עדכון
+ ביטול
+ העדכון נכשל
+ Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.
+ This upgrade will restart Flow Launcher
+ Following files will be updated
+ Update files
+ Update description
+
+
+ דלג
+ Welcome to Flow Launcher
+ Hello, this is the first time you are running Flow Launcher!
+ Before starting, this wizard will assist in setting up Flow Launcher. You can skip this if you wish. Please choose a language
+ Search and run all files and applications on your PC
+ Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
+ Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.
+ Hotkeys
+ Action Keyword and Commands
+ Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.
+ Let's Start Flow Launcher
+ Finished. Enjoy Flow Launcher. Don't forget the hotkey to start :)
+
+
+
+ Back / Context Menu
+ Item Navigation
+ Open Context Menu
+ Open Containing Folder
+ Run as Admin / Open Folder in Default File Manager
+ Query History
+ Back to Result in Context Menu
+ Autocomplete
+ Open / Run Selected Item
+ Open Setting Window
+ Reload Plugin Data
+
+ Select first result
+ Select last result
+ Run current query again
+ Open result
+ Open result #{0}
+
+ Weather
+ Weather in Google Result
+ > ping 8.8.8.8
+ Shell Command
+ s Bluetooth
+ Bluetooth in Windows Settings
+ sn
+ Sticky Notes
+
+
+ File Size
+ Created
+ Last Modified
+
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index ddb1d5555..372f4630e 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -65,6 +65,8 @@
Conserva ultima ricerca
Seleziona ultima ricerca
Cancella ultima ricerca
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Altezza Finestra Fissa
L'altezza della finestra non si può regolare trascinando.
Numero massimo di risultati mostrati
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index 962b68017..e7671367a 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -65,6 +65,8 @@
前回のクエリを保存
前回のクエリを選択
前回のクエリを消去
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
結果の最大表示件数
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index 81dae9179..67bf2490a 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -65,6 +65,8 @@
직전 쿼리에 계속 입력
직전 쿼리 내용 선택
직전 쿼리 지우기
+ Preserve Last Action Keyword
+ Select Last Action Keyword
창 높이 고정
드래그로 창 높이를 조정하지 않습니다.
표시할 결과 수
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index b608f5c0b..e3b8e36da 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -65,6 +65,8 @@
Bevar siste spørring
Velg siste spørring
Tøm siste spørring
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fast vindushøyde
Vindushøyden kan ikke justeres ved å dra.
Maksimalt antall resultater vist
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index d5bd0f284..db440c3a0 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -65,6 +65,8 @@
Behoud laatste zoekopdracht
Selecteer laatste zoekopdracht
Laatste zoekopdracht verwijderen
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Vaste venster hoogte
De vensterhoogte is niet aanpasbaar door te slepen.
Laat maximale resultaten zien
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 7aa0d64b2..df7c9d2d4 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -65,6 +65,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Zachowaj ostatnie zapytanie
Wybierz ostatnie zapytanie
Puste ostatnie zapytanie
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Stała wysokość okna
Wysokość okna nie jest regulowana poprzez przeciąganie.
Maksymalna liczba wyników
@@ -361,7 +363,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
Nadpisz
Anuluj
Zresetuj
- Usu
+ Usuń
Aktualizuj
Tak
Nie
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index 6f6bb4df8..4a30ffda4 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -65,6 +65,8 @@
Preservar Última Consulta
Selecionar última consulta
Limpar última consulta
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index 9f316220d..470bf2b4e 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -65,6 +65,8 @@ Clique "Não" se já tiver instalado e, de seguida, ser-lhe-á solicit
Manter última consulta
Selecionar última consulta
Limpar última consulta
+ Manter palavra-chave da última ação
+ Selecionar palavra-chave da última ação
Altura fixa de janela
Não é possível ajustar o tamanho da janela por arrasto.
Número máximo de resultados
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index f501fd638..1c420100f 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -1,12 +1,13 @@
+
- Flow определил, что вы установили {0} плагины, которым требуется {1} для работы. Скачать {1}?
+ Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
{2}{2}
- Кликните нет, если он уже установлен, и вам будет предложено выбрать папку, где находится исполняемый файл {1}
+ Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
- Пожалуйста, выберите исполняемый файл {0}
- Не удалось установить путь к исполняемому файлу {0}, пожалуйста, попробуйте через настройки Flow (прокрутите вниз).
+ Please select the {0} executable
+ Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -64,6 +65,8 @@
Сохранение последнего запроса
Выбор последнего запроса
Очистить последний запрос
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Фиксированная высота окна
The window height is not adjustable by dragging.
Максимальное количество результатов
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index f91fd596d..3db778cc8 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -65,6 +65,8 @@
Ponechať
Označiť
Vymazať
+ Ponechať posledný akčný príkaz
+ Označiť posledný akčný príkaz
Pevná výška okna
Výška okna sa nedá nastaviť ťahaním.
Maximum výsledkov
@@ -454,4 +456,3 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s
Vytvorené
Upravené
-
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index af32a5cfe..fc5a1e2fc 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -65,6 +65,8 @@
Sačuvaj poslednji Upit
Selektuj poslednji Upit
Isprazni poslednji Upit
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Maksimum prikazanih rezultata
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index ecca292d9..cfb3689c3 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -65,6 +65,8 @@
Son Sorguyu Sakla
Son Sorguyu Sakla ve Tümünü Seç
Sorgu Kutusunu Temizle
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Sabit Pencere Yükseliği
Pencere yüksekliği sürükleme ile ayarlanamaz.
Maksimum Sonuç Sayısı
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index f74efa48b..09c576150 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -65,6 +65,8 @@
Зберегти останній запит
Вибрати останній запит
Очистити останній запит
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Фіксована висота вікна
Висота вікна не регулюється перетягуванням.
Максимальна кількість результатів
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index 802d4b06c..31e8ad2aa 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -65,6 +65,8 @@
Giữ lại truy vấn cuối cùng
Chọn truy vấn cuối cùng
Trống truy vấn cuối cùng
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Giữ nguyên chiều cao cửa sổ
Chiều cao cửa sổ không thể thay đổi bằng cách kéo.
Số kết quả tối đa
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 3a8217f59..681c715fb 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -65,6 +65,8 @@
保留上次搜索关键字
选择上次搜索关键字
清空上次搜索关键字
+ Preserve Last Action Keyword
+ Select Last Action Keyword
固定窗口高度
窗口高度不能通过拖动来调整。
最大结果显示个数
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 3cdf0a7b4..44be5257b 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -65,6 +65,8 @@
保留上一個查詢
選擇上一個查詢
清空上次搜尋關鍵字
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
最大結果顯示個數
diff --git a/Flow.Launcher/Properties/Resources.he-IL.resx b/Flow.Launcher/Properties/Resources.he-IL.resx
new file mode 100644
index 000000000..ca0f66f53
--- /dev/null
+++ b/Flow.Launcher/Properties/Resources.he-IL.resx
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\app.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Images\dev.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Images\gamemode.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
index c5d371c6c..4d1ad4bf1 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
@@ -16,7 +16,7 @@
URL des Lesezeichens in Zwischenablage kopieren
Browser laden aus:
Browser-Name
- URL des Lesezeichens in Zwischenablage kopieren
+ Pfad zu Datenverzeichnis
Hinzufügen
Bearbeiten
Löschen
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
index b80e4f926..db87ee281 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
@@ -23,6 +23,6 @@
Navegar
Otros
Motor del navegador
- Si no está utilizando Chrome, Firefox o Edge, o si está utilizando su versión portátil, debe añadir el directorio de datos de los marcadores y seleccionar el motor del navegador correcto para que este complemento funcione.
+ Si no está utilizando Chrome, Firefox o Edge, o si está utilizando su versión portable, debe añadir el directorio de datos de los marcadores y seleccionar el motor del navegador correcto para que este complemento funcione.
Por ejemplo: El motor de Brave es Chromium; y la ubicación por defecto de los datos de los marcadores es: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Para el motor de Firefox, el directorio de los marcadores es la carpeta de datos del usuario que contiene el archivo places.sqlite.
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
new file mode 100644
index 000000000..7c6f73ed7
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
@@ -0,0 +1,28 @@
+
+
+
+
+ Browser Bookmarks
+ Search your browser bookmarks
+
+
+ Bookmark Data
+ Open bookmarks in:
+ New window
+ New tab
+ Set browser from path:
+ Choose
+ Copy url
+ Copy the bookmark's url to clipboard
+ Load Browser From:
+ Browser Name
+ Data Directory Path
+ הוסף
+ ערוך
+ מחק
+ Browse
+ Others
+ Browser Engine
+ If you are not using Chrome, Firefox or Edge, or you are using their portable version, you need to add bookmarks data directory and select correct browser engine to make this plugin work.
+ For example: Brave's engine is Chromium; and its default bookmarks data location is: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". For Firefox engine, the bookmarks directory is the userdata folder contains the places.sqlite file.
+
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
index 47bcaacc9..d8da714dc 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
@@ -2,8 +2,8 @@
Rechner
- Ermöglicht mathematische Berechnungen (z. B. 5*3-2 in Flow Launcher)
- Nicht eine Zahl (NaN)
+ Ermöglicht mathematische Berechnungen. (Versuchen Sie 5*3-2 in Flow Launcher)
+ Nicht eine Zahl (NaN)
Ausdruck falsch oder unvollständig (Haben Sie einige Klammern vergessen?)
Diese Zahl in die Zwischenablage kopieren
Dezimaltrennzeichen
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
new file mode 100644
index 000000000..15598118c
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
@@ -0,0 +1,15 @@
+
+
+
+ Calculator
+ Allows to do mathematical calculations.(Try 5*3-2 in Flow Launcher)
+ Not a number (NaN)
+ Expression wrong or incomplete (Did you forget some parentheses?)
+ Copy this number to the clipboard
+ Decimal separator
+ The decimal separator to be used in the output.
+ Use system locale
+ Comma (,)
+ Dot (.)
+ Max. decimal places
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
index e3862df76..f2df655c7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
@@ -2,7 +2,7 @@
- Bitte treffen Sie zuerst eine Auswahl.
+ Bitte treffen Sie zuerst eine Auswahl
Bitte wählen Sie einen Ordner-Link aus
Sind Sie sicher, dass Sie {0} löschen wollen?
Sind Sie sicher, dass Sie diese Datei dauerhaft löschen möchten?
@@ -40,8 +40,8 @@
Shell-Pfad
Indexsuche ausgeschlossene Pfade
Ort des Suchergebnisses als Arbeitsverzeichnis der ausführbaren Datei verwenden
- Drücken Sie die Enter, um den Ordner im Default-Dateimanager zu öffnen
- Use Index Search For Path Search
+ Drücken Sie Enter, um Ordner im Default-Dateimanager zu öffnen
+ Indexsuche für Pfadsuche verwenden
Indexierungsoptionen
Suche:
Pfad-Suche:
@@ -60,10 +60,10 @@
Aktiviert
Deaktiviert
- Content Search Engine
- Directory Recursive Search Engine
- Index Search Engine
- Open Windows Index Option
+ Content-Suchmaschine
+ Verzeichnis Rekursive Suchmaschine
+ Suchmaschine indizieren
+ Windows-Indexierungsoptionen öffnen
Ausgeschlossene Dateitypen (durch Komma getrennt)
Zum Beispiel: exe,jpg,png
Maximale Ergebnisse
@@ -131,12 +131,12 @@
Pfad
Größe
Extension
- Type Name
+ Typname
Erstellungsdatum
Änderungsdatum
Attribute
- File List FileName
- Run Count
+ Dateilistenname
+ Ausführungszahl
Datum kürzlich geändert
Zugriffsdatum
Ausführungsdatum
@@ -145,7 +145,7 @@
Warnung: Dies ist keine Schnellsortieroption, Suchen können langsam sein
Vollständigen Pfad suchen
- Enable File/Folder Run Count
+ Datei-/Ordnerlaufzähler aktivieren
Klicken, um Everything zu starten oder zu installieren
Everything-Installation
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
new file mode 100644
index 000000000..0e1753d67
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -0,0 +1,165 @@
+
+
+
+
+ Please make a selection first
+ Please select a folder link
+ Are you sure you want to delete {0}?
+ Are you sure you want to permanently delete this file?
+ Are you sure you want to permanently delete this file/folder?
+ Deletion successful
+ Successfully deleted {0}
+ Assigning the global action keyword could bring up too many results during search. Please choose a specific action keyword
+ Quick Access can not be set to the global action keyword when enabled. Please choose a specific action keyword
+ The required service for Windows Index Search does not appear to be running
+ To fix this, start the Windows Search service. Select here to remove this warning
+ The warning message has been switched off. As an alternative for searching files and folders, would you like to install Everything plugin?{0}{0}Select 'Yes' to install Everything plugin, or 'No' to return
+ Explorer Alternative
+ Error occurred during search: {0}
+ Could not open folder
+ Could not open file
+
+
+ מחק
+ ערוך
+ הוסף
+ General Setting
+ Customise Action Keywords
+ Quick Access Links
+ Everything Setting
+ Preview Panel
+ Size
+ Date Created
+ Date Modified
+ Display File Info
+ Date and time format
+ Sort Option:
+ Everything Path:
+ Launch Hidden
+ Editor Path
+ Shell Path
+ Index Search Excluded Paths
+ Use search result's location as the working directory of the executable
+ Hit Enter to open folder in Default File Manager
+ Use Index Search For Path Search
+ Indexing Options
+ Search:
+ Path Search:
+ File Content Search:
+ Index Search:
+ Quick Access:
+ Current Action Keyword
+ בוצע
+ Enabled
+ When disabled Flow will not execute this search option, and will additionally revert back to '*' to free up the action keyword
+ Everything
+ Windows Index
+ Direct Enumeration
+ File Editor Path
+ Folder Editor Path
+ Enabled
+ Disabled
+
+ Content Search Engine
+ Directory Recursive Search Engine
+ Index Search Engine
+ Open Windows Index Option
+ Excluded File Types (comma seperated)
+ For example: exe,jpg,png
+ Maximum results
+ The maximum number of results requested from active search engine
+
+
+ Explorer
+ Find and manage files and folders via Windows Search or Everything
+
+
+ Ctrl + Enter to open the directory
+ Ctrl + Enter to open the containing folder
+
+
+ Copy path
+ Copy path of current item to clipboard
+ Copy
+ Copy current file to clipboard
+ Copy current folder to clipboard
+ מחק
+ Permanently delete current file
+ Permanently delete current folder
+ Path:
+ Delete the selected
+ Run as different user
+ Run the selected using a different user account
+ Open containing folder
+ Open the location that contains current item
+ Open With Editor:
+ Failed to open file at {0} with Editor {1} at {2}
+ Open With Shell:
+ Failed to open folder {0} with Shell {1} at {2}
+ Exclude current and sub-directories from Index Search
+ Excluded from Index Search
+ Open Windows Indexing Options
+ Manage indexed files and folders
+ Failed to open Windows Indexing Options
+ Add to Quick Access
+ Add current item to Quick Access
+ Successfully Added
+ Successfully added to Quick Access
+ Successfully Removed
+ Successfully removed from Quick Access
+ Add to Quick Access so it can be opened with Explorer's Search Activation action keyword
+ Remove from Quick Access
+ Remove from Quick Access
+ Remove current item from Quick Access
+ Show Windows Context Menu
+ Open With
+ Select a program to open with
+
+
+ {0} free of {1}
+ Open in Default File Manager
+
+ Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.
+
+
+
+ Failed to load Everything SDK
+ אזהרה: שירות Everything אינו פועל
+ שגיאה במהלך שאילתה לEverything
+ Sort By
+ Name
+ Path
+ Size
+ Extension
+ Type Name
+ Date Created
+ Date Modified
+ Attributes
+ File List FileName
+ Run Count
+ Date Recently Changed
+ Date Accessed
+ Date Run
+ ↑
+ ↓
+ Warning: This is not a Fast Sort option, searches may be slow
+
+ Search Full Path
+ Enable File/Folder Run Count
+
+ Click to launch or install Everything
+ Everything Installation
+ Installing Everything service. Please wait...
+ Successfully installed Everything service
+ Failed to automatically install Everything service. Please manually install it from https://www.voidtools.com
+ Click here to start it
+ Unable to find an Everything installation, would you like to manually select a location?{0}{0}Click no and Everything will be automatically installed for you
+ Do you want to enable content search for Everything?
+ It can be very slow without index (which is only supported in Everything v1.5+)
+
+
+ Native Context Menu
+ Display native context menu (experimental)
+ Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').
+ Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
index 38b9c29c6..911364fdf 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
@@ -43,7 +43,7 @@
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
- Search:
+ Поиск:
Path Search:
File Content Search:
Index Search:
@@ -78,17 +78,17 @@
Ctrl + Enter to open the containing folder
- Copy path
+ Скопировать путь
Copy path of current item to clipboard
- Copy
+ Скопировать
Copy current file to clipboard
Copy current folder to clipboard
Удалить
Permanently delete current file
Permanently delete current folder
- Path:
+ Путь:
Delete the selected
- Run as different user
+ Запустить от имени другого пользователя
Run the selected using a different user account
Open containing folder
Open the location that contains current item
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
index 50d3b01ed..f39f4d4be 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
@@ -1,9 +1,9 @@
- Plug-in-Aktions-Schlüsselwort {0} aktivieren
+ Aktions-Schlüsselwort für Plug-in {0} aktivieren
Plug-in-Indikator
- Bietet Vorschläge für Aktionswörter für Plug-ins
+ Bietet Vorschläge für Aktions-Schlüsselwörter für Plug-ins
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
new file mode 100644
index 000000000..893948d3d
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
@@ -0,0 +1,9 @@
+
+
+
+ Activate {0} plugin action keyword
+
+ Plugin Indicator
+ Provides plugins action words suggestions
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
new file mode 100644
index 000000000..e13a857a1
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
@@ -0,0 +1,63 @@
+
+
+
+
+ Downloading plugin
+ Successfully downloaded {0}
+ Error: Unable to download the plugin
+ {0} by {1} {2}{3}Would you like to uninstall this plugin? After the uninstallation Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to uninstall this plugin?
+ {0} by {1} {2}{3}Would you like to install this plugin? After the installation Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to install this plugin?
+ Plugin Install
+ Installing Plugin
+ Download and install {0}
+ Plugin Uninstall
+ Plugin {0} successfully installed. Restarting Flow, please wait...
+ Unable to find the plugin.json metadata file from the extracted zip file.
+ Error: A plugin which has the same or greater version with {0} already exists.
+ Error installing plugin
+ Error occurred while trying to install {0}
+ Error uninstalling plugin
+ No update available
+ All plugins are up to date
+ {0} by {1} {2}{3}Would you like to update this plugin? After the update Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to update this plugin?
+ Plugin Update
+ This plugin is already installed
+ Plugin Manifest Download Failed
+ Please check if you can connect to github.com. This error means you may not be able to install or update plugins.
+ Update all plugins
+ Would you like to update all plugins?
+ Would you like to update {0} plugins?{1}Flow Launcher will restart after updating all plugins.
+ Would you like to update {0} plugins?
+ {0} plugins successfully updated. Restarting Flow, please wait...
+ Plugin {0} successfully updated. Restarting Flow, please wait...
+ Installing from an unknown source
+ You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
+
+ Plugin {0} successfully installed. Please restart Flow.
+ Plugin {0} successfully uninstalled. Please restart Flow.
+ Plugin {0} successfully updated. Please restart Flow.
+ {0} plugins successfully updated. Please restart Flow.
+ Plugin {0} has already been modified. Please restart Flow before making any further changes.
+
+
+ Plugins Manager
+ Management of installing, uninstalling or updating Flow Launcher plugins
+ Unknown Author
+
+
+ Open website
+ Visit the plugin's website
+ See source code
+ See the plugin's source code
+ Suggest an enhancement or submit an issue
+ Suggest an enhancement or submit an issue to the plugin developer
+ Go to Flow's plugins repository
+ Visit the PluginsManifest repository to see community-made plugin submissions
+
+
+ Install from unknown source warning
+ Automatically restart Flow Launcher after installing/uninstalling/updating plugins
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
index b3429f7af..8697818dc 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
@@ -1,11 +1,11 @@
- Prozesskiller
- Beende laufende Prozesse durch Flow Launcher
+ Process Killer
+ Laufende Prozesse aus Flow Launcher beenden
- alle Instanzen von "{0} " beenden
- beende {0} Prozesse
- alle Instanzen beenden
+ Alle Instanzen von "{0}" beenden
+ {0} Prozesse beenden
+ Alle Instanzen beenden
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
new file mode 100644
index 000000000..c4cc85463
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
@@ -0,0 +1,11 @@
+
+
+
+ Process Killer
+ Kill running processes from Flow Launcher
+
+ kill all instances of "{0}"
+ kill {0} processes
+ kill all instances
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
index 81f2b7c7b..7923024ab 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
@@ -31,7 +31,7 @@
App-Pfad ausblenden
Für ausführbare Dateien wie UWP oder lnk den Dateipfad nicht mehr sichtbar machen
Uninstaller ausblenden
- Versteckt Programme mit gängigen Uninstaller-Namen, wie unins000.exe
+ Blendet Programme mit gängigen Uninstaller-Namen aus, wie unins000.exe
In Programmbeschreibung suchen
Flow wird in Programmbeschreibung suchen
Suffixe
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
index 3adc1fd33..b67a1a727 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
@@ -75,7 +75,7 @@
Masquer ce programme des résultats
Ouvrir le répertoire cible
- Programme
+ Programmes
Rechercher des programmes dans Flow Launcher
Chemin d'accès invalide
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
new file mode 100644
index 000000000..69b9324dc
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
@@ -0,0 +1,95 @@
+
+
+
+
+ Reset Default
+ מחק
+ ערוך
+ הוסף
+ Name
+ Enable
+ Enabled
+ Disable
+ Status
+ Enabled
+ Disabled
+ Location
+ All Programs
+ File Type
+ Reindex
+ Indexing
+ Index Sources
+ Options
+ UWP Apps
+ When enabled, Flow will load UWP Applications
+ Start Menu
+ When enabled, Flow will load programs from the start menu
+ Registry
+ When enabled, Flow will load programs from the registry
+ PATH
+ When enabled, Flow will load programs from the PATH environment variable
+ Hide app path
+ For executable files such as UWP or lnk, hide the file path from being visible
+ Hide uninstallers
+ Hides programs with common uninstaller names, such as unins000.exe
+ Search in Program Description
+ Flow will search program's description
+ Suffixes
+ Max Depth
+
+ Directory
+ Browse
+ File Suffixes:
+ Maximum Search Depth (-1 is unlimited):
+
+ Please select a program source
+ Are you sure you want to delete the selected program sources?
+ Another program source with the same location already exists.
+
+ Program Source
+ Edit directory and status of this program source.
+
+ עדכון
+ Program Plugin will only index files with selected suffixes and .url files with selected protocols.
+ Successfully updated file suffixes
+ File suffixes can't be empty
+ Protocols can't be empty
+
+ File Suffixes
+ URL Protocols
+ Steam Games
+ Epic Games
+ Http/Https
+ Custom URL Protocols
+ Custom File Suffixes
+
+ Insert file suffixes you want to index. Suffixes should be separated by ';'. (ex>bat;py)
+
+
+ Insert protocols of .url files you want to index. Protocols should be separated by ';', and should end with "://". (ex>ftp://;mailto://)
+
+
+ Run As Different User
+ Run As Administrator
+ Open containing folder
+ Disable this program from displaying
+ Open target folder
+
+ Program
+ Search programs in Flow Launcher
+
+ Invalid Path
+
+ Customized Explorer
+ Args
+ You can customize the explorer used for opening the container folder by inputing the Environmental Variable of the explorer you want to use. It will be useful to use CMD to test whether the Environmental Variable is available.
+ Enter the customized args you want to add for your customized explorer. %s for parent directory, %f for full path (which only works for win32). Check the explorer's website for details.
+
+
+ הצליח
+ Error
+ Successfully disabled this program from displaying in your query
+ This app is not intended to be run as administrator
+ Unable to run {0}
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
new file mode 100644
index 000000000..b7d02c558
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Replace Win+R
+ Close Command Prompt after pressing any key
+ Press any key to close this window...
+ Do not close Command Prompt after command execution
+ Always run as administrator
+ Run as different user
+ Shell
+ Allows to execute system commands from Flow Launcher
+ this command has been executed {0} times
+ execute command through command shell
+ Run As Administrator
+ Copy the command
+ Only show number of most used commands:
+
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
index bf3864c7b..20fc3fb5d 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
@@ -6,7 +6,7 @@
Press any key to close this window...
Не закрывать командную строку после выполнения команды
Всегда запускать с правами администратора
- Run as different user
+ Запустить от имени другого пользователя
Оболочка
Allows to execute system commands from Flow Launcher
эта команда была выполнена {0} раз
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
index cb8b00f52..5a5170838 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
@@ -46,7 +46,7 @@
Busca actualizaciones de Flow Launcher
Accede a la documentación de Flow Launcher para más ayuda y consejos de uso
Abre la ubicación donde se almacena la configuración de Flow Launcher
- Cambia a Modo Juego
+ Cambiar a Modo Juego
Correcto
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
new file mode 100644
index 000000000..b98fc47ee
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
@@ -0,0 +1,63 @@
+
+
+
+
+ Command
+ Description
+
+ Shutdown
+ Restart
+ Restart With Advanced Boot Options
+ Log Off/Sign Out
+ Lock
+ Sleep
+ Hibernate
+ Index Option
+ Empty Recycle Bin
+ Open Recycle Bin
+ יציאה
+ Save Settings
+ Restart Flow Launcher
+ הגדרות
+ Reload Plugin Data
+ Check For Update
+ Open Log Location
+ Flow Launcher Tips
+ Flow Launcher UserData Folder
+ Toggle Game Mode
+
+
+ Shutdown Computer
+ Restart Computer
+ Restart the computer with Advanced Boot Options for Safe and Debugging modes, as well as other options
+ Log off
+ Lock this computer
+ Close Flow Launcher
+ Restart Flow Launcher
+ Tweak Flow Launcher's settings
+ Put computer to sleep
+ Empty recycle bin
+ Open recycle bin
+ Indexing Options
+ Hibernate computer
+ Save all Flow Launcher settings
+ Refreshes plugin data with new content
+ Open Flow Launcher's log location
+ Check for new Flow Launcher update
+ Visit Flow Launcher's documentation for more help and how to use tips
+ Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
+
+
+ הצליח
+ All Flow Launcher settings saved
+ Reloaded all applicable plugin data
+ Are you sure you want to shut the computer down?
+ Are you sure you want to restart the computer?
+ Are you sure you want to restart the computer with Advanced Boot Options?
+ Are you sure you want to log off?
+
+ System Commands
+ Provides System related commands. e.g. shutdown, lock, settings etc.
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
index 9ae4c17df..ee13754d5 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
@@ -5,13 +5,13 @@
Neues Fenster
Neuer Tab
- Öffne URL:{0}
- Kann URL nicht öffnen:{0}
+ URL öffnen: {0}
+ URL kann nicht geöffnet werden: {0}
URL
- Öffne eine eingegebene URL mit Flow Launcher
+ Öffnen Sie die eingetippte URL in Flow Launcher
Bitte legen Sie Ihren Browser-Pfad fest:
- Auswählen
- URL öffnen: {0}
+ Wählen
+ Anwendung (*.exe)|*.exe|Alle Dateien|*.*
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
new file mode 100644
index 000000000..418731021
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Open search in:
+ New Window
+ New Tab
+
+ Open url:{0}
+ Can't open url:{0}
+
+ URL
+ Open the typed URL from Flow Launcher
+
+ Please set your browser path:
+ Choose
+ Application(*.exe)|*.exe|All files|*.*
+
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
index 623a5d5fb..6e92178db 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
@@ -29,7 +29,8 @@
وبالتالي، فإن الصيغة العامة للبحث على نتفليكس هي https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
العنوان
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
index e9f59929b..849f27f05 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
@@ -29,7 +29,8 @@
Obecný vzorec pro vyhledávání Netflixu je tedy https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Název
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
index 096abc5f1..2a7d4aa32 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
index 15788acaa..0c72b11bf 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
@@ -6,7 +6,7 @@
Neues Fenster
Neuer Tab
Browser aus Pfad festlegen:
- Auswählen
+ Wählen
Löschen
Bearbeiten
Hinzufügen
@@ -19,7 +19,7 @@
Suche
Autovervollständigung von Suchanfragen verwenden:
Daten automatisch vervollständigen aus:
- Bitte wähle einen Suchdienst
+ Bitte wählen Sie eine Websuche aus
Sind Sie sicher, dass Sie {0} löschen wollen?
Wenn Sie Flow eine Suche nach einer bestimmten Website hinzufügen möchten, geben Sie zunächst eine Dummy-Textzeichenfolge in die Suchleiste dieser Website ein und starten Sie die Suche. Kopieren Sie jetzt den Inhalt der Adressleiste des Browsers und fügen Sie ihn in das URL-Feld unten ein. Ersetzen Sie Ihre Testzeichenfolge durch {q}. Zum Beispiel, wenn Sie auf Netflix nach casino suchen, steht in der Adressleiste
https://www.netflix.com/search?q=Casino
@@ -30,23 +30,24 @@
https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Titel
Status
- Wähle Symbol
- Symbol
+ Icon auswählen
+ Icon
Abbrechen
- Ungültige Internetsuche
- Bitte Titel eingeben
- Aktions-Schlüsselwort ist bereits vorhanden. Bitte geben Sie ein anderes ein.
- Bitte URL eingeben
- Aktionsschlüsselwort existiert bereits. Bitte gebe ein anderes ein.
+ Ungültige Websuche
+ Bitte geben Sie einen Titel ein
+ Bitte geben Sie ein Aktions-Schlüsselwort ein
+ Bitte geben Sie eine URL ein
+ Aktions-Schlüsselwort ist bereits vorhanden. Bitte geben Sie ein anderes ein
Erfolg
Hinweis: Sie müssen keine benutzerdefinierten Bilder in diesem Verzeichnis ablegen, wenn die Version von Flow aktualisiert wird, gehen diese verloren. Flow kopiert automatisch jegliche Bilder außerhalb dieses Verzeichnisses herüber in den benutzerdefinierten Bildspeicherort von WebSearch.
- Internetsuche
+ Web-Suchen
Ermöglicht die Durchführung von Web-Suchen
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
index 6e992b944..517ac0918 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
index bb78d36b0..e6e4a94d2 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
@@ -29,7 +29,8 @@
De esta manera, la fórmula genérica para una búsqueda en Netflix será https://www.netflix.com/search?q={q}
-
+ Copiar URL
+ Copiar URL de búsqueda al portapapeles
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
index f5988733e..c6b1b145c 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
@@ -29,7 +29,8 @@
Ainsi, la formule générique pour une recherche Netflix est https://www.netflix.com/search?q={q}
-
+ Copier l'URL
+ Copier l'URL de la recherche dans le presse-papiers
Titre
@@ -45,7 +46,7 @@
Ajout
Astuce : Vous n'avez pas besoin de placer des images personnalisées dans ce dossier, si la version de Flow est mise à jour, elles seront perdues. Flow copiera automatiquement toutes les images en dehors de ce dossier dans l'emplacement de l'image personnalisée de la Recherche Web.
- Recherches Web
+ Recherches web
Permet d'effectuer des recherches web
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
new file mode 100644
index 000000000..820bb141b
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
@@ -0,0 +1,52 @@
+
+
+
+ Search Source Setting
+ Open search in:
+ New Window
+ New Tab
+ Set browser from path:
+ Choose
+ מחק
+ ערוך
+ הוסף
+ Enabled
+ Enabled
+ Disabled
+ Confirm
+ Action Keyword
+ URL
+ Search
+ Use Search Query Autocomplete:
+ Autocomplete Data from:
+ Please select a web search
+ Are you sure you want to delete {0}?
+ If you want to add a search for a particular website to Flow, first enter a dummy text string in the search bar of that website, and launch the search. Now copy the contents of the browser's address bar, and paste it in the URL field below. Replace your test string with {q}. For example, if you search for casino on Netflix, its address bar reads
+ https://www.netflix.com/search?q=Casino
+
+ Now copy this entire string and paste it in the URL field below.
+ Then replace casino with {q}.
+ Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
+
+
+ Copy URL
+ Copy search URL to clipboard
+
+
+ Title
+ Status
+ Select Icon
+ Icon
+ ביטול
+ Invalid web search
+ Please enter a title
+ Please enter an action keyword
+ Please enter a URL
+ Action keyword already exists, please enter a different one
+ הצליח
+ Hint: You do not need to place custom images in this directory, if Flow's version is updated they will be lost. Flow will automatically copy any images outside of this directory across to WebSearch's custom image location.
+
+ Web Searches
+ Allows to perform web searches
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
index dc9bd7a2e..26c1e8459 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
@@ -29,7 +29,8 @@
Così la formula generica per una ricerca su Netflix è https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Titolo
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
index b5d4df430..85ce0e282 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
タイトル
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
index 1f43e20c2..5ab5fffa3 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
이름
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
index b84daeb87..4bba382a9 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
@@ -29,7 +29,8 @@
dvs. den generiske formelen for et søk på Netflix er https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tittel
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
index fb6fd4353..a48d99487 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ URL kopiëren
+ Zoek-URL kopiëren naar klembord
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
index 1c426ee08..4f702d4a7 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
@@ -29,7 +29,8 @@
W ten sposób ogólna formuła wyszukiwania na Netflix to https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tytuł
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
index b2dedeb60..d4135c795 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
index 56d65e849..16969dac7 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
@@ -29,7 +29,8 @@
Assim, a fórmula genérica de uma pesquisa na Netflix é https://www.netflix.com/search?q={q}
-
+ Copiar URL
+ Copiar URL para a área de transferência
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
index a2ec9405a..ffe37b3ce 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
@@ -1,4 +1,4 @@
-
+
Search Source Setting
@@ -28,7 +28,8 @@
Then replace casino with {q}.
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Скопировать URL-адрес
+ Скопировать URL поиска в буфер обмена
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
index e23d12a16..44b765c58 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
@@ -29,7 +29,8 @@
Všeobecný vzorec pre vyhľadávanie na Netflix je teda https://www.netflix.com/search?q={q}
-
+ Kopírovať URL
+ Kopírovať URL vyhľadávanie do schránky
Názov
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
index 54ee24376..5f1803655 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
index 05f3de095..1506b753b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Başlık
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
index 87419023b..beb085d28 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
@@ -29,7 +29,8 @@
Таким чином, загальна формула для пошуку на Netflix має вигляд https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Назва
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
index a6de788b5..e3105283f 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tiêu đề
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
index cd05cf7b8..d3df223cc 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
@@ -29,7 +29,8 @@
那么 Netflix 搜索的表达式就是 https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
标题
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
index d50d65867..eb58a4ec0 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
標題
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
index a716ef4c6..dac5f82bc 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
@@ -126,7 +126,7 @@
File name, Should not translated
- Barrierefreiheitsoptionen
+ Optionen für Barrierefreiheit
Area Control Panel (legacy settings)
@@ -296,7 +296,7 @@
Programme
- SurfaceHub
+ Oberflächenhub
System
@@ -424,11 +424,11 @@
Mean the "Caps Lock" key
- Mobilfunknetz und SIM-Karte
+ Mobilfunk und SIM
Area NetworkAndInternet
- Wählen Sie aus, welche Ordner im Startmenü angezeigt werden
+ Wählen Sie, welche Ordner im Start erscheinen
Area Personalization
@@ -547,7 +547,7 @@
Area Control Panel (legacy settings)
- deuteranopia
+ Farbenfehlsichtigkeit
Medical: Mean you don't can see red colors
@@ -654,7 +654,7 @@
Area Privacy
- FindFast
+ Schnell finden
Area Control Panel (legacy settings)
@@ -697,7 +697,7 @@
Area Control Panel (legacy settings)
- Game DVR
+ DVR
Area Gaming
@@ -865,7 +865,7 @@
Area Apps
- Messaging
+ Nachrichten
Area Privacy
@@ -876,7 +876,7 @@
Area Privacy
- Microsoft Mail Post Office
+ Microsoft Mail Post
Area Control Panel (legacy settings)
@@ -1251,7 +1251,7 @@
Area System
- protanopia
+ Protanopie
Medical: Mean you don't can see green colors
@@ -1332,7 +1332,7 @@
Area Control Panel (legacy settings)
- schedtasks
+ sedtasks
File name, Should not translated
@@ -1412,7 +1412,7 @@
Area System
- Speech
+ Sprache
Area EaseOfAccess
@@ -1544,7 +1544,7 @@
Transparenz
- tritanopia
+ Farbenblindheit (Blau)
Medical: Mean you don't can see yellow and blue colors
@@ -1552,7 +1552,7 @@
Area UpdateAndSecurity
- TruePlay
+ TruePlaying
Area Gaming
@@ -2064,7 +2064,7 @@
Microsoft ChangJie-Einstellungen
- Replace sounds with visual cues
+ Sounds durch visuelle Hinweise ersetzen
Temporäre Internet-Dateieinstellungen ändern
@@ -2079,7 +2079,7 @@
Change the mouse pointer display or speed
- Back up your recovery key
+ Ihren Wiederherstellungsschlüssel sichern
Save backup copies of your files with File History
@@ -2133,7 +2133,7 @@
Change power-saving settings
- Optimise for blindness
+ Optimieren für Blindheit
@@ -2155,7 +2155,7 @@
Ihre Offline-Dateien verschlüsseln
- Train the computer to recognise your voice
+ Trainieren Sie den Computer, Ihre Stimme zu erkennen
Erweiterte Druckereinrichtung
@@ -2461,10 +2461,10 @@
Set your default programs
- Set up a broadband connection
+ Eine Breitbandverbindung einrichten
- Calibrate the screen for pen or touch input
+ Kalibrieren des Screens für Stift- oder Toucheingabe
Benutzerzertifikate verwalten
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
new file mode 100644
index 000000000..2b6d5aa63
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
@@ -0,0 +1,2514 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ אודות
+ Area System
+
+
+ access.cpl
+ File name, Should not translated
+
+
+ Accessibility Options
+ Area Control Panel (legacy settings)
+
+
+ Accessory apps
+ Area Privacy
+
+
+ Access work or school
+ Area UserAccounts
+
+
+ Account info
+ Area Privacy
+
+
+ Accounts
+ Area SurfaceHub
+
+
+ Action Center
+ Area Control Panel (legacy settings)
+
+
+ Activation
+ Area UpdateAndSecurity
+
+
+ Activity history
+ Area Privacy
+
+
+ Add Hardware
+ Area Control Panel (legacy settings)
+
+
+ Add/Remove Programs
+ Area Control Panel (legacy settings)
+
+
+ Add your phone
+ Area Phone
+
+
+ Administrative Tools
+ Area System
+
+
+ Advanced display settings
+ Area System, only available on devices that support advanced display options
+
+
+ Advanced graphics
+
+
+ Advertising ID
+ Area Privacy, Deprecated in Windows 10, version 1809 and later
+
+
+ Airplane mode
+ Area NetworkAndInternet
+
+
+ Alt+Tab
+ Means the key combination "Tabulator+Alt" on the keyboard
+
+
+ Alternative names
+
+
+ Animations
+
+
+ App color
+
+
+ App diagnostics
+ Area Privacy
+
+
+ App features
+ Area Apps
+
+
+ App
+ Short/modern name for application
+
+
+ Apps and Features
+ Area Apps
+
+
+ System settings
+ Type of the setting is a "Modern Windows settings". We use the same term as used in start menu search at the moment.
+
+
+ Apps for websites
+ Area Apps
+
+
+ App volume and device preferences
+ Area System, Added in Windows 10, version 1903
+
+
+ appwiz.cpl
+ File name, Should not translated
+
+
+ Area
+ Mean the settings area or settings category
+
+
+ Accounts
+
+
+ Administrative Tools
+ Area Control Panel (legacy settings)
+
+
+ Appearance and Personalization
+
+
+ Apps
+
+
+ Clock and Region
+
+
+ Control Panel
+
+
+ Cortana
+
+
+ Devices
+
+
+ Ease of access
+
+
+ Extras
+
+
+ Gaming
+
+
+ Hardware and Sound
+
+
+ Home page
+
+
+ Mixed reality
+
+
+ Network and Internet
+
+
+ Personalization
+
+
+ Phone
+
+
+ Privacy
+
+
+ Programs
+
+
+ SurfaceHub
+
+
+ System
+
+
+ System and Security
+
+
+ Time and language
+
+
+ Update and security
+
+
+ User accounts
+
+
+ Assigned access
+
+
+ Audio
+ Area EaseOfAccess
+
+
+ Audio alerts
+
+
+ Audio and speech
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ Automatic file downloads
+ Area Privacy
+
+
+ AutoPlay
+ Area Device
+
+
+ Background
+ Area Personalization
+
+
+ Background Apps
+ Area Privacy
+
+
+ Backup
+ Area UpdateAndSecurity
+
+
+ Backup and Restore
+ Area Control Panel (legacy settings)
+
+
+ Battery Saver
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Battery Saver settings
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Battery saver usage details
+
+
+ Battery use
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Biometric Devices
+ Area Control Panel (legacy settings)
+
+
+ BitLocker Drive Encryption
+ Area Control Panel (legacy settings)
+
+
+ Blue light
+
+
+ Bluetooth
+ Area Device
+
+
+ Bluetooth devices
+ Area Control Panel (legacy settings)
+
+
+ Blue-yellow
+
+
+ Bopomofo IME
+ Area TimeAndLanguage
+
+
+ bpmf
+ Should not translated
+
+
+ Broadcasting
+ Area Gaming
+
+
+ Calendar
+ Area Privacy
+
+
+ Call history
+ Area Privacy
+
+
+ calling
+
+
+ Camera
+ Area Privacy
+
+
+ Cangjie IME
+ Area TimeAndLanguage
+
+
+ Caps Lock
+ Mean the "Caps Lock" key
+
+
+ Cellular and SIM
+ Area NetworkAndInternet
+
+
+ Choose which folders appear on Start
+ Area Personalization
+
+
+ Client service for NetWare
+ Area Control Panel (legacy settings)
+
+
+ Clipboard
+ Area System
+
+
+ Closed captions
+ Area EaseOfAccess
+
+
+ Color filters
+ Area EaseOfAccess
+
+
+ Color management
+ Area Control Panel (legacy settings)
+
+
+ Colors
+ Area Personalization
+
+
+ Command
+ The command to direct start a setting
+
+
+ Connected Devices
+ Area Device
+
+
+ Contacts
+ Area Privacy
+
+
+ Control Panel
+ Type of the setting is a "(legacy) Control Panel setting"
+
+
+ Copy command
+
+
+ Core Isolation
+ Means the protection of the system core
+
+
+ Cortana
+ Area Cortana
+
+
+ Cortana across my devices
+ Area Cortana
+
+
+ Cortana - Language
+ Area Cortana
+
+
+ Credential manager
+ Area Control Panel (legacy settings)
+
+
+ Crossdevice
+
+
+ Custom devices
+
+
+ Dark color
+
+
+ Dark mode
+
+
+ Data usage
+ Area NetworkAndInternet
+
+
+ Date and time
+ Area TimeAndLanguage
+
+
+ Default apps
+ Area Apps
+
+
+ Default camera
+ Area Device
+
+
+ Default location
+ Area Control Panel (legacy settings)
+
+
+ Default programs
+ Area Control Panel (legacy settings)
+
+
+ Default Save Locations
+ Area System
+
+
+ Delivery Optimization
+ Area UpdateAndSecurity
+
+
+ desk.cpl
+ File name, Should not translated
+
+
+ Desktop themes
+ Area Control Panel (legacy settings)
+
+
+ deuteranopia
+ Medical: Mean you don't can see red colors
+
+
+ Device manager
+ Area Control Panel (legacy settings)
+
+
+ Devices and printers
+ Area Control Panel (legacy settings)
+
+
+ DHCP
+ Should not translated
+
+
+ Dial-up
+ Area NetworkAndInternet
+
+
+ Direct access
+ Area NetworkAndInternet, only available if DirectAccess is enabled
+
+
+ Direct open your phone
+ Area EaseOfAccess
+
+
+ Display
+ Area EaseOfAccess
+
+
+ Display properties
+ Area Control Panel (legacy settings)
+
+
+ DNS
+ Should not translated
+
+
+ Documents
+ Area Privacy
+
+
+ Duplicating my display
+ Area System
+
+
+ During these hours
+ Area System
+
+
+ Ease of access center
+ Area Control Panel (legacy settings)
+
+
+ Edition
+ Means the "Windows Edition"
+
+
+ Email
+ Area Privacy
+
+
+ Email and app accounts
+ Area UserAccounts
+
+
+ Encryption
+ Area System
+
+
+ Environment
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ Ethernet
+ Area NetworkAndInternet
+
+
+ Exploit Protection
+
+
+ Extras
+ Area Extra, , only used for setting of 3rd-Party tools
+
+
+ Eye control
+ Area EaseOfAccess
+
+
+ Eye tracker
+ Area Privacy, requires eyetracker hardware
+
+
+ Family and other people
+ Area UserAccounts
+
+
+ Feedback and diagnostics
+ Area Privacy
+
+
+ File system
+ Area Privacy
+
+
+ FindFast
+ Area Control Panel (legacy settings)
+
+
+ findfast.cpl
+ File name, Should not translated
+
+
+ Find My Device
+ Area UpdateAndSecurity
+
+
+ Firewall
+
+
+ Focus assist - Quiet hours
+ Area System
+
+
+ Focus assist - Quiet moments
+ Area System
+
+
+ Folder options
+ Area Control Panel (legacy settings)
+
+
+ Fonts
+ Area EaseOfAccess
+
+
+ For developers
+ Area UpdateAndSecurity
+
+
+ Game bar
+ Area Gaming
+
+
+ Game controllers
+ Area Control Panel (legacy settings)
+
+
+ Game DVR
+ Area Gaming
+
+
+ מצב משחק
+ Area Gaming
+
+
+ Gateway
+ Should not translated
+
+
+ כללי
+ Area Privacy
+
+
+ Get programs
+ Area Control Panel (legacy settings)
+
+
+ Getting started
+ Area Control Panel (legacy settings)
+
+
+ Glance
+ Area Personalization, Deprecated in Windows 10, version 1809 and later
+
+
+ Graphics settings
+ Area System
+
+
+ Grayscale
+
+
+ Green week
+ Mean you don't can see green colors
+
+
+ Headset display
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ High contrast
+ Area EaseOfAccess
+
+
+ Holographic audio
+
+
+ Holographic Environment
+
+
+ Holographic Headset
+
+
+ Holographic Management
+
+
+ Home group
+ Area Control Panel (legacy settings)
+
+
+ ID
+ MEans The "Windows Identifier"
+
+
+ Image
+
+
+ Indexing options
+ Area Control Panel (legacy settings)
+
+
+ inetcpl.cpl
+ File name, Should not translated
+
+
+ Infrared
+ Area Control Panel (legacy settings)
+
+
+ Inking and typing
+ Area Privacy
+
+
+ Internet options
+ Area Control Panel (legacy settings)
+
+
+ intl.cpl
+ File name, Should not translated
+
+
+ Inverted colors
+
+
+ IP
+ Should not translated
+
+
+ Isolated Browsing
+
+
+ Japan IME settings
+ Area TimeAndLanguage, available if the Microsoft Japan input method editor is installed
+
+
+ joy.cpl
+ File name, Should not translated
+
+
+ Joystick properties
+ Area Control Panel (legacy settings)
+
+
+ jpnime
+ Should not translated
+
+
+ Keyboard
+ Area EaseOfAccess
+
+
+ Keypad
+
+
+ Keys
+
+
+ שפה
+ Area TimeAndLanguage
+
+
+ Light color
+
+
+ Light mode
+
+
+ Location
+ Area Privacy
+
+
+ Lock screen
+ Area Personalization
+
+
+ Magnifier
+ Area EaseOfAccess
+
+
+ Mail - Microsoft Exchange or Windows Messaging
+ Area Control Panel (legacy settings)
+
+
+ main.cpl
+ File name, Should not translated
+
+
+ Manage known networks
+ Area NetworkAndInternet
+
+
+ Manage optional features
+ Area Apps
+
+
+ Messaging
+ Area Privacy
+
+
+ Metered connection
+
+
+ Microphone
+ Area Privacy
+
+
+ Microsoft Mail Post Office
+ Area Control Panel (legacy settings)
+
+
+ mlcfg32.cpl
+ File name, Should not translated
+
+
+ mmsys.cpl
+ File name, Should not translated
+
+
+ Mobile devices
+
+
+ Mobile hotspot
+ Area NetworkAndInternet
+
+
+ modem.cpl
+ File name, Should not translated
+
+
+ Mono
+
+
+ More details
+ Area Cortana
+
+
+ Motion
+ Area Privacy
+
+
+ Mouse
+ Area EaseOfAccess
+
+
+ Mouse and touchpad
+ Area Device
+
+
+ Mouse, Fonts, Keyboard, and Printers properties
+ Area Control Panel (legacy settings)
+
+
+ Mouse pointer
+ Area EaseOfAccess
+
+
+ Multimedia properties
+ Area Control Panel (legacy settings)
+
+
+ Multitasking
+ Area System
+
+
+ Narrator
+ Area EaseOfAccess
+
+
+ Navigation bar
+ Area Personalization
+
+
+ netcpl.cpl
+ File name, Should not translated
+
+
+ netsetup.cpl
+ File name, Should not translated
+
+
+ Network
+ Area NetworkAndInternet
+
+
+ Network and sharing center
+ Area Control Panel (legacy settings)
+
+
+ Network connection
+ Area Control Panel (legacy settings)
+
+
+ Network properties
+ Area Control Panel (legacy settings)
+
+
+ Network Setup Wizard
+ Area Control Panel (legacy settings)
+
+
+ Network status
+ Area NetworkAndInternet
+
+
+ NFC
+ Area NetworkAndInternet
+
+
+ NFC Transactions
+ "NFC should not translated"
+
+
+ Night light
+
+
+ Night light settings
+ Area System
+
+
+ Note
+
+
+ Only available when you have connected a mobile device to your device.
+
+
+ Only available on devices that support advanced graphics options.
+
+
+ Only available on devices that have a battery, such as a tablet.
+
+
+ Deprecated in Windows 10, version 1809 (build 17763) and later.
+
+
+ Only available if Dial is paired.
+
+
+ Only available if DirectAccess is enabled.
+
+
+ Only available on devices that support advanced display options.
+
+
+ Only present if user is enrolled in WIP.
+
+
+ Requires eyetracker hardware.
+
+
+ Available if the Microsoft Japan input method editor is installed.
+
+
+ Available if the Microsoft Pinyin input method editor is installed.
+
+
+ Available if the Microsoft Wubi input method editor is installed.
+
+
+ Only available if the Mixed Reality Portal app is installed.
+
+
+ Only available on mobile and if the enterprise has deployed a provisioning package.
+
+
+ Added in Windows 10, version 1903 (build 18362).
+
+
+ Added in Windows 10, version 2004 (build 19041).
+
+
+ Only available if "settings apps" are installed, for example, by a 3rd party.
+
+
+ Only available if touchpad hardware is present.
+
+
+ Only available if the device has a Wi-Fi adapter.
+
+
+ Device must be Windows Anywhere-capable.
+
+
+ Only available if enterprise has deployed a provisioning package.
+
+
+ Notifications
+ Area Privacy
+
+
+ Notifications and actions
+ Area System
+
+
+ Num Lock
+ Mean the "Num Lock" key
+
+
+ nwc.cpl
+ File name, Should not translated
+
+
+ odbccp32.cpl
+ File name, Should not translated
+
+
+ ODBC Data Source Administrator (32-bit)
+ Area Control Panel (legacy settings)
+
+
+ ODBC Data Source Administrator (64-bit)
+ Area Control Panel (legacy settings)
+
+
+ Offline files
+ Area Control Panel (legacy settings)
+
+
+ Offline Maps
+ Area Apps
+
+
+ Offline Maps - Download maps
+ Area Apps
+
+
+ On-Screen
+
+
+ OS
+ Means the "Operating System"
+
+
+ Other devices
+ Area Privacy
+
+
+ Other options
+ Area EaseOfAccess
+
+
+ Other users
+
+
+ Parental controls
+ Area Control Panel (legacy settings)
+
+
+ Password
+
+
+ password.cpl
+ File name, Should not translated
+
+
+ Password properties
+ Area Control Panel (legacy settings)
+
+
+ Pen and input devices
+ Area Control Panel (legacy settings)
+
+
+ Pen and touch
+ Area Control Panel (legacy settings)
+
+
+ Pen and Windows Ink
+ Area Device
+
+
+ People Near Me
+ Area Control Panel (legacy settings)
+
+
+ Performance information and tools
+ Area Control Panel (legacy settings)
+
+
+ Permissions and history
+ Area Cortana
+
+
+ Personalization (category)
+ Area Personalization
+
+
+ Phone
+ Area Phone
+
+
+ Phone and modem
+ Area Control Panel (legacy settings)
+
+
+ Phone and modem - Options
+ Area Control Panel (legacy settings)
+
+
+ Phone calls
+ Area Privacy
+
+
+ Phone - Default apps
+ Area System
+
+
+ Picture
+
+
+ Pictures
+ Area Privacy
+
+
+ Pinyin IME settings
+ Area TimeAndLanguage, available if the Microsoft Pinyin input method editor is installed
+
+
+ Pinyin IME settings - domain lexicon
+ Area TimeAndLanguage
+
+
+ Pinyin IME settings - Key configuration
+ Area TimeAndLanguage
+
+
+ Pinyin IME settings - UDP
+ Area TimeAndLanguage
+
+
+ Playing a game full screen
+ Area Gaming
+
+
+ Plugin to search for Windows settings
+
+
+ Windows Settings
+
+
+ Power and sleep
+ Area System
+
+
+ powercfg.cpl
+ File name, Should not translated
+
+
+ Power options
+ Area Control Panel (legacy settings)
+
+
+ Presentation
+
+
+ Printers
+ Area Control Panel (legacy settings)
+
+
+ Printers and scanners
+ Area Device
+
+
+ Print screen
+ Mean the "Print screen" key
+
+
+ Problem reports and solutions
+ Area Control Panel (legacy settings)
+
+
+ Processor
+
+
+ Programs and features
+ Area Control Panel (legacy settings)
+
+
+ Projecting to this PC
+ Area System
+
+
+ protanopia
+ Medical: Mean you don't can see green colors
+
+
+ Provisioning
+ Area UserAccounts, only available if enterprise has deployed a provisioning package
+
+
+ Proximity
+ Area NetworkAndInternet
+
+
+ Proxy
+ Area NetworkAndInternet
+
+
+ Quickime
+ Area TimeAndLanguage
+
+
+ Quiet moments game
+
+
+ Radios
+ Area Privacy
+
+
+ RAM
+ Means the Read-Access-Memory (typical the used to inform about the size)
+
+
+ Recognition
+
+
+ Recovery
+ Area UpdateAndSecurity
+
+
+ Red eye
+ Mean red eye effect by over-the-night flights
+
+
+ Red-green
+ Mean the weakness you can't differ between red and green colors
+
+
+ Red week
+ Mean you don't can see red colors
+
+
+ Region
+ Area TimeAndLanguage
+
+
+ Regional language
+ Area TimeAndLanguage
+
+
+ Regional settings properties
+ Area Control Panel (legacy settings)
+
+
+ Region and language
+ Area Control Panel (legacy settings)
+
+
+ Region formatting
+
+
+ RemoteApp and desktop connections
+ Area Control Panel (legacy settings)
+
+
+ Remote Desktop
+ Area System
+
+
+ Scanners and cameras
+ Area Control Panel (legacy settings)
+
+
+ schedtasks
+ File name, Should not translated
+
+
+ Scheduled
+
+
+ Scheduled tasks
+ Area Control Panel (legacy settings)
+
+
+ Screen rotation
+ Area System
+
+
+ Scroll bars
+
+
+ Scroll Lock
+ Mean the "Scroll Lock" key
+
+
+ SDNS
+ Should not translated
+
+
+ Searching Windows
+ Area Cortana
+
+
+ SecureDNS
+ Should not translated
+
+
+ Security Center
+ Area Control Panel (legacy settings)
+
+
+ Security Processor
+
+
+ Session cleanup
+ Area SurfaceHub
+
+
+ Settings home page
+ Area Home, Overview-page for all areas of settings
+
+
+ Set up a kiosk
+ Area UserAccounts
+
+
+ Shared experiences
+ Area System
+
+
+ Shortcuts
+
+
+ wifi
+ dont translate this, is a short term to find entries
+
+
+ Sign-in options
+ Area UserAccounts
+
+
+ Sign-in options - Dynamic lock
+ Area UserAccounts
+
+
+ Size
+ Size for text and symbols
+
+
+ Sound
+ Area System
+
+
+ Speech
+ Area EaseOfAccess
+
+
+ Speech recognition
+ Area Control Panel (legacy settings)
+
+
+ Speech typing
+
+
+ Start
+ Area Personalization
+
+
+ Start places
+
+
+ Startup apps
+ Area Apps
+
+
+ sticpl.cpl
+ File name, Should not translated
+
+
+ Storage
+ Area System
+
+
+ Storage policies
+ Area System
+
+
+ Storage Sense
+ Area System
+
+
+ in
+ Example: Area "System" in System settings
+
+
+ Sync center
+ Area Control Panel (legacy settings)
+
+
+ Sync your settings
+ Area UserAccounts
+
+
+ sysdm.cpl
+ File name, Should not translated
+
+
+ System
+ Area Control Panel (legacy settings)
+
+
+ System properties and Add New Hardware wizard
+ Area Control Panel (legacy settings)
+
+
+ Tab
+ Means the key "Tabulator" on the keyboard
+
+
+ Tablet mode
+ Area System
+
+
+ Tablet PC settings
+ Area Control Panel (legacy settings)
+
+
+ Talk
+
+
+ Talk to Cortana
+ Area Cortana
+
+
+ Taskbar
+ Area Personalization
+
+
+ Taskbar color
+
+
+ Tasks
+ Area Privacy
+
+
+ Team Conferencing
+ Area SurfaceHub
+
+
+ Team device management
+ Area SurfaceHub
+
+
+ Text to speech
+ Area Control Panel (legacy settings)
+
+
+ Themes
+ Area Personalization
+
+
+ themes.cpl
+ File name, Should not translated
+
+
+ timedate.cpl
+ File name, Should not translated
+
+
+ Timeline
+
+
+ Touch
+
+
+ Touch feedback
+
+
+ Touchpad
+ Area Device
+
+
+ Transparency
+
+
+ tritanopia
+ Medical: Mean you don't can see yellow and blue colors
+
+
+ Troubleshoot
+ Area UpdateAndSecurity
+
+
+ TruePlay
+ Area Gaming
+
+
+ Typing
+ Area Device
+
+
+ Uninstall
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ USB
+ Area Device
+
+
+ User accounts
+ Area Control Panel (legacy settings)
+
+
+ Version
+ Means The "Windows Version"
+
+
+ Video playback
+ Area Apps
+
+
+ Videos
+ Area Privacy
+
+
+ Virtual Desktops
+
+
+ Virus
+ Means the virus in computers and software
+
+
+ Voice activation
+ Area Privacy
+
+
+ Volume
+
+
+ VPN
+ Area NetworkAndInternet
+
+
+ Wallpaper
+
+
+ Warmer color
+
+
+ Welcome center
+ Area Control Panel (legacy settings)
+
+
+ Welcome screen
+ Area SurfaceHub
+
+
+ wgpocpl.cpl
+ File name, Should not translated
+
+
+ Wheel
+ Area Device
+
+
+ Wi-Fi
+ Area NetworkAndInternet, only available if Wi-Fi calling is enabled
+
+
+ Wi-Fi Calling
+ Area NetworkAndInternet, only available if Wi-Fi calling is enabled
+
+
+ Wi-Fi settings
+ "Wi-Fi" should not translated
+
+
+ Window border
+
+
+ Windows Anytime Upgrade
+ Area Control Panel (legacy settings)
+
+
+ Windows Anywhere
+ Area UserAccounts, device must be Windows Anywhere-capable
+
+
+ Windows CardSpace
+ Area Control Panel (legacy settings)
+
+
+ Windows Defender
+ Area Control Panel (legacy settings)
+
+
+ Windows Firewall
+ Area Control Panel (legacy settings)
+
+
+ Windows Hello setup - Face
+ Area UserAccounts
+
+
+ Windows Hello setup - Fingerprint
+ Area UserAccounts
+
+
+ Windows Insider Program
+ Area UpdateAndSecurity
+
+
+ Windows Mobility Center
+ Area Control Panel (legacy settings)
+
+
+ Windows search
+ Area Cortana
+
+
+ Windows Security
+ Area UpdateAndSecurity
+
+
+ Windows Update
+ Area UpdateAndSecurity
+
+
+ Windows Update - Advanced options
+ Area UpdateAndSecurity
+
+
+ Windows Update - Check for updates
+ Area UpdateAndSecurity
+
+
+ Windows Update - Restart options
+ Area UpdateAndSecurity
+
+
+ Windows Update - View optional updates
+ Area UpdateAndSecurity
+
+
+ Windows Update - View update history
+ Area UpdateAndSecurity
+
+
+ Wireless
+
+
+ Workplace
+
+
+ Workplace provisioning
+ Area UserAccounts
+
+
+ Wubi IME settings
+ Area TimeAndLanguage, available if the Microsoft Wubi input method editor is installed
+
+
+ Wubi IME settings - UDP
+ Area TimeAndLanguage
+
+
+ Xbox Networking
+ Area Gaming
+
+
+ Your info
+ Area UserAccounts
+
+
+ Zoom
+ Mean zooming of things via a magnifier
+
+
+ Change device installation settings
+
+
+ Turn off background images
+
+
+ Navigation properties
+
+
+ Media streaming options
+
+
+ Make a file type always open in a specific program
+
+
+ Change the Narrator’s voice
+
+
+ Find and fix keyboard problems
+
+
+ Use screen reader
+
+
+ Show which workgroup this computer is on
+
+
+ Change mouse wheel settings
+
+
+ Manage computer certificates
+
+
+ Find and fix problems
+
+
+ Change settings for content received using Tap and send
+
+
+ Change default settings for media or devices
+
+
+ Print the speech reference card
+
+
+ Calibrate display colour
+
+
+ Manage file encryption certificates
+
+
+ View recent messages about your computer
+
+
+ Give other users access to this computer
+
+
+ Show hidden files and folders
+
+
+ Change Windows To Go start-up options
+
+
+ See which processes start up automatically when you start Windows
+
+
+ Tell if an RSS feed is available on a website
+
+
+ Add clocks for different time zones
+
+
+ Add a Bluetooth device
+
+
+ Customise the mouse buttons
+
+
+ Set tablet buttons to perform certain tasks
+
+
+ View installed fonts
+
+
+ Change the way currency is displayed
+
+
+ Edit group policy
+
+
+ Manage browser add-ons
+
+
+ Check processor speed
+
+
+ Check firewall status
+
+
+ Send or receive a file
+
+
+ Add or remove user accounts
+
+
+ Edit the system environment variables
+
+
+ Manage BitLocker
+
+
+ Auto-hide the taskbar
+
+
+ Change sound card settings
+
+
+ Make changes to accounts
+
+
+ Edit local users and groups
+
+
+ View network computers and devices
+
+
+ Install a program from the network
+
+
+ View scanners and cameras
+
+
+ Microsoft IME Register Word (Japanese)
+
+
+ Restore your files with File History
+
+
+ Turn On-Screen keyboard on or off
+
+
+ Block or allow third-party cookies
+
+
+ Find and fix audio recording problems
+
+
+ Create a recovery drive
+
+
+ Microsoft New Phonetic Settings
+
+
+ Generate a system health report
+
+
+ Fix problems with your computer
+
+
+ Back up and Restore (Windows 7)
+
+
+ Preview, delete, show or hide fonts
+
+
+ Microsoft Quick Settings
+
+
+ View reliability history
+
+
+ Access RemoteApp and desktops
+
+
+ Set up ODBC data sources
+
+
+ Reset Security Policies
+
+
+ Block or allow pop-ups
+
+
+ Turn autocomplete in Internet Explorer on or off
+
+
+ Microsoft Pinyin SimpleFast Options
+
+
+ Change what closing the lid does
+
+
+ Turn off unnecessary animations
+
+
+ Create a restore point
+
+
+ Turn off automatic window arrangement
+
+
+ Troubleshooting History
+
+
+ Diagnose your computer's memory problems
+
+
+ View recommended actions to keep Windows running smoothly
+
+
+ Change cursor blink rate
+
+
+ Add or remove programs
+
+
+ Create a password reset disk
+
+
+ Configure advanced user profile properties
+
+
+ Start or stop using AutoPlay for all media and devices
+
+
+ Change Automatic Maintenance settings
+
+
+ Specify single- or double-click to open
+
+
+ Select users who can use remote desktop
+
+
+ Show which programs are installed on your computer
+
+
+ Allow remote access to your computer
+
+
+ View advanced system settings
+
+
+ How to install a program
+
+
+ Change how your keyboard works
+
+
+ Automatically adjust for daylight saving time
+
+
+ Change the order of Windows SideShow gadgets
+
+
+ Check keyboard status
+
+
+ Control the computer without the mouse or keyboard
+
+
+ Change or remove a program
+
+
+ Change multi-touch gesture settings
+
+
+ Set up ODBC data sources (64-bit)
+
+
+ Configure proxy server
+
+
+ Change your homepage
+
+
+ Group similar windows on the taskbar
+
+
+ Change Windows SideShow settings
+
+
+ Use audio description for video
+
+
+ Change workgroup name
+
+
+ Find and fix printing problems
+
+
+ Change when the computer sleeps
+
+
+ Set up a virtual private network (VPN) connection
+
+
+ Accommodate learning abilities
+
+
+ Set up a dial-up connection
+
+
+ Set up a connection or network
+
+
+ How to change your Windows password
+
+
+ Make it easier to see the mouse pointer
+
+
+ Set up iSCSI initiator
+
+
+ Accommodate low vision
+
+
+ Manage offline files
+
+
+ Review your computer's status and resolve issues
+
+
+ Microsoft ChangJie Settings
+
+
+ Replace sounds with visual cues
+
+
+ Change temporary Internet file settings
+
+
+ Connect to the Internet
+
+
+ Find and fix audio playback problems
+
+
+ Change the mouse pointer display or speed
+
+
+ Back up your recovery key
+
+
+ Save backup copies of your files with File History
+
+
+ View current accessibility settings
+
+
+ Change tablet pen settings
+
+
+ Change how your mouse works
+
+
+ Show how much RAM is on this computer
+
+
+ Edit power plan
+
+
+ Adjust system volume
+
+
+ Defragment and optimise your drives
+
+
+ Set up ODBC data sources (32-bit)
+
+
+ Change Font Settings
+
+
+ Magnify portions of the screen using Magnifier
+
+
+ Change the file type associated with a file extension
+
+
+ View event logs
+
+
+ Manage Windows Credentials
+
+
+ Set up a microphone
+
+
+ Change how the mouse pointer looks
+
+
+ Change power-saving settings
+
+
+ Optimise for blindness
+
+
+
+
+
+
+ Turn Windows features on or off
+
+
+ Show which operating system your computer is running
+
+
+ View local services
+
+
+ Manage Work Folders
+
+
+ Encrypt your offline files
+
+
+ Train the computer to recognise your voice
+
+
+ Advanced printer setup
+
+
+ Change default printer
+
+
+ Edit environment variables for your account
+
+
+ Optimise visual display
+
+
+ Change mouse click settings
+
+
+ Change advanced colour management settings for displays, scanners and printers
+
+
+ Let Windows suggest Ease of Access settings
+
+
+ Clear disk space by deleting unnecessary files
+
+
+ View devices and printers
+
+
+ Private Character Editor
+
+
+ Record steps to reproduce a problem
+
+
+ Adjust the appearance and performance of Windows
+
+
+ Settings for Microsoft IME (Japanese)
+
+
+ Invite someone to connect to your PC and help you, or offer to help someone else
+
+
+ Run programs made for previous versions of Windows
+
+
+ Choose the order of how your screen rotates
+
+
+ Change how Windows searches
+
+
+ Set flicks to perform certain tasks
+
+
+ Change account type
+
+
+ Change screen saver
+
+
+ Change User Account Control settings
+
+
+ Turn on easy access keys
+
+
+ Identify and repair network problems
+
+
+ Find and fix networking and connection problems
+
+
+ Play CDs or other media automatically
+
+
+ View basic information about your computer
+
+
+ Choose how you open links
+
+
+ Allow Remote Assistance invitations to be sent from this computer
+
+
+ Task Manager
+
+
+ Turn flicks on or off
+
+
+ Add a language
+
+
+ View network status and tasks
+
+
+ Turn Magnifier on or off
+
+
+ See the name of this computer
+
+
+ View network connections
+
+
+ Perform recommended maintenance tasks automatically
+
+
+ Manage disk space used by your offline files
+
+
+ Turn High Contrast on or off
+
+
+ Change the way time is displayed
+
+
+ Change how web pages are displayed in tabs
+
+
+ Change the way dates and lists are displayed
+
+
+ Manage audio devices
+
+
+ Change security settings
+
+
+ Check security status
+
+
+ Delete cookies or temporary files
+
+
+ Specify which hand you write with
+
+
+ Change touch input settings
+
+
+ How to change the size of virtual memory
+
+
+ Hear text read aloud with Narrator
+
+
+ Set up USB game controllers
+
+
+ Show which domain your computer is on
+
+
+ View all problem reports
+
+
+ 16-Bit Application Support
+
+
+ Set up dialling rules
+
+
+ Enable or disable session cookies
+
+
+ Give administrative rights to a domain user
+
+
+ Choose when to turn off display
+
+
+ Move the pointer with the keypad using MouseKeys
+
+
+ Change Windows SideShow-compatible device settings
+
+
+ Adjust commonly used mobility settings
+
+
+ Change text-to-speech settings
+
+
+ Set the time and date
+
+
+ Change location settings
+
+
+ Change mouse settings
+
+
+ Manage Storage Spaces
+
+
+ Show or hide file extensions
+
+
+ Allow an app through Windows Firewall
+
+
+ Change system sounds
+
+
+ Adjust ClearType text
+
+
+ Turn screen saver on or off
+
+
+ Find and fix windows update problems
+
+
+ Change Bluetooth settings
+
+
+ Connect to a network
+
+
+ Change the search provider in Internet Explorer
+
+
+ Join a domain
+
+
+ Add a device
+
+
+ Find and fix problems with Windows Search
+
+
+ Choose a power plan
+
+
+ Change how the mouse pointer looks when it’s moving
+
+
+ Uninstall a program
+
+
+ Create and format hard disk partitions
+
+
+ Change date, time or number formats
+
+
+ Change PC wake-up settings
+
+
+ Manage network passwords
+
+
+ Change input methods
+
+
+ Manage advanced sharing settings
+
+
+ Change battery settings
+
+
+ Rename this computer
+
+
+ Lock or unlock the taskbar
+
+
+ Manage Web Credentials
+
+
+ Change the time zone
+
+
+ Start speech recognition
+
+
+ View installed updates
+
+
+ What's happened to the Quick Launch toolbar?
+
+
+ Change search options for files and folders
+
+
+ Adjust settings before giving a presentation
+
+
+ Scan a document or picture
+
+
+ Change the way measurements are displayed
+
+
+ Press key combinations one at a time
+
+
+ Restore data, files or computer from backup (Windows 7)
+
+
+ Set your default programs
+
+
+ Set up a broadband connection
+
+
+ Calibrate the screen for pen or touch input
+
+
+ Manage user certificates
+
+
+ Schedule tasks
+
+
+ Ignore repeated keystrokes using FilterKeys
+
+
+ Find and fix bluescreen problems
+
+
+ Hear a tone when keys are pressed
+
+
+ Delete browsing history
+
+
+ Change what the power buttons do
+
+
+ Create standard user account
+
+
+ Take speech tutorials
+
+
+ View system resource usage in Task Manager
+
+
+ Create an account
+
+
+ Get more features with a new edition of Windows
+
+
+ Control Panel
+
+
+ TaskLink
+
+
+ Unknown
+
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
index 418ea06c5..e7f8e1683 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
@@ -1905,7 +1905,7 @@
Microsoft Quick Settings
- View reliability history
+ Ver histórico de fiabilidade
Access RemoteApp and desktops
@@ -1923,7 +1923,7 @@
Ativar ou desativar conclusão automática no Internet Explorer
- Microsoft Pinyin SimpleFast Options
+ Opções SimpleFast do Microsoft Pinyin
Change what closing the lid does
@@ -1947,16 +1947,16 @@
Ver ações recomendadas para manter o sistema a funcionar nas melhores condições
- Change cursor blink rate
+ Alterar a frequência de piscar do cursor
Adicionar ou remover programas
- Create a password reset disk
+ Criar disco de redefinição da palavra-passe
- Configure advanced user profile properties
+ Configurar propriedades avançadas do perfil de utilizador
Start or stop using AutoPlay for all media and devices
@@ -1971,10 +1971,10 @@
Utilizadores que podem utilizar o ambiente de trabalho remoto
- Show which programs are installed on your computer
+ Mostre que programas estão instalados no seu computador
- Allow remote access to your computer
+ Permitir o acesso remoto ao seu computador
Ver definições avançadas do sistema
@@ -1986,10 +1986,10 @@
Alterar modo de funcionamento do teclado
- Automatically adjust for daylight saving time
+ Ajustar automaticamente para horário de verão
- Change the order of Windows SideShow gadgets
+ Alterar a ordem dos Windows SideShow gadgets
Analisar estado do teclado
@@ -2037,34 +2037,34 @@
Accommodate learning abilities
- Set up a dial-up connection
+ Configurar uma ligação telefónica
- Set up a connection or network
+ Configurar uma ligação ou rede
Como alterar a palavra-passe do Windows
- Make it easier to see the mouse pointer
+ Tornar mais fácil ver o ponteiro do rato
- Set up iSCSI initiator
+ Configurar o iniciador iSCSI
- Accommodate low vision
+ Ajustar para baixa visão
Gerir ficheiros offline
- Review your computer's status and resolve issues
+ Verificar o estado do computador e resolver problemas
- Microsoft ChangJie Settings
+ Configurações Microsoft ChangJie
- Replace sounds with visual cues
+ Substituir sons por pistas visuais
Change temporary Internet file settings
@@ -2079,10 +2079,10 @@
Alterar exibição e/ou velocidade do ponteiro do rato
- Back up your recovery key
+ Cópia de segurança da chave de recuperação
- Save backup copies of your files with File History
+ Guardar cópias de segurança dos ficheiros no Histórico de Ficheiros
View current accessibility settings
@@ -2155,7 +2155,7 @@
Encrypt your offline files
- Train the computer to recognise your voice
+ Treinar o computador para reconhecer a sua voz
Configuração avançada de impressora
@@ -2218,7 +2218,7 @@
Alterar proteção de ecrã
- Change User Account Control settings
+ Alterar Configurações de Controlo da Conta do Utilizador
Turn on easy access keys
@@ -2455,7 +2455,7 @@
Press key combinations one at a time
- Restore data, files or computer from backup (Windows 7)
+ Restaurar dados, ficheiros ou computador a partir de cópia de segurança (Windows 7)
Set your default programs
From f7edecea108ed2fe365682e97d95b73fa40668a1 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 10 Jan 2025 16:26:20 +1100
Subject: [PATCH 074/200] New Crowdin updates (#3149)
New translations
---
Flow.Launcher/Languages/de.xaml | 4 +-
Flow.Launcher/Languages/es.xaml | 4 +-
Flow.Launcher/Languages/he.xaml | 108 +++++++++---------
.../Languages/he.xaml | 28 ++---
.../Properties/Resources.de-DE.resx | 4 +-
5 files changed, 74 insertions(+), 74 deletions(-)
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 7f2e2bd8d..c7e775ae3 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -65,8 +65,8 @@
Letzte Abfrage beibehalten
Letzte Abfrage auswählen
Letzte Abfrage leeren
- Preserve Last Action Keyword
- Select Last Action Keyword
+ Letztes Aktions-Schlüsselwort beibehalten
+ Letztes Aktions-Schlüsselwort auswählen
Feste Fensterhöhe
Die Fensterhöhe ist durch Ziehen nicht anpassbar.
Maximal gezeigte Ergebnisse
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index bf22aea48..c7595f69b 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -65,8 +65,8 @@
Mantener la última consulta
Seleccionar la última consulta
Limpiar la última consulta
- Conservar palabra clave de última acción
- Seleccionar palabra clave de última acción
+ Conservar última palabra clave de acción
+ Seleccionar última palabra clave de acción
Altura de la ventana fija
La altura de la ventana no se puede ajustar arrastrando el ratón.
Número máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index eeb33da17..f3c9bb307 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -9,7 +9,7 @@
אנא בחר את קובץ ההפעלה {0}
לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).
נכשל בהפעלת תוספים
- תוספים: {0} - נכשלים בטעינה ויהיו מושבתים, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
+ תוספים: {0} - נכשלו בטעינה ויושבתו, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
רישום מקש הקיצור "{0}" נכשל. ייתכן שמקש הקיצור נמצא בשימוש על ידי תוכנה אחרת. שנה למקש קיצור אחר, או צא מהתוכנה האחרת.
@@ -54,10 +54,10 @@
צג ראשי
צג מותאם אישית
Search Window Position on Monitor
- Center
- Center Top
- Left Top
- Right Top
+ מרכז
+ מרכז עליון
+ שמאל עליון
+ ימין עליון
Custom Position
שפה
Last Query Style
@@ -83,16 +83,16 @@
Please select pythonw.exe
Always Start Typing in English Mode
Temporarily change your input method to English mode when activating Flow.
- Auto Update
- Select
+ עדכון אוטומטי
+ בחר
Hide Flow Launcher on startup
Flow Launcher search window is hidden in the tray after starting up.
Hide tray icon
When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.
Query Search Precision
Changes minimum match score required for results.
- None
- Low
+ ללא
+ נמוך
Regular
Search with Pinyin
Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
@@ -120,26 +120,26 @@
Priority
Change Plugin Results Priority
Plugin Directory
- by
+ מאת
Init time:
Query time:
- Version
- Website
- Uninstall
+ גרסה
+ אתר
+ הסר התקנה
חנות תוספים
- New Release
+ שחרור חדש
Recently Updated
תוספים
- Installed
+ מותקן
רענן
התקן
- Uninstall
+ הסר התקנה
עדכון
Plugin already installed
- New Version
+ גרסה חדשה
This plugin has been updated within the last 7 days
New Update is Available
@@ -164,7 +164,7 @@
Query Box Font
Result Title Font
Result Subtitle Font
- Reset
+ אפס
Customize
Window Mode
Opacity
@@ -196,9 +196,9 @@
- Hotkey
- Hotkeys
- Open Flow Launcher
+ מקש קיצור
+ מקשי קיצור
+ פתח את Flow Launcher
Enter shortcut to show/hide Flow Launcher.
Toggle Preview
Enter shortcut to show/hide preview in search window.
@@ -206,24 +206,24 @@
List of currently registered hotkeys
Open Result Modifier Key
Select a modifier key to open selected result via keyboard.
- Show Hotkey
+ הצג מקש קיצור
Show result selection hotkey with results.
Auto Complete
Runs autocomplete for the selected items.
Select Next Item
Select Previous Item
- Next Page
- Previous Page
+ הדף הבא
+ הדף הקודם
Cycle Previous Query
Cycle Next Query
Open Context Menu
Open Native Context Menu
Open Setting Window
- Copy File Path
+ העתק את נתיב הקובץ
Toggle Game Mode
Toggle History
Open Containing Folder
- Run As Admin
+ הרץ כמנהל
Refresh Search Results
Reload Plugins Data
Quick Adjust Window Width
@@ -234,13 +234,13 @@
Custom Query Shortcuts
Built-in Shortcuts
שאילתה
- Shortcut
- Expansion
- Description
+ קיצור דרך
+ הרחבה
+ תיאור
מחק
ערוך
הוסף
- None
+ ללא
אנא בחר פריט
Are you sure you want to delete {0} plugin hotkey?
Are you sure you want to delete shortcut: {0} with expansion {1}?
@@ -259,8 +259,8 @@
Enable HTTP Proxy
HTTP Server
Port
- User Name
- Password
+ שם משתמש
+ סיסמא
Test Proxy
שמור
Server field can't be empty
@@ -272,11 +272,11 @@
אודות
- Website
- GitHub
- Docs
- Version
- Icons
+ אתר אינטרנט
+ Github
+ תיעוד
+ גרסה
+ סמלים
You have activated Flow Launcher {0} times
Check for Updates
Become A Sponsor
@@ -302,8 +302,8 @@
Select File Manager
Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
- File Manager
- Profile Name
+ מנהל קבצים
+ שם פרופיל
File Manager Path
Arg For Folder
Arg For File
@@ -314,9 +314,9 @@
Browser
Browser Name
Browser Path
- New Window
- New Tab
- Private Mode
+ חלון חדש
+ כרטיסייה חדשה
+ מצב פרטיות
Change Priority
@@ -362,14 +362,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
שמור
Overwrite
ביטול
- Reset
+ אפס
מחק
- OK
- Yes
- No
+ אישור
+ כן
+ לא
- Version
+ גרסה
זמן
Please tell us how application crashed so we can fix it
שלח דיווח
@@ -377,21 +377,21 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
כללי
חריגים
Exception Type
- Source
+ מקור
Stack Trace
- Sending
+ שולח
Report sent successfully
Failed to send report
Flow Launcher got an error
- Please wait...
+ אנא המתן...
Checking for new update
You already have the latest Flow Launcher version
- Update found
- Updating...
+ עדכון נמצא
+ מעדכן...
Flow Launcher was not able to move your user profile data to the new update version.
Please manually move your profile data folder from {0} to {1}
@@ -405,7 +405,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.
This upgrade will restart Flow Launcher
Following files will be updated
- Update files
+ עדכן קבצים
Update description
@@ -416,7 +416,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Search and run all files and applications on your PC
Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.
- Hotkeys
+ מקשי קיצור
Action Keyword and Commands
Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.
Let's Start Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
index 0e1753d67..f87dd7d63 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -29,8 +29,8 @@
Everything Setting
Preview Panel
Size
- Date Created
- Date Modified
+ תאריך יצירה
+ תאריך שינוי
Display File Info
Date and time format
Sort Option:
@@ -126,20 +126,20 @@
Failed to load Everything SDK
אזהרה: שירות Everything אינו פועל
שגיאה במהלך שאילתה לEverything
- Sort By
+ מיין לפי
Name
- Path
+ נתיב
Size
Extension
Type Name
- Date Created
- Date Modified
- Attributes
+ תאריך יצירה
+ תאריך שינוי
+ מאפיינים
File List FileName
Run Count
- Date Recently Changed
- Date Accessed
- Date Run
+ תאריך שינוי אחרון
+ תאריך גישה
+ תאריך הרצה
↑
↓
Warning: This is not a Fast Sort option, searches may be slow
@@ -149,11 +149,11 @@
Click to launch or install Everything
Everything Installation
- Installing Everything service. Please wait...
- Successfully installed Everything service
- Failed to automatically install Everything service. Please manually install it from https://www.voidtools.com
+ מתקין את שירות Everything. אנא המתן...
+ שירות Everything הותקן בהצלחה
+ התקנה אוטומטית של שירות Everything נכשלה. אנא הורד אותו ידנית מ- https://www.voidtools.com
Click here to start it
- Unable to find an Everything installation, would you like to manually select a location?{0}{0}Click no and Everything will be automatically installed for you
+ לא מצליח למצוא התקנה של Everything, האם תרצה לבחור מיקום באופן ידני?{0}{0}לחץ על לא וEverything יותקן עבורך אוטומטית
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
index dac5f82bc..dcc74d520 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
@@ -2130,7 +2130,7 @@
Ändern, wie der Mauszeiger ausschaut
- Change power-saving settings
+ Energiespareinstellungen ändern
Optimieren für Blindheit
@@ -2143,7 +2143,7 @@
Windows-Features ein- oder ausschalten
- Show which operating system your computer is running
+ Betriebssystem, welches auf deinem Computer läuft, anzeigen
Lokale Dienste ansehen
From 7fbb68f6b71cde6d1698a18471df2b175250dfc4 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Mon, 27 Jan 2025 16:45:09 +1100
Subject: [PATCH 075/200] version bump
---
appveyor.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/appveyor.yml b/appveyor.yml
index 421088133..af5aaefdc 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: '1.19.4.{build}'
+version: '1.19.5.{build}'
init:
- ps: |
From b9890a975662d2472bfb8844791da1310065045e Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Mon, 27 Jan 2025 16:48:43 +1100
Subject: [PATCH 076/200] bump plugin versions
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Calculator/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Program/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Shell/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Sys/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.Url/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
index a7c230956..519141f6c 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json
@@ -4,7 +4,7 @@
"Name": "Browser Bookmarks",
"Description": "Search your browser bookmarks",
"Author": "qianlifeng, Ioannis G.",
- "Version": "3.3.3",
+ "Version": "3.3.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.BrowserBookmark.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
index bb15cedf2..99e185928 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/plugin.json
@@ -4,7 +4,7 @@
"Name": "Calculator",
"Description": "Provide mathematical calculations.(Try 5*3-2 in Flow Launcher)",
"Author": "cxfksword",
- "Version": "3.1.4",
+ "Version": "3.1.5",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Calculator.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
index d5156fbfd..4eb6bb83b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
@@ -10,7 +10,7 @@
"Name": "Explorer",
"Description": "Find and manage files and folders via Windows Search or Everything",
"Author": "Jeremy Wu",
- "Version": "3.2.3",
+ "Version": "3.2.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json b/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
index 3584d04a4..2b4870792 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json
@@ -4,7 +4,7 @@
"Name": "Plugin Indicator",
"Description": "Provides plugin action keyword suggestions",
"Author": "qianlifeng",
- "Version": "3.0.6",
+ "Version": "3.0.7",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginIndicator.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json b/Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json
index 6562b3cdf..df5a2c784 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": "3.2.3",
+ "Version": "3.2.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json b/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
index 882ccd029..956c4b4e1 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json
@@ -4,7 +4,7 @@
"Name":"Process Killer",
"Description":"Kill running processes from Flow",
"Author":"Flow-Launcher",
- "Version":"3.0.7",
+ "Version":"3.0.8",
"Language":"csharp",
"Website":"https://github.com/Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller",
"IcoPath":"Images\\app.png",
diff --git a/Plugins/Flow.Launcher.Plugin.Program/plugin.json b/Plugins/Flow.Launcher.Plugin.Program/plugin.json
index 6c718ce45..5a95e75f4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Program/plugin.json
@@ -4,7 +4,7 @@
"Name": "Program",
"Description": "Search programs in Flow.Launcher",
"Author": "qianlifeng",
- "Version": "3.3.3",
+ "Version": "3.3.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Program.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
index 6c81e8a26..681e8f751 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json
@@ -4,7 +4,7 @@
"Name": "Shell",
"Description": "Provide executing commands from Flow Launcher",
"Author": "qianlifeng",
- "Version": "3.2.4",
+ "Version": "3.2.5",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Shell.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/plugin.json b/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
index 75be43587..90ca264cc 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Sys/plugin.json
@@ -4,7 +4,7 @@
"Name": "System Commands",
"Description": "Provide System related commands. e.g. shutdown,lock, setting etc.",
"Author": "qianlifeng",
- "Version": "3.1.6",
+ "Version": "3.1.7",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Sys.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.Url/plugin.json b/Plugins/Flow.Launcher.Plugin.Url/plugin.json
index cab056870..73d9bff30 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Url/plugin.json
@@ -4,7 +4,7 @@
"Name": "URL",
"Description": "Open the typed URL from Flow Launcher",
"Author": "qianlifeng",
- "Version": "3.0.7",
+ "Version": "3.0.8",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Url.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index 0314ddfdb..6b6792ad3 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -26,7 +26,7 @@
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
- "Version": "3.1.3",
+ "Version": "3.1.4",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json b/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
index 5c717827e..413a555d3 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json
@@ -4,7 +4,7 @@
"Description": "Search settings inside Control Panel and Settings App",
"Name": "Windows Settings",
"Author": "TobiasSekan",
- "Version": "4.0.11",
+ "Version": "4.0.12",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WindowsSettings.dll",
From 9a8eabd5ee94366f3a90645bd45aa839f067afef Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 27 Jan 2025 22:56:19 +0000
Subject: [PATCH 077/200] Bump Microsoft.Data.Sqlite from 9.0.0 to 9.0.1
Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/dotnet/efcore/releases)
- [Commits](https://github.com/dotnet/efcore/compare/v9.0.0...v9.0.1)
---
updated-dependencies:
- dependency-name: Microsoft.Data.Sqlite
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index 03ac0491f..d7a626e1d 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -95,7 +95,7 @@
-
+
From 208e4a8c204749ac9c78ab32ed0172c7c1075b77 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 27 Jan 2025 22:56:59 +0000
Subject: [PATCH 078/200] Bump VirtualizingWrapPanel from 2.1.0 to 2.1.1
Bumps [VirtualizingWrapPanel](https://github.com/sbaeumlisberger/VirtualizingWrapPanel) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/releases)
- [Commits](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/compare/v2.1.0...v2.1.1)
---
updated-dependencies:
- dependency-name: VirtualizingWrapPanel
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 788beddfb..16228258f 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -100,7 +100,7 @@
-
+
From 3260faba985a595b2df48c0541ebb9bef6aea88e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 31 Jan 2025 22:01:29 +0800
Subject: [PATCH 079/200] Add support for changing startup to logon task for
faster startup experience
---
.../UserSettings/Settings.cs | 1 +
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/Helper/AutoStartup.cs | 115 +++++++++++++++++-
.../SettingsPaneGeneralViewModel.cs | 34 +++++-
.../Views/SettingsPaneGeneral.xaml | 7 ++
6 files changed, 151 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index c412fb32f..81895fdcc 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -238,6 +238,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool EnableUpdateLog { get; set; }
public bool StartFlowLauncherOnSystemStartup { get; set; } = false;
+ public bool UseLogonTaskForStartup { get; set; } = false;
public bool HideOnStartup { get; set; } = true;
bool _hideNotifyIcon { get; set; }
public bool HideNotifyIcon
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 4d1adc6cd..38f846d92 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -119,7 +119,7 @@ namespace Flow.Launcher
{
try
{
- Helper.AutoStartup.Enable();
+ Helper.AutoStartup.Enable(_settings.UseLogonTaskForStartup);
}
catch (Exception e)
{
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 788beddfb..570785be7 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -100,6 +100,7 @@
+
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 4bff30caf..116520ecf 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -1,18 +1,31 @@
using System;
+using System.IO;
+using System.Linq;
+using System.Security.Principal;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Microsoft.Win32;
+using Microsoft.Win32.TaskScheduler;
namespace Flow.Launcher.Helper;
public class AutoStartup
{
private const string StartupPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
+ private const string LogonTaskName = $"{Constant.FlowLauncher} Startup";
+ private const string LogonTaskDesc = $"{Constant.FlowLauncher} Auto Startup";
public static bool IsEnabled
{
get
{
+ // Check if logon task is enabled
+ if (CheckLogonTask())
+ {
+ return true;
+ }
+
+ // Check if registry is enabled
try
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
@@ -28,12 +41,45 @@ public class AutoStartup
}
}
- public static void Disable()
+ private static bool CheckLogonTask()
+ {
+ using var taskService = new TaskService();
+ var task = taskService.RootFolder.AllTasks.FirstOrDefault(t => t.Name == LogonTaskName);
+ if (task != null)
+ {
+ try
+ {
+ // Check if the action is the same as the current executable path
+ var action = task.Definition.Actions.FirstOrDefault()!.ToString().Trim();
+ if (!Constant.ExecutablePath.Equals(action, StringComparison.OrdinalIgnoreCase) && !File.Exists(action))
+ {
+ UnscheduleLogonTask();
+ ScheduleLogonTask();
+ }
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to check logon task");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static void Disable(bool logonTask)
{
try
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.DeleteValue(Constant.FlowLauncher, false);
+ if (logonTask)
+ {
+ UnscheduleLogonTask();
+ }
+ else
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
+ key?.DeleteValue(Constant.FlowLauncher, false);
+ }
}
catch (Exception e)
{
@@ -42,12 +88,19 @@ public class AutoStartup
}
}
- internal static void Enable()
+ internal static void Enable(bool logonTask)
{
try
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
+ if (logonTask)
+ {
+ ScheduleLogonTask();
+ }
+ else
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
+ key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
+ }
}
catch (Exception e)
{
@@ -55,4 +108,54 @@ public class AutoStartup
throw;
}
}
+
+ private static bool ScheduleLogonTask()
+ {
+ using var td = TaskService.Instance.NewTask();
+ td.RegistrationInfo.Description = LogonTaskDesc;
+ td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name, Delay = TimeSpan.FromSeconds(2) });
+ td.Actions.Add(Constant.ExecutablePath);
+
+ if (IsCurrentUserIsAdmin())
+ {
+ td.Principal.RunLevel = TaskRunLevel.Highest;
+ }
+
+ td.Settings.StopIfGoingOnBatteries = false;
+ td.Settings.DisallowStartIfOnBatteries = false;
+ td.Settings.ExecutionTimeLimit = TimeSpan.Zero;
+
+ try
+ {
+ TaskService.Instance.RootFolder.RegisterTaskDefinition(LogonTaskName, td);
+ return true;
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to schedule logon task");
+ return false;
+ }
+ }
+
+ private static bool UnscheduleLogonTask()
+ {
+ using var taskService = new TaskService();
+ try
+ {
+ taskService.RootFolder.DeleteTask(LogonTaskName);
+ return true;
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to unschedule logon task");
+ return false;
+ }
+ }
+
+ private static bool IsCurrentUserIsAdmin()
+ {
+ var identity = WindowsIdentity.GetCurrent();
+ var principal = new WindowsPrincipal(identity);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3d94355e6..0aca761a0 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -42,9 +42,16 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
try
{
if (value)
- AutoStartup.Enable();
+ {
+ // Enable either registry or task scheduler
+ AutoStartup.Enable(UseLogonTaskForStartup);
+ }
else
- AutoStartup.Disable();
+ {
+ // Disable both registry and task scheduler
+ AutoStartup.Disable(true);
+ AutoStartup.Disable(false);
+ }
}
catch (Exception e)
{
@@ -54,6 +61,29 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
}
}
+ public bool UseLogonTaskForStartup
+ {
+ get => Settings.UseLogonTaskForStartup;
+ set
+ {
+ Settings.UseLogonTaskForStartup = value;
+
+ if (StartFlowLauncherOnSystemStartup)
+ {
+ try
+ {
+ // Disable and enable to update the startup method
+ AutoStartup.Disable(!UseLogonTaskForStartup);
+ AutoStartup.Enable(UseLogonTaskForStartup);
+ }
+ catch (Exception e)
+ {
+ Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ e.Message);
+ }
+ }
+ }
+ }
public List SearchWindowScreens { get; } =
DropdownDataGeneric.GetValues("SearchWindowScreen");
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 30e065b16..f57eba654 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -36,6 +36,13 @@
OnContent="{DynamicResource enable}" />
+
+
+
+
Date: Fri, 31 Jan 2025 22:06:53 +0800
Subject: [PATCH 080/200] Move string to resources
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/Languages/zh-cn.xaml | 8 ++++++--
Flow.Launcher/Languages/zh-tw.xaml | 8 ++++++--
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 2 +-
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f..8e8c9abef 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -46,6 +46,7 @@
Portable Mode
Store all settings and user data in one folder (Useful when used with removable drives or cloud services).
Start Flow Launcher on system startup
+ Use logon task instead of startup entry for faster startup experience
Error setting launch on startup
Hide Flow Launcher when focus is lost
Do not show new version notifications
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 681c715fb..d2d1044af 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -1,5 +1,8 @@
-
-
+
+
Flow 检测到您已安装 {0} 个插件,需要 {1} 才能运行。是否要下载 {1}?
@@ -44,6 +47,7 @@
便携模式
将所有设置和用户数据存储在一个文件夹中 (可用于可移除驱动器或云服务)。
开机自启
+ 使用登录任务而非启动项以更快自启
设置开机自启时出错
失去焦点时自动隐藏 Flow Launcher
不显示新版本提示
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 44be5257b..b5aa53377 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -1,5 +1,8 @@
-
-
+
+
Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
@@ -44,6 +47,7 @@
便攜模式
將所有設定和使用者資料存儲在一個資料夾中(當與可移動磁碟或雲服務一起使用時很有用)。
開機時啟動
+ 使用登錄任務而非啟動項以更快自啟
Error setting launch on startup
失去焦點時自動隱藏 Flow Launcher
不顯示新版本提示
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index f57eba654..e52614e74 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -36,7 +36,7 @@
OnContent="{DynamicResource enable}" />
-
+
Date: Fri, 31 Jan 2025 22:22:00 +0800
Subject: [PATCH 081/200] Fix issue when checking logon task
---
Flow.Launcher/Helper/AutoStartup.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 116520ecf..79466f1fb 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -56,15 +56,16 @@ public class AutoStartup
UnscheduleLogonTask();
ScheduleLogonTask();
}
+
+ return true;
}
catch (Exception)
{
Log.Error("AutoStartup", "Failed to check logon task");
- return false;
}
}
- return true;
+ return false;
}
public static void Disable(bool logonTask)
From e320ca1d492594351d81f05ab3da8838c8672dd6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Feb 2025 13:10:32 +0800
Subject: [PATCH 082/200] Add support for deleting plugin settings when
uninstalling plugins
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 21 +++++++++++++++----
.../Languages/en.xaml | 6 ++++--
.../Languages/zh-cn.xaml | 6 ++++--
.../Languages/zh-tw.xaml | 6 ++++--
.../PluginsManager.cs | 6 +++++-
5 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1da..55bc0e2bd 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,6 +14,7 @@ using ISavable = Flow.Launcher.Plugin.ISavable;
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Infrastructure.Storage;
namespace Flow.Launcher.Core.Plugin
{
@@ -439,7 +440,7 @@ namespace Flow.Launcher.Core.Plugin
public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
- UninstallPlugin(existingVersion, removeSettings:false, checkModified:false);
+ UninstallPlugin(existingVersion, removeSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}
@@ -454,9 +455,9 @@ namespace Flow.Launcher.Core.Plugin
///
/// Uninstall a plugin.
///
- public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true)
+ public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true, bool removePluginSettings = false)
{
- UninstallPlugin(plugin, removeSettings, true);
+ UninstallPlugin(plugin, removeSettings, removePluginSettings, true);
}
#endregion
@@ -529,7 +530,7 @@ namespace Flow.Launcher.Core.Plugin
}
}
- internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified)
+ internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
@@ -542,6 +543,18 @@ namespace Flow.Launcher.Core.Plugin
AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
}
+ if (removePluginSettings)
+ {
+ var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
+ var assembly = assemblyLoader.LoadAssemblyAndDependencies();
+ var assemblyName = assembly.GetName().Name;
+ var directoryPath = Path.Combine(DataLocation.DataDirectory(), JsonStorage
-
+
Date: Wed, 12 Feb 2025 10:21:14 +0800
Subject: [PATCH 108/200] Improve explorer path parse when path ends with
backslash
---
.../FileExplorerHelper.cs | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index d908b0fde..b97c096c3 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -15,7 +15,20 @@ namespace Flow.Launcher.Infrastructure
{
var explorerWindow = GetActiveExplorer();
string locationUrl = explorerWindow?.LocationURL;
- return !string.IsNullOrEmpty(locationUrl) ? new Uri(locationUrl).LocalPath + "\\" : null;
+ return !string.IsNullOrEmpty(locationUrl) ? GetDirectoryPath(new Uri(locationUrl).LocalPath) : null;
+ }
+
+ ///
+ /// Get directory path from a file path
+ ///
+ private static string GetDirectoryPath(string path)
+ {
+ if (!path.EndsWith("\\"))
+ {
+ return path + "\\";
+ }
+
+ return path;
}
///
From ddbbd693e8992c8c8f18d21f71f3dff2a01e02d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 12 Feb 2025 15:06:15 +0800
Subject: [PATCH 109/200] Make sure back to query results from context menu
before changing query
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 1 +
Flow.Launcher/CustomShortcutSetting.xaml.cs | 1 +
Flow.Launcher/ResultListBox.xaml.cs | 3 +++
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 1 +
Flow.Launcher/ViewModel/PluginViewModel.cs | 1 +
5 files changed, 7 insertions(+)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8..3db49b381 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,6 +76,7 @@ namespace Flow.Launcher
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
+ App.API.BackToQueryResults();
App.API.ChangeQuery(tbAction.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb..10452726d 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,6 +64,7 @@ namespace Flow.Launcher
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
+ App.API.BackToQueryResults();
App.API.ChangeQuery(tbExpand.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/ResultListBox.xaml.cs b/Flow.Launcher/ResultListBox.xaml.cs
index ac51b195c..cc003457f 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -149,7 +149,10 @@ namespace Flow.Launcher
var rawQuery = query;
var effect = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move | DragDropEffects.Copy);
if (effect == DragDropEffects.Move)
+ {
+ App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery, true);
+ }
}
private void ResultListBox_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 38b5bec65..97c938e78 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,6 +64,7 @@ namespace Flow.Launcher.ViewModel
private void ShowCommandQuery(string action)
{
var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
+ App.API.BackToQueryResults();
App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
App.API.ShowMainWindow();
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 4ce8bd470..e56e8e9e5 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,6 +146,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private void OpenDeletePluginWindow()
{
+ PluginManager.API.BackToQueryResults();
PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
PluginManager.API.ShowMainWindow();
}
From 5313229fb918b19e99eddfd5023c41fed9724e66 Mon Sep 17 00:00:00 2001
From: zggsong
Date: Fri, 14 Feb 2025 13:22:27 +0800
Subject: [PATCH 110/200] perf: hide main window from alt tab program switcher
#2356
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 75 ++++++++++++++++++++
Flow.Launcher/MainWindow.xaml | 1 +
Flow.Launcher/MainWindow.xaml.cs | 5 ++
3 files changed, 81 insertions(+)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index caf3f0a7f..eeb24af2e 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -148,4 +148,79 @@ public class WindowsInteropHelper
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
+
+ #region Alt Tab
+
+ private const int GWL_EXSTYLE = -20;
+ private const int WS_EX_TOOLWINDOW = 0x00000080;
+ private const int WS_EX_APPWINDOW = 0x00040000;
+
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
+ private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)]
+ private static extern int IntSetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
+
+ [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
+ private static extern void SetLastError(int dwErrorCode);
+
+ private static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
+ {
+ SetLastError(0); // Clear any existing error
+
+ if (IntPtr.Size == 4) return new IntPtr(IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)));
+
+ return IntSetWindowLongPtr(hWnd, nIndex, dwNewLong);
+ }
+
+ private static int IntPtrToInt32(IntPtr intPtr)
+ {
+ return unchecked((int)intPtr.ToInt64());
+ }
+
+ ///
+ /// Hide windows in the Alt+Tab window list
+ ///
+ /// To hide a window
+ public static void HideFromAltTab(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+
+ // Add TOOLWINDOW style, remove APPWINDOW style
+ exStyle = (exStyle | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW;
+
+ SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ }
+
+ ///
+ /// Restore window display in the Alt+Tab window list.
+ ///
+ /// To restore the displayed window
+ public static void ShowInAltTab(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+
+ // Remove the TOOLWINDOW style and add the APPWINDOW style.
+ exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+
+ SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ }
+
+ ///
+ /// To obtain the current overridden style of a window.
+ ///
+ /// To obtain the style dialog window
+ /// current extension style value
+ public static int GetCurrentWindowStyle(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ return GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ }
+
+ #endregion
}
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index f5fd729d4..da9e1a5b5 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -20,6 +20,7 @@
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
+ SourceInitialized="OnSourceInitialized"
Initialized="OnInitialized"
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 8ca153afc..41dc68fd9 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -171,6 +171,11 @@ namespace Flow.Launcher
Environment.Exit(0);
}
+ private void OnSourceInitialized(object sender, EventArgs e)
+ {
+ WindowsInteropHelper.HideFromAltTab(this);
+ }
+
private void OnInitialized(object sender, EventArgs e)
{
}
From 829dbaafe7fae537d487f4b67cfe593c01ac5081 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 14 Feb 2025 16:12:15 +0800
Subject: [PATCH 111/200] Use CSWin32 for code quality
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 44 ++++++--------------
Flow.Launcher/NativeMethods.txt | 5 ++-
2 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index eeb24af2e..4891bf41a 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -151,29 +151,11 @@ public class WindowsInteropHelper
#region Alt Tab
- private const int GWL_EXSTYLE = -20;
- private const int WS_EX_TOOLWINDOW = 0x00000080;
- private const int WS_EX_APPWINDOW = 0x00040000;
-
- [DllImport("user32.dll")]
- private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
- private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
-
- [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)]
- private static extern int IntSetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
- private static extern void SetLastError(int dwErrorCode);
-
- private static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
+ private static IntPtr SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
- SetLastError(0); // Clear any existing error
+ PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
- if (IntPtr.Size == 4) return new IntPtr(IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)));
-
- return IntSetWindowLongPtr(hWnd, nIndex, dwNewLong);
+ return PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
}
private static int IntPtrToInt32(IntPtr intPtr)
@@ -182,44 +164,44 @@ public class WindowsInteropHelper
}
///
- /// Hide windows in the Alt+Tab window list
+ /// Hide windows in the Alt+Tab window list
///
/// To hide a window
public static void HideFromAltTab(Window window)
{
var helper = new WindowInteropHelper(window);
- var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Add TOOLWINDOW style, remove APPWINDOW style
- exStyle = (exStyle | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW;
+ var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
- /// Restore window display in the Alt+Tab window list.
+ /// Restore window display in the Alt+Tab window list.
///
/// To restore the displayed window
public static void ShowInAltTab(Window window)
{
var helper = new WindowInteropHelper(window);
- var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
- exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+ var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
- /// To obtain the current overridden style of a window.
+ /// To obtain the current overridden style of a window.
///
/// To obtain the style dialog window
/// current extension style value
public static int GetCurrentWindowStyle(Window window)
{
var helper = new WindowInteropHelper(window);
- return GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ return PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
}
#endregion
diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt
index 2b147c05f..88eeeca6e 100644
--- a/Flow.Launcher/NativeMethods.txt
+++ b/Flow.Launcher/NativeMethods.txt
@@ -14,4 +14,7 @@ FindWindowEx
WINDOW_STYLE
WM_ENTERSIZEMOVE
-WM_EXITSIZEMOVE
\ No newline at end of file
+WM_EXITSIZEMOVE
+
+SetLastError
+WINDOW_EX_STYLE
\ No newline at end of file
From dc07e762fe0abc147a71ea5e8cd8b156e3ad611e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 14 Feb 2025 16:25:51 +0800
Subject: [PATCH 112/200] Add error handling for Get & SetWindowLong failure &
Combine get style function
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 33 +++++++++++---------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index 4891bf41a..3e57948a5 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -151,16 +151,17 @@ public class WindowsInteropHelper
#region Alt Tab
- private static IntPtr SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
+ private static int SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
- return PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
- }
+ var result = PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
+ if (result == 0 && Marshal.GetLastPInvokeError() != 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
- private static int IntPtrToInt32(IntPtr intPtr)
- {
- return unchecked((int)intPtr.ToInt64());
+ return result;
}
///
@@ -169,13 +170,12 @@ public class WindowsInteropHelper
/// To hide a window
public static void HideFromAltTab(Window window)
{
- var helper = new WindowInteropHelper(window);
- var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var exStyle = GetCurrentWindowStyle(window);
// Add TOOLWINDOW style, remove APPWINDOW style
var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
+ SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
@@ -184,13 +184,12 @@ public class WindowsInteropHelper
/// To restore the displayed window
public static void ShowInAltTab(Window window)
{
- var helper = new WindowInteropHelper(window);
- var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var exStyle = GetCurrentWindowStyle(window);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
+ SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
@@ -198,10 +197,14 @@ public class WindowsInteropHelper
///
/// To obtain the style dialog window
/// current extension style value
- public static int GetCurrentWindowStyle(Window window)
+ private static int GetCurrentWindowStyle(Window window)
{
- var helper = new WindowInteropHelper(window);
- return PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var style = PInvoke.GetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ if (style == 0 && Marshal.GetLastPInvokeError() != 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
+ return style;
}
#endregion
From cc570274ffb4ad678d4fba75914c4c40e515d53a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 16 Feb 2025 22:47:10 +0800
Subject: [PATCH 113/200] Fix get thumbnail exception
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index 2fb8cf363..a8d1d78ed 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,8 +31,6 @@ namespace Flow.Launcher.Infrastructure.Image
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
- private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
-
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
@@ -79,7 +77,12 @@ namespace Flow.Launcher.Infrastructure.Image
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
- catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
+ catch (COMException)
+ {
+ // Fallback to IconOnly if ThumbnailOnly fails
+ imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
+ }
+ catch (FileNotFoundException)
{
// Fallback to IconOnly if ThumbnailOnly fails
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
From 38b285067d1874ce1952db25a2529502a53cbe4f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 16 Feb 2025 22:50:43 +0800
Subject: [PATCH 114/200] Improve documents
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index a8d1d78ed..bd34bdd2a 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -79,12 +79,12 @@ namespace Flow.Launcher.Infrastructure.Image
}
catch (COMException)
{
- // Fallback to IconOnly if ThumbnailOnly fails
+ // Fallback to IconOnly for COM exceptions
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
catch (FileNotFoundException)
{
- // Fallback to IconOnly if ThumbnailOnly fails
+ // Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
}
From d73f3a165b9d3faa8b9cf35f0bd714b286bd5af9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 00:00:18 +0800
Subject: [PATCH 115/200] Fix custom hotkey preview issue
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 18 ++++++++++--------
Flow.Launcher/CustomShortcutSetting.xaml.cs | 8 +++++---
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 11 +++++++----
.../Views/SettingsPaneHotkey.xaml.cs | 4 ++--
Flow.Launcher/SettingWindow.xaml.cs | 8 +++++---
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +++--
7 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8..db1df0cf2 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -7,20 +7,23 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
private SettingWindow _settingWidow;
+ private readonly Settings _settings;
+ private readonly MainViewModel _mainViewModel;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
- public Settings Settings { get; }
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
+ public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings, MainViewModel mainVM)
{
_settingWidow = settingWidow;
- Settings = settings;
+ _settings = settings;
+ _mainViewModel = mainVM;
InitializeComponent();
}
@@ -33,13 +36,13 @@ namespace Flow.Launcher
{
if (!update)
{
- Settings.CustomPluginHotkeys ??= new ObservableCollection();
+ _settings.CustomPluginHotkeys ??= new ObservableCollection();
var pluginHotkey = new CustomPluginHotkey
{
Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
};
- Settings.CustomPluginHotkeys.Add(pluginHotkey);
+ _settings.CustomPluginHotkeys.Add(pluginHotkey);
HotKeyMapper.SetCustomQueryHotkey(pluginHotkey);
}
@@ -59,7 +62,7 @@ namespace Flow.Launcher
public void UpdateItem(CustomPluginHotkey item)
{
- updateCustomHotkey = Settings.CustomPluginHotkeys.FirstOrDefault(o =>
+ updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
@@ -77,8 +80,7 @@ namespace Flow.Launcher
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- Application.Current.MainWindow.Show();
- Application.Current.MainWindow.Opacity = 1;
+ _mainViewModel.Show(false);
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb..cb2cfcb29 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -4,21 +4,24 @@ using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
+ private readonly MainViewModel _mainViewModel;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
+ public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm, MainViewModel mainVM)
{
_hotkeyVm = vm;
+ _mainViewModel = mainVM;
InitializeComponent();
}
@@ -65,8 +68,7 @@ namespace Flow.Launcher
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- Application.Current.MainWindow.Show();
- Application.Current.MainWindow.Opacity = 1;
+ _mainViewModel.Show(false);
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf24..2d8126033 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -105,7 +105,7 @@ namespace Flow.Launcher
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
+ SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM, _mainVM);
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 6d8af9a3f..5aedd3be7 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -8,12 +8,14 @@ using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneHotkeyViewModel : BaseModel
{
public Settings Settings { get; }
+ private MainViewModel MainVM { get; }
public CustomPluginHotkey SelectedCustomPluginHotkey { get; set; }
public CustomShortcutModel SelectedCustomShortcut { get; set; }
@@ -25,9 +27,10 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
$"{KeyConstant.Ctrl}+{KeyConstant.Alt}"
};
- public SettingsPaneHotkeyViewModel(Settings settings)
+ public SettingsPaneHotkeyViewModel(Settings settings, MainViewModel mainVM)
{
Settings = settings;
+ MainVM = mainVM;
}
[RelayCommand]
@@ -71,7 +74,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings);
+ var window = new CustomQueryHotkeySetting(null, Settings, MainVM);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -79,7 +82,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings).ShowDialog();
+ new CustomQueryHotkeySetting(null, Settings, MainVM).ShowDialog();
}
[RelayCommand]
@@ -126,7 +129,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomShortcutAdd()
{
- var window = new CustomShortcutSetting(this);
+ var window = new CustomShortcutSetting(this, MainVM);
if (window.ShowDialog() is true)
{
var shortcut = new CustomShortcutModel(window.Key, window.Value);
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 061eabf51..26939c9f9 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -12,9 +12,9 @@ public partial class SettingsPaneHotkey
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
+ if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, MainViewModel: { } mainVM })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
- _viewModel = new SettingsPaneHotkeyViewModel(settings);
+ _viewModel = new SettingsPaneHotkeyViewModel(settings, mainVM);
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index d5b303516..ae481b65b 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -20,12 +20,14 @@ public partial class SettingWindow
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
+ private readonly MainViewModel _mainVM;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
+ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel, MainViewModel mainVM)
{
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
+ _mainVM = mainVM;
_api = api;
InitializePosition();
InitializeComponent();
@@ -160,7 +162,7 @@ public partial class SettingWindow
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
+ var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable, _mainVM);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
@@ -206,5 +208,5 @@ public partial class SettingWindow
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
- public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
+ public record PaneData(Settings Settings, Updater Updater, IPortable Portable, MainViewModel MainViewModel);
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3..7c2abb078 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1359,7 +1359,7 @@ namespace Flow.Launcher.ViewModel
}
}
- public void Show()
+ public void Show(bool invokeEvent = true)
{
Application.Current.Dispatcher.Invoke(() =>
{
@@ -1368,7 +1368,8 @@ namespace Flow.Launcher.ViewModel
MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
- VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
+ if (invokeEvent)
+ VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
From 0611340d7159d050bc3a8a9dac7d4df852a568f1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 16:10:07 +0800
Subject: [PATCH 116/200] Invoke visibility changed event when previewing
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 5 ++---
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index db1df0cf2..d33794d61 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -80,7 +80,7 @@ namespace Flow.Launcher
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- _mainViewModel.Show(false);
+ _mainViewModel.Show();
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index cb2cfcb29..4cc30c8f5 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -68,7 +68,7 @@ namespace Flow.Launcher
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- _mainViewModel.Show(false);
+ _mainViewModel.Show();
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 7c2abb078..55bc8d1b3 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1359,7 +1359,7 @@ namespace Flow.Launcher.ViewModel
}
}
- public void Show(bool invokeEvent = true)
+ public void Show()
{
Application.Current.Dispatcher.Invoke(() =>
{
@@ -1368,8 +1368,7 @@ namespace Flow.Launcher.ViewModel
MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
- if (invokeEvent)
- VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
+ VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
From 71f1acd9ec148ea82055644b7498e2c956b6f623 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 19:07:01 +0800
Subject: [PATCH 117/200] Revert com expcetion & Add thumbnail only check
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index bd34bdd2a..b98ea50fe 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,6 +31,8 @@ namespace Flow.Launcher.Infrastructure.Image
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
+ private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
+
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
@@ -77,12 +79,12 @@ namespace Flow.Launcher.Infrastructure.Image
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
- catch (COMException)
+ catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
{
- // Fallback to IconOnly for COM exceptions
+ // Fallback to IconOnly if ThumbnailOnly fails
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
- catch (FileNotFoundException)
+ catch (FileNotFoundException) when (options == ThumbnailOptions.ThumbnailOnly)
{
// Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
From 827b6edb38f58c5d7f94a19b0c690a1b9c1ce3f4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:12:46 +0800
Subject: [PATCH 118/200] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 5bfc68ea6..374caa511 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -120,10 +120,9 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+
if (result == MessageBoxResult.Yes)
- {
Process.Start("shutdown", "/s /t 0");
- }
return true;
}
@@ -140,10 +139,9 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+
if (result == MessageBoxResult.Yes)
- {
Process.Start("shutdown", "/r /t 0");
- }
return true;
}
@@ -204,7 +202,11 @@ namespace Flow.Launcher.Plugin.Sys
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
- Action = c => PInvoke.SetSuspendState(false, false, false)
+ Action = c =>
+ {
+ PInvoke.SetSuspendState(false, false, false);
+ return true;
+ }
},
new Result
{
@@ -231,10 +233,7 @@ namespace Flow.Launcher.Plugin.Sys
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
Action = c =>
{
- {
- System.Diagnostics.Process.Start("control.exe", "srchadmin.dll");
- }
-
+ Process.Start("control.exe", "srchadmin.dll");
return true;
}
},
@@ -272,10 +271,7 @@ namespace Flow.Launcher.Plugin.Sys
CopyText = recycleBinFolder,
Action = c =>
{
- {
- System.Diagnostics.Process.Start("explorer", recycleBinFolder);
- }
-
+ Process.Start("explorer", recycleBinFolder);
return true;
}
},
From ffa303825ef2a1523751f4aedc6a309726796b24 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:22:06 +0800
Subject: [PATCH 119/200] Replace process commands with PInvoke
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 374caa511..16c1b7f91 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -122,7 +122,7 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/s /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -141,7 +141,7 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/r /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -160,7 +160,7 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/r /o /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -179,7 +179,7 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, 0);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
From e93699b37daaa1bedefd5e442413ea79dbe3204e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:37:20 +0800
Subject: [PATCH 120/200] Add shutdown reason
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 16c1b7f91..3199f50a2 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -121,8 +121,12 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+ // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure,
+ // software updates, or other predefined reasons.
+ // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -141,7 +145,8 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -160,7 +165,8 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -179,7 +185,8 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
From 18093148429abfaa94db92607984a53d97cde8cf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 00:08:15 +0800
Subject: [PATCH 121/200] Enable shutdown privilege before calling PInvoke for
shutdown and start
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 63 +++++++++++++++++--
.../NativeMethods.txt | 7 ++-
2 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 3199f50a2..7d3f66746 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Runtime.InteropServices;
using System.Windows;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
@@ -9,6 +10,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using Windows.Win32;
using Windows.Win32.Foundation;
+using Windows.Win32.Security;
using Windows.Win32.System.Shutdown;
using Application = System.Windows.Application;
using Control = System.Windows.Controls.Control;
@@ -20,6 +22,8 @@ namespace Flow.Launcher.Plugin.Sys
private PluginInitContext context;
private Dictionary KeywordTitleMappings = new Dictionary();
+ private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
+
public Control CreateSettingPanel()
{
var results = Commands();
@@ -100,6 +104,44 @@ namespace Flow.Launcher.Plugin.Sys
};
}
+ private static unsafe bool EnableShutdownPrivilege()
+ {
+ try
+ {
+ if (!PInvoke.OpenProcessToken(Process.GetCurrentProcess().SafeHandle, TOKEN_ACCESS_MASK.TOKEN_ADJUST_PRIVILEGES | TOKEN_ACCESS_MASK.TOKEN_QUERY, out var tokenHandle))
+ {
+ return false;
+ }
+
+ if (!PInvoke.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out var luid))
+ {
+ return false;
+ }
+
+ var privileges = new TOKEN_PRIVILEGES
+ {
+ PrivilegeCount = 1,
+ Privileges = new() { e0 = new LUID_AND_ATTRIBUTES { Luid = luid, Attributes = TOKEN_PRIVILEGES_ATTRIBUTES.SE_PRIVILEGE_ENABLED } }
+ };
+
+ if (!PInvoke.AdjustTokenPrivileges(tokenHandle, false, &privileges, 0, null, null))
+ {
+ return false;
+ }
+
+ if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.NO_ERROR)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
private List Commands()
{
var results = new List();
@@ -125,8 +167,11 @@ namespace Flow.Launcher.Plugin.Sys
// software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/s /t 0");
return true;
}
@@ -145,8 +190,11 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/r /t 0");
return true;
}
@@ -165,8 +213,11 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/r /o /t 0");
return true;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
index 8fcb6cae9..6159c725b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
+++ b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
@@ -3,4 +3,9 @@ LockWorkStation
SHEmptyRecycleBin
S_OK
E_UNEXPECTED
-SetSuspendState
\ No newline at end of file
+SetSuspendState
+OpenProcessToken
+WIN32_ERROR
+LookupPrivilegeValue
+AdjustTokenPrivileges
+TOKEN_PRIVILEGES
\ No newline at end of file
From 648e3f268990c6da85eef377d5d1b5bc97dc438b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:07:18 +0800
Subject: [PATCH 122/200] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 7d3f66746..f6117aab9 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -23,6 +23,9 @@ namespace Flow.Launcher.Plugin.Sys
private Dictionary KeywordTitleMappings = new Dictionary();
private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
+ // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
+ // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
+ private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
public Control CreateSettingPanel()
{
@@ -163,13 +166,9 @@ namespace Flow.Launcher.Plugin.Sys
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
- // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure,
- // software updates, or other predefined reasons.
- // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, REASON);
else
Process.Start("shutdown", "/s /t 0");
@@ -191,8 +190,7 @@ namespace Flow.Launcher.Plugin.Sys
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, REASON);
else
Process.Start("shutdown", "/r /t 0");
@@ -214,8 +212,7 @@ namespace Flow.Launcher.Plugin.Sys
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, REASON);
else
Process.Start("shutdown", "/r /o /t 0");
@@ -236,8 +233,7 @@ namespace Flow.Launcher.Plugin.Sys
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, REASON);
return true;
}
From a065179d53aee2146e633e0bf2db2ad3ccd066f6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:12:33 +0800
Subject: [PATCH 123/200] Use PInvoke for const
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 3 +--
Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt | 3 ++-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index f6117aab9..3bda99e71 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -22,7 +22,6 @@ namespace Flow.Launcher.Plugin.Sys
private PluginInitContext context;
private Dictionary KeywordTitleMappings = new Dictionary();
- private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
// SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
@@ -116,7 +115,7 @@ namespace Flow.Launcher.Plugin.Sys
return false;
}
- if (!PInvoke.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out var luid))
+ if (!PInvoke.LookupPrivilegeValue(null, PInvoke.SE_SHUTDOWN_NAME, out var luid))
{
return false;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
index 6159c725b..4567e46a3 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
+++ b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
@@ -8,4 +8,5 @@ OpenProcessToken
WIN32_ERROR
LookupPrivilegeValue
AdjustTokenPrivileges
-TOKEN_PRIVILEGES
\ No newline at end of file
+TOKEN_PRIVILEGES
+SE_SHUTDOWN_NAME
\ No newline at end of file
From 3bd4ca4105840ab4a679a21817148ade91660263 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:17:45 +0800
Subject: [PATCH 124/200] Replace hiberate with PInvoke
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 3bda99e71..e81d70c52 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -269,12 +269,7 @@ namespace Flow.Launcher.Plugin.Sys
IcoPath = "Images\\hibernate.png",
Action= c =>
{
- var info = ShellCommand.SetProcessStartInfo("shutdown", arguments:"/h");
- info.WindowStyle = ProcessWindowStyle.Hidden;
- info.UseShellExecute = true;
-
- ShellCommand.Execute(info);
-
+ PInvoke.SetSuspendState(true, false, false);
return true;
}
},
From 6b032b33520a272f8d9a239253272aa0fa234f68 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:32:47 +0800
Subject: [PATCH 125/200] Revert changes and use api function instead
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 7 ++-----
Flow.Launcher/CustomShortcutSetting.xaml.cs | 7 ++-----
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 11 ++++-------
.../SettingPages/Views/SettingsPaneHotkey.xaml.cs | 4 ++--
Flow.Launcher/SettingWindow.xaml.cs | 8 +++-----
6 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index d33794d61..1bd6ee95b 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -7,7 +7,6 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
@@ -15,15 +14,13 @@ namespace Flow.Launcher
{
private SettingWindow _settingWidow;
private readonly Settings _settings;
- private readonly MainViewModel _mainViewModel;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings, MainViewModel mainVM)
+ public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
{
_settingWidow = settingWidow;
_settings = settings;
- _mainViewModel = mainVM;
InitializeComponent();
}
@@ -80,7 +77,7 @@ namespace Flow.Launcher
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- _mainViewModel.Show();
+ App.API.ShowMainWindow();
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 4cc30c8f5..05d4d3d83 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -4,24 +4,21 @@ using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
- private readonly MainViewModel _mainViewModel;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm, MainViewModel mainVM)
+ public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
{
_hotkeyVm = vm;
- _mainViewModel = mainVM;
InitializeComponent();
}
@@ -68,7 +65,7 @@ namespace Flow.Launcher
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- _mainViewModel.Show();
+ App.API.ShowMainWindow();
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 2d8126033..f0295cf24 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -105,7 +105,7 @@ namespace Flow.Launcher
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM, _mainVM);
+ SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 5aedd3be7..6d8af9a3f 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -8,14 +8,12 @@ using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneHotkeyViewModel : BaseModel
{
public Settings Settings { get; }
- private MainViewModel MainVM { get; }
public CustomPluginHotkey SelectedCustomPluginHotkey { get; set; }
public CustomShortcutModel SelectedCustomShortcut { get; set; }
@@ -27,10 +25,9 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
$"{KeyConstant.Ctrl}+{KeyConstant.Alt}"
};
- public SettingsPaneHotkeyViewModel(Settings settings, MainViewModel mainVM)
+ public SettingsPaneHotkeyViewModel(Settings settings)
{
Settings = settings;
- MainVM = mainVM;
}
[RelayCommand]
@@ -74,7 +71,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings, MainVM);
+ var window = new CustomQueryHotkeySetting(null, Settings);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -82,7 +79,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings, MainVM).ShowDialog();
+ new CustomQueryHotkeySetting(null, Settings).ShowDialog();
}
[RelayCommand]
@@ -129,7 +126,7 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
[RelayCommand]
private void CustomShortcutAdd()
{
- var window = new CustomShortcutSetting(this, MainVM);
+ var window = new CustomShortcutSetting(this);
if (window.ShowDialog() is true)
{
var shortcut = new CustomShortcutModel(window.Key, window.Value);
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 26939c9f9..061eabf51 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -12,9 +12,9 @@ public partial class SettingsPaneHotkey
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, MainViewModel: { } mainVM })
+ if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
- _viewModel = new SettingsPaneHotkeyViewModel(settings, mainVM);
+ _viewModel = new SettingsPaneHotkeyViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index ae481b65b..d5b303516 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -20,14 +20,12 @@ public partial class SettingWindow
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
- private readonly MainViewModel _mainVM;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel, MainViewModel mainVM)
+ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
{
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
- _mainVM = mainVM;
_api = api;
InitializePosition();
InitializeComponent();
@@ -162,7 +160,7 @@ public partial class SettingWindow
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable, _mainVM);
+ var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
@@ -208,5 +206,5 @@ public partial class SettingWindow
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
- public record PaneData(Settings Settings, Updater Updater, IPortable Portable, MainViewModel MainViewModel);
+ public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
}
From 9284c559f68cc8418af9cea727c8954b01153e6c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:41:26 +0800
Subject: [PATCH 126/200] Use api function to hide window
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 8 ++++----
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 671489846..c1ed904b3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -534,7 +534,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(plugin);
return ShouldHideWindow;
@@ -572,7 +572,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return false;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(plugin);
return ShouldHideWindow;
@@ -626,7 +626,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return ShouldHideWindow;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(x); // No need to wait
return ShouldHideWindow;
},
@@ -703,7 +703,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
Uninstall(x.Metadata);
if (Settings.AutoRestartAfterChanging)
{
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 5bfc68ea6..edf9c82e4 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -333,7 +333,7 @@ namespace Flow.Launcher.Plugin.Sys
Action = c =>
{
// Hide the window first then show msg after done because sometimes the reload could take a while, so not to make user think it's frozen.
- Application.Current.MainWindow.Hide();
+ context.API.HideMainWindow();
_ = context.API.ReloadAllPluginData().ContinueWith(_ =>
context.API.ShowMsg(
@@ -352,7 +352,7 @@ namespace Flow.Launcher.Plugin.Sys
IcoPath = "Images\\checkupdate.png",
Action = c =>
{
- Application.Current.MainWindow.Hide();
+ context.API.HideMainWindow();
context.API.CheckForNewUpdate();
return true;
}
From 3dade8bbfcf5c556e5b08caab23b38aabc55f9b1 Mon Sep 17 00:00:00 2001
From: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
Date: Wed, 19 Feb 2025 00:03:46 -0800
Subject: [PATCH 127/200] Don't restart the jsonrpc process when reloading
data.
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index f95266c7f..19d7edb31 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -135,10 +135,9 @@ namespace Flow.Launcher.Core.Plugin
public virtual async Task ReloadDataAsync()
{
- SetupJsonRPC();
try
{
- await RPC.InvokeAsync("reload", Context);
+ await RPC.InvokeAsync("reload_data", Context);
}
catch (RemoteMethodNotFoundException e)
{
From 2843236214981585fb2316ea25e675cf56bc21f3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 19 Feb 2025 17:09:09 +0800
Subject: [PATCH 128/200] Improve documents & Improve code quality
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 1 +
Flow.Launcher/CustomShortcutSetting.xaml.cs | 1 +
Flow.Launcher/ResultListBox.xaml.cs | 1 +
Flow.Launcher/ViewModel/MainViewModel.cs | 2 ++
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 1 +
Flow.Launcher/ViewModel/PluginViewModel.cs | 1 +
Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 5 +++--
8 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 3db49b381..fd829afe2 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,6 +76,7 @@ namespace Flow.Launcher
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(tbAction.Text);
Application.Current.MainWindow.Show();
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 10452726d..d05a5c15c 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,6 +64,7 @@ namespace Flow.Launcher
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(tbExpand.Text);
Application.Current.MainWindow.Show();
diff --git a/Flow.Launcher/ResultListBox.xaml.cs b/Flow.Launcher/ResultListBox.xaml.cs
index cc003457f..834692536 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -150,6 +150,7 @@ namespace Flow.Launcher
var effect = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move | DragDropEffects.Copy);
if (effect == DragDropEffects.Move)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery, true);
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5c3251bfc..4af93daf9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1266,6 +1266,7 @@ namespace Flow.Launcher.ViewModel
{
_topMostRecord.Remove(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ReQuery();
return false;
@@ -1284,6 +1285,7 @@ namespace Flow.Launcher.ViewModel
{
_topMostRecord.AddOrUpdate(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ReQuery();
return false;
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 97c938e78..7675ecb16 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,6 +64,7 @@ namespace Flow.Launcher.ViewModel
private void ShowCommandQuery(string action)
{
var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
App.API.ShowMainWindow();
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index e56e8e9e5..c8601c431 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,6 +146,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private void OpenDeletePluginWindow()
{
+ // if user happens to open context menu, we need to return back to query results before changing query
PluginManager.API.BackToQueryResults();
PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
PluginManager.API.ShowMainWindow();
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
index 17e9fe2bc..482e821dc 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
@@ -59,7 +59,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
var link = pluginManifestInfo.UrlSourceCode.StartsWith("https://github.com")
? Regex.Replace(pluginManifestInfo.UrlSourceCode, @"\/tree\/\w+$", "") + "/issues"
: pluginManifestInfo.UrlSourceCode;
-
Context.API.OpenUrl(link);
return true;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 7f1f4bd4d..86808cfbc 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -5,7 +5,6 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows;
using WindowsInput;
using WindowsInput.Native;
using Flow.Launcher.Infrastructure.Hotkey;
@@ -379,9 +378,11 @@ namespace Flow.Launcher.Plugin.Shell
private void OnWinRPressed()
{
// show the main window and set focus to the query box
- Task.Run(() =>
+ _ = Task.Run(() =>
{
context.API.ShowMainWindow();
+ // if user happens to open context menu, we need to return back to query results before changing query
+ context.API.BackToQueryResults();
context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
From ccf8d876ae2f96b556926f9d7df5c91347552adf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 14:59:16 +0800
Subject: [PATCH 129/200] Add support for hiding dulplicated windows apps
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 28 +++++++++++++++++++
.../Flow.Launcher.Plugin.Program/Settings.cs | 1 +
2 files changed, 29 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 6ba7047f2..00fb1d344 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -72,6 +72,8 @@ namespace Flow.Launcher.Plugin.Program
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
+ private const string WindowsAppPath = "c:\\program files\\windowsapps";
+
static Main()
{
}
@@ -90,11 +92,20 @@ namespace Flow.Launcher.Plugin.Program
{
try
{
+ // Collect all UWP Windows app directories
+ var uwpsDirectories = _settings.HideDulplicatedWindowsApp ? _uwps
+ .Where(uwp => !string.IsNullOrEmpty(uwp.Location)) // Exclude invalid paths
+ .Where(uwp => uwp.Location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase)) // Keep system apps
+ .Select(uwp => uwp.Location.TrimEnd('\\')) // Remove trailing slash
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToArray() : null;
+
return _win32s.Cast()
.Concat(_uwps)
.AsParallel()
.WithCancellation(token)
.Where(HideUninstallersFilter)
+ .Where(p => HideDulplicatedWindowsAppFilter(p, uwpsDirectories))
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, Context.API))
.Where(r => r?.Score > 0)
@@ -152,6 +163,23 @@ namespace Flow.Launcher.Plugin.Program
return true;
}
+ private static bool HideDulplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
+ {
+ if (uwpsDirectories == null || uwpsDirectories.Length == 0) return true;
+ if (program is UWPApp) return true;
+
+ var location = program.Location.TrimEnd('\\'); // Ensure trailing slash
+ if (string.IsNullOrEmpty(location))
+ return true; // Keep if location is invalid
+
+ if (!location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase))
+ return true; // Keep if not a Windows app
+
+ // Check if the any Win32 executable directory contains UWP Windows app location matches
+ return !uwpsDirectories.Any(uwpDirectory =>
+ location.StartsWith(uwpDirectory, StringComparison.OrdinalIgnoreCase));
+ }
+
public async Task InitAsync(PluginInitContext context)
{
Context = context;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index fb24f64d7..664277e02 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,6 +121,7 @@ namespace Flow.Launcher.Plugin.Program
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
+ public bool HideDulplicatedWindowsApp { get; set; } = true;
internal const char SuffixSeparator = ';';
}
From b4bffb1cf54bb0a050ea2277ffa1893b1df05c39 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 17:17:53 +0800
Subject: [PATCH 130/200] Use null as default value for record key
---
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 bb005752e..9b16cc1cb 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -266,8 +266,9 @@ namespace Flow.Launcher.Plugin
/// 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.
/// If the plugin does not specific this, FL just uses Title and SubTitle to identify this result.
+ /// Note: Because old data does not have this key, we should use null as the default value for consistency.
///
- public string RecordKey { get; set; } = string.Empty;
+ public string RecordKey { get; set; } = null;
///
/// Info of the preview section of a
From 4f41be67ac5135158d22d6f99859cda1a2f84f57 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:02:59 +0800
Subject: [PATCH 131/200] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1da..8f2d78d76 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -281,7 +281,7 @@ namespace Flow.Launcher.Core.Plugin
return results;
}
- public static void UpdatePluginMetadata(List results, PluginMetadata metadata, Query query)
+ public static void UpdatePluginMetadata(IReadOnlyList results, PluginMetadata metadata, Query query)
{
foreach (var r in results)
{
From 2ffe170407b0ca012b267051569e29de43c77c46 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:06:15 +0800
Subject: [PATCH 132/200] Use deep clone for result updating
---
Flow.Launcher/ViewModel/MainViewModel.cs | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5c3251bfc..b498f4001 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -231,8 +231,8 @@ namespace Flow.Launcher.ViewModel
var token = e.Token == default ? _updateToken : e.Token;
- // make a copy of results to avoid plugin change the result when updating view model
- var resultsCopy = e.Results.ToList();
+ // 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);
PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query);
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
@@ -414,6 +414,22 @@ namespace Flow.Launcher.ViewModel
}
}
+ private static IReadOnlyList DeepCloneResults(IReadOnlyList results, CancellationToken token = default)
+ {
+ var resultsCopy = new List();
+ foreach (var result in results.ToList())
+ {
+ if (token.IsCancellationRequested)
+ {
+ break;
+ }
+
+ var resultCopy = result.Clone();
+ resultsCopy.Add(resultCopy);
+ }
+ return resultsCopy;
+ }
+
#endregion
#region BasicCommands
@@ -1469,9 +1485,9 @@ namespace Flow.Launcher.ViewModel
{
if (_topMostRecord.IsTopMost(result))
{
- result.Score = Result.MaxScore;
+ result.Score = 100000; //Result.MaxScore;
}
- else if (result.Score != Result.MaxScore)
+ else
{
var priorityScore = metaResults.Metadata.Priority * 150;
result.Score += result.AddSelectedCount ?
From 9850e9d3eb6af9c78003738e23dd819336446ba4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:17:29 +0800
Subject: [PATCH 133/200] Fix issue that plugin will cannot cache records
---
Flow.Launcher/ViewModel/MainViewModel.cs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index b498f4001..e030d8eae 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1196,9 +1196,18 @@ namespace Flow.Launcher.ViewModel
currentCancellationToken.ThrowIfCancellationRequested();
- results ??= _emptyResult;
+ IReadOnlyList resultsCopy;
+ if (results == null)
+ {
+ resultsCopy = _emptyResult;
+ }
+ else
+ {
+ // make a copy of results to avoid possible issue that FL changes some properties of the records, like score, etc.
+ resultsCopy = DeepCloneResults(results);
+ }
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query,
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
currentCancellationToken, reSelect)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
From 7ccfbcae7f2cef218357abd1aa842592e88a4b9f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 23:15:12 +0800
Subject: [PATCH 134/200] Add hide dulplicated windows apps into settings panel
---
.../Languages/en.xaml | 2 +
.../Flow.Launcher.Plugin.Program/Settings.cs | 2 +-
.../Views/ProgramSetting.xaml | 53 ++++++++++---------
.../Views/ProgramSetting.xaml.cs | 10 ++++
4 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 7ed711e17..640b082e7 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -36,6 +36,8 @@
Hides programs with common uninstaller names, such as unins000.exe
Search in Program Description
Flow will search program's description
+ Hide dulplicated apps
+ Hide dulplicated Win32 programs that are already in the UWP list
Suffixes
Max Depth
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index 664277e02..53cb1755d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,7 +121,7 @@ namespace Flow.Launcher.Plugin.Program
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
- public bool HideDulplicatedWindowsApp { get; set; } = true;
+ public bool HideDulplicatedWindowsApp { get; set; } = false;
internal const char SuffixSeparator = ';';
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index e5ca6967e..0482099ad 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -8,7 +8,7 @@
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
-
+
@@ -18,40 +18,40 @@
+ ToolTip="{DynamicResource flowlauncher_plugin_program_index_uwp_tooltip}"
+ Visibility="{Binding ShowUWPCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}" />
@@ -67,21 +67,20 @@
BorderBrush="{DynamicResource Color03B}"
BorderThickness="1" />
@@ -91,11 +90,15 @@
IsChecked="{Binding HideUninstallers}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers_tooltip}" />
+
@@ -142,7 +145,7 @@
Minimum="0" />
@@ -151,7 +154,7 @@
+ Margin="0 0 20 0">
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 36b5acc8a..0c6265594 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -57,6 +57,16 @@ namespace Flow.Launcher.Plugin.Program.Views
}
}
+ public bool HideDulplicatedWindowsApp
+ {
+ get => _settings.HideDulplicatedWindowsApp;
+ set
+ {
+ Main.ResetCache();
+ _settings.HideDulplicatedWindowsApp = value;
+ }
+ }
+
public bool EnableRegistrySource
{
get => _settings.EnableRegistrySource;
From 097633e9e0a4d504cda69caf86bdc40ca71706a8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 09:29:43 +0800
Subject: [PATCH 135/200] Fix typos
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 4 ++--
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 6 +++---
Plugins/Flow.Launcher.Plugin.Program/Settings.cs | 2 +-
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml | 6 +++---
.../Views/ProgramSetting.xaml.cs | 6 +++---
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 640b082e7..790c9d2c6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -36,8 +36,8 @@
Hides programs with common uninstaller names, such as unins000.exe
Search in Program Description
Flow will search program's description
- Hide dulplicated apps
- Hide dulplicated Win32 programs that are already in the UWP list
+ Hide duplicated apps
+ Hide duplicated Win32 programs that are already in the UWP list
Suffixes
Max Depth
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 00fb1d344..dd2a874fa 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -93,7 +93,7 @@ namespace Flow.Launcher.Plugin.Program
try
{
// Collect all UWP Windows app directories
- var uwpsDirectories = _settings.HideDulplicatedWindowsApp ? _uwps
+ var uwpsDirectories = _settings.HideDuplicatedWindowsApp ? _uwps
.Where(uwp => !string.IsNullOrEmpty(uwp.Location)) // Exclude invalid paths
.Where(uwp => uwp.Location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase)) // Keep system apps
.Select(uwp => uwp.Location.TrimEnd('\\')) // Remove trailing slash
@@ -105,7 +105,7 @@ namespace Flow.Launcher.Plugin.Program
.AsParallel()
.WithCancellation(token)
.Where(HideUninstallersFilter)
- .Where(p => HideDulplicatedWindowsAppFilter(p, uwpsDirectories))
+ .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, Context.API))
.Where(r => r?.Score > 0)
@@ -163,7 +163,7 @@ namespace Flow.Launcher.Plugin.Program
return true;
}
- private static bool HideDulplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
+ private static bool HideDuplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
{
if (uwpsDirectories == null || uwpsDirectories.Length == 0) return true;
if (program is UWPApp) return true;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index 53cb1755d..b2aad63b3 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,7 +121,7 @@ namespace Flow.Launcher.Plugin.Program
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
- public bool HideDulplicatedWindowsApp { get; set; } = false;
+ public bool HideDuplicatedWindowsApp { get; set; } = false;
internal const char SuffixSeparator = ';';
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index 0482099ad..973ac9f60 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -96,9 +96,9 @@
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_description_tooltip}" />
+ Content="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp}"
+ IsChecked="{Binding HideDuplicatedWindowsApp}"
+ ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip}" />
_settings.HideDulplicatedWindowsApp;
+ get => _settings.HideDuplicatedWindowsApp;
set
{
Main.ResetCache();
- _settings.HideDulplicatedWindowsApp = value;
+ _settings.HideDuplicatedWindowsApp = value;
}
}
From 79bcf8be18beb61d7072bd092ef1e2c67fb0ef7f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 09:32:58 +0800
Subject: [PATCH 136/200] Use system environment for Windows app path
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index dd2a874fa..65af0b56c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -72,7 +72,7 @@ namespace Flow.Launcher.Plugin.Program
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
- private const string WindowsAppPath = "c:\\program files\\windowsapps";
+ private static readonly string WindowsAppPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsApps");
static Main()
{
From 5fc8ed1824d55b48e9b2db056688afd490f99e0f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 11:11:44 +0800
Subject: [PATCH 137/200] Remove useless settings control & project reference
---
.../Flow.Launcher.Plugin.Url.csproj | 1 -
Plugins/Flow.Launcher.Plugin.Url/Main.cs | 10 +---------
.../SettingsControl.xaml | 17 -----------------
.../SettingsControl.xaml.cs | 18 ------------------
4 files changed, 1 insertion(+), 45 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
index 3db0cd0cb..6d338733e 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
@@ -42,7 +42,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Main.cs b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
index 80425a8ff..03516636d 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
-using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Url
{
- public class Main : ISettingProvider,IPlugin, IPluginI18n
+ public class Main : IPlugin, IPluginI18n
{
//based on https://gist.github.com/dperini/729294
private const string urlPattern = "^" +
@@ -43,7 +42,6 @@ namespace Flow.Launcher.Plugin.Url
Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
private PluginInitContext context;
private Settings _settings;
-
public List Query(Query query)
{
@@ -82,12 +80,6 @@ namespace Flow.Launcher.Plugin.Url
return new List(0);
}
-
- public Control CreateSettingPanel()
- {
- return new SettingsControl(context.API,_settings);
- }
-
public bool IsURL(string raw)
{
raw = raw.ToLower();
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
deleted file mode 100644
index 8ff7b5ab5..000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
deleted file mode 100644
index f68d1bb2d..000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Windows.Controls;
-
-namespace Flow.Launcher.Plugin.Url
-{
- public partial class SettingsControl : UserControl
- {
- private Settings _settings;
- private IPublicAPI _flowlauncherAPI;
-
- public SettingsControl(IPublicAPI flowlauncherAPI,Settings settings)
- {
- InitializeComponent();
- _settings = settings;
- _flowlauncherAPI = flowlauncherAPI;
-
- }
- }
-}
From c472239ea9e2e8a814ed85330d4a66308a9bf956 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 11:20:00 +0800
Subject: [PATCH 138/200] Fix unneccessary black lines when settings control is
null
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 50eb30998..2a4b22bf3 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -112,7 +112,7 @@ namespace Flow.Launcher.Core.Plugin
public Control CreateSettingPanel()
{
if (Settings == null || Settings.Count == 0)
- return new();
+ return null;
var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 4ce8bd470..a46b98d64 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -90,7 +90,7 @@ namespace Flow.Launcher.ViewModel
private Control _bottomPart2;
public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginDisplayBottomData() : null;
- public bool HasSettingControl => PluginPair.Plugin is ISettingProvider;
+ public bool HasSettingControl => PluginPair.Plugin is ISettingProvider settingProvider && settingProvider.CreateSettingPanel() != null;
public Control SettingControl
=> IsExpanded
? _settingControl
From 54a49d68f3a7f6ea6488b47d0e5ed83edab67d44 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 21 Feb 2025 20:55:32 +1100
Subject: [PATCH 139/200] Enable the use of Win hotkey to trigger flow (#3262)
---
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/Helper/HotKeyMapper.cs | 39 +++++++++++++++++++++++
Flow.Launcher/HotkeyControl.xaml.cs | 11 ++++++-
Flow.Launcher/HotkeyControlDialog.xaml.cs | 29 +++++++++++++++--
4 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 16228258f..2f26017a6 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -83,6 +83,7 @@
+
all
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 8b30b8be1..64434b49c 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -6,6 +6,8 @@ using NHotkey.Wpf;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
+using ChefKeys;
+using System.Globalization;
namespace Flow.Launcher.Helper;
@@ -29,15 +31,40 @@ internal static class HotKeyMapper
_mainViewModel.ToggleFlowLauncher();
}
+ internal static void OnToggleHotkeyWithChefKeys()
+ {
+ if (!_mainViewModel.ShouldIgnoreHotkeys())
+ _mainViewModel.ToggleFlowLauncher();
+ }
+
private static void SetHotkey(string hotkeyStr, EventHandler action)
{
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ SetWithChefKeys(hotkeyStr);
+ return;
+ }
+
var hotkey = new HotkeyModel(hotkeyStr);
SetHotkey(hotkey, action);
}
+ private static void SetWithChefKeys(string hotkeyStr)
+ {
+ ChefKeysManager.RegisterHotkey(hotkeyStr, hotkeyStr, OnToggleHotkeyWithChefKeys);
+ ChefKeysManager.Start();
+ }
+
internal static void SetHotkey(HotkeyModel hotkey, EventHandler action)
{
string hotkeyStr = hotkey.ToString();
+
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ SetWithChefKeys(hotkeyStr);
+ return;
+ }
+
try
{
HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action);
@@ -52,12 +79,24 @@ internal static class HotKeyMapper
internal static void RemoveHotkey(string hotkeyStr)
{
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ RemoveWithChefKeys(hotkeyStr);
+ return;
+ }
+
if (!string.IsNullOrEmpty(hotkeyStr))
{
HotkeyManager.Current.Remove(hotkeyStr);
}
}
+ private static void RemoveWithChefKeys(string hotkeyStr)
+ {
+ ChefKeysManager.UnregisterHotkey(hotkeyStr);
+ ChefKeysManager.Stop();
+ }
+
internal static void LoadCustomPluginHotkey()
{
if (_settings.CustomPluginHotkeys == null)
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index a42bde7c9..e1dfc1108 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -154,7 +154,16 @@ namespace Flow.Launcher
{
if (triggerValidate)
{
- bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
+ bool hotkeyAvailable = false;
+ // TODO: This is a temporary way to enforce changing only the open flow hotkey to Win, and will be removed by PR #3157
+ if (keyModel.ToString() == "LWin" || keyModel.ToString() == "RWin")
+ {
+ hotkeyAvailable = true;
+ }
+ else
+ {
+ hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
+ }
if (!hotkeyAvailable)
{
diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs
index a7b99f670..a4d21a782 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -3,6 +3,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
+using ChefKeys;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
@@ -33,6 +34,8 @@ public partial class HotkeyControlDialog : ContentDialog
public string ResultValue { get; private set; } = string.Empty;
public static string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
+ private static bool isOpenFlowHotkey;
+
public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings hotkeySettings, string windowTitle = "")
{
WindowTitle = windowTitle switch
@@ -46,6 +49,14 @@ public partial class HotkeyControlDialog : ContentDialog
SetKeysToDisplay(CurrentHotkey);
InitializeComponent();
+
+ // TODO: This is a temporary way to enforce changing only the open flow hotkey to Win, and will be removed by PR #3157
+ isOpenFlowHotkey = _hotkeySettings.RegisteredHotkeys
+ .Any(x => x.DescriptionResourceKey == "flowlauncherHotkey"
+ && x.Hotkey.ToString() == hotkey);
+
+ ChefKeysManager.StartMenuEnableBlocking = true;
+ ChefKeysManager.Start();
}
private void Reset(object sender, RoutedEventArgs routedEventArgs)
@@ -61,12 +72,18 @@ public partial class HotkeyControlDialog : ContentDialog
private void Cancel(object sender, RoutedEventArgs routedEventArgs)
{
+ ChefKeysManager.StartMenuEnableBlocking = false;
+ ChefKeysManager.Stop();
+
ResultType = EResultType.Cancel;
Hide();
}
private void Save(object sender, RoutedEventArgs routedEventArgs)
{
+ ChefKeysManager.StartMenuEnableBlocking = false;
+ ChefKeysManager.Stop();
+
if (KeysToDisplay.Count == 1 && KeysToDisplay[0] == EmptyHotkey)
{
ResultType = EResultType.Delete;
@@ -85,6 +102,9 @@ public partial class HotkeyControlDialog : ContentDialog
//when alt is pressed, the real key should be e.SystemKey
Key key = e.Key == Key.System ? e.SystemKey : e.Key;
+ if (ChefKeysManager.StartMenuBlocked && key.ToString() == ChefKeysManager.StartMenuSimulatedKey)
+ return;
+
SpecialKeyState specialKeyState = GlobalHotkey.CheckModifiers();
var hotkeyModel = new HotkeyModel(
@@ -168,8 +188,13 @@ public partial class HotkeyControlDialog : ContentDialog
}
}
- private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
- hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
+ private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture)
+ {
+ if (isOpenFlowHotkey && (hotkey.ToString() == "LWin" || hotkey.ToString() == "RWin"))
+ return true;
+
+ return hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
+ }
private void Overwrite(object sender, RoutedEventArgs e)
{
From 41733615fd75cd35bf3933a90e92b93ae217e09a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 20:45:42 +0800
Subject: [PATCH 140/200] Improve code quality
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 5 +----
Flow.Launcher/CustomShortcutSetting.xaml | 5 +----
Flow.Launcher/PriorityChangeWindow.xaml | 5 +----
Flow.Launcher/SelectBrowserWindow.xaml | 5 +----
Flow.Launcher/SelectFileManagerWindow.xaml | 5 +----
Flow.Launcher/WelcomeWindow.xaml | 5 +----
6 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 068afda15..70ebb404b 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -32,14 +32,11 @@
-
-
-
-
-
+
+
+
all
From 928ca474ab25934f4872412254d51bc0144a1dad Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 25 Feb 2025 13:48:02 +0800
Subject: [PATCH 172/200] Add preview background in welcome page 2
---
.../Resources/Pages/WelcomePage2.xaml.cs | 27 +++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 7dfb85a83..004e4d6d2 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -2,11 +2,12 @@
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using System;
-using System.Windows;
-using System.Windows.Media;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
+using System.IO;
+using System.Windows.Media.Imaging;
+using System.Windows.Media;
namespace Flow.Launcher.Resources.Pages
{
@@ -29,5 +30,27 @@ namespace Flow.Launcher.Resources.Pages
{
HotKeyMapper.SetHotkey(hotkey, HotKeyMapper.OnToggleHotkey);
}
+
+ public Brush PreviewBackground
+ {
+ get
+ {
+ var wallpaper = WallpaperPathRetrieval.GetWallpaperPath();
+ if (wallpaper is not null && File.Exists(wallpaper))
+ {
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = memStream;
+ bitmap.DecodePixelWidth = 800;
+ bitmap.DecodePixelHeight = 600;
+ bitmap.EndInit();
+ return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ }
+
+ var wallpaperColor = WallpaperPathRetrieval.GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+ }
}
}
From fe48427252f5ce8c84e697da42a24406d9675a3f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 25 Feb 2025 15:08:27 +0800
Subject: [PATCH 173/200] Log error for logon task
---
Flow.Launcher/Helper/AutoStartup.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 936951ee9..c5e20504b 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -59,9 +59,9 @@ public class AutoStartup
return true;
}
- catch (Exception)
+ catch (Exception e)
{
- Log.Error("AutoStartup", "Failed to check logon task");
+ Log.Error("AutoStartup", $"Failed to check logon task: {e}");
}
}
@@ -159,9 +159,9 @@ public class AutoStartup
TaskService.Instance.RootFolder.RegisterTaskDefinition(LogonTaskName, td);
return true;
}
- catch (Exception)
+ catch (Exception e)
{
- Log.Error("AutoStartup", "Failed to schedule logon task");
+ Log.Error("AutoStartup", $"Failed to schedule logon task: {e}");
return false;
}
}
@@ -174,9 +174,9 @@ public class AutoStartup
taskService.RootFolder.DeleteTask(LogonTaskName);
return true;
}
- catch (Exception)
+ catch (Exception e)
{
- Log.Error("AutoStartup", "Failed to unschedule logon task");
+ Log.Error("AutoStartup", $"Failed to unschedule logon task: {e}");
return false;
}
}
From 1a6733e86d0c1eb772c6f5eec4542435373bc42f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 25 Feb 2025 18:06:23 +0800
Subject: [PATCH 174/200] Improve background wallpaper fetch
---
.../Helper/WallpaperPathRetrieval.cs | 42 +++++++++++++++++--
.../Resources/Pages/WelcomePage2.xaml.cs | 21 +---------
.../ViewModels/SettingsPaneThemeViewModel.cs | 21 +---------
3 files changed, 40 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 8a42d480f..f79fea288 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -1,9 +1,10 @@
using System;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Text;
-using System.Windows.Documents;
using System.Windows.Media;
+using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;
@@ -14,7 +15,40 @@ public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
- public static unsafe string GetWallpaperPath()
+ private static readonly Dictionary wallpaperCache = new();
+
+ public static Brush GetWallpaperBrush()
+ {
+ var wallpaper = GetWallpaperPath();
+ if (wallpaper is not null && File.Exists(wallpaper))
+ {
+ // Since the wallpaper file name is the same (TranscodedWallpaper),
+ // we need to use the last modified date to differentiate them
+ var dateModified = File.GetLastWriteTime(wallpaper);
+ wallpaperCache.TryGetValue(dateModified, out var cachedWallpaper);
+ if (cachedWallpaper != null)
+ {
+ return new ImageBrush(cachedWallpaper) { Stretch = Stretch.UniformToFill };
+ }
+
+ // We should not dispose the memory stream since the bitmap is still in use
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = memStream;
+ bitmap.DecodePixelWidth = 800;
+ bitmap.DecodePixelHeight = 600;
+ bitmap.EndInit();
+ bitmap.Freeze(); // Make the bitmap thread-safe
+ wallpaperCache[dateModified] = bitmap;
+ return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ }
+
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+
+ private static unsafe string GetWallpaperPath()
{
var wallpaperPtr = stackalloc char[MAX_PATH];
PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH,
@@ -25,7 +59,7 @@ public static class WallpaperPathRetrieval
return wallpaper.ToString();
}
- public static Color GetWallpaperColor()
+ private static Color GetWallpaperColor()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", true);
var result = key?.GetValue("Background", null);
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 004e4d6d2..1ed5747cd 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -5,8 +5,6 @@ using System;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
-using System.IO;
-using System.Windows.Media.Imaging;
using System.Windows.Media;
namespace Flow.Launcher.Resources.Pages
@@ -33,24 +31,7 @@ namespace Flow.Launcher.Resources.Pages
public Brush PreviewBackground
{
- get
- {
- var wallpaper = WallpaperPathRetrieval.GetWallpaperPath();
- if (wallpaper is not null && File.Exists(wallpaper))
- {
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.DecodePixelWidth = 800;
- bitmap.DecodePixelHeight = 600;
- bitmap.EndInit();
- return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
- }
-
- var wallpaperColor = WallpaperPathRetrieval.GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
- }
+ get => WallpaperPathRetrieval.GetWallpaperBrush();
}
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 980b2a811..ed933678d 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -5,7 +5,6 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Media;
-using System.Windows.Media.Imaging;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@@ -14,7 +13,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using ModernWpf;
-using Flow.Launcher.Core;
using ThemeManager = Flow.Launcher.Core.Resource.ThemeManager;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
@@ -212,24 +210,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
public Brush PreviewBackground
{
- get
- {
- var wallpaper = WallpaperPathRetrieval.GetWallpaperPath();
- if (wallpaper is not null && File.Exists(wallpaper))
- {
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.DecodePixelWidth = 800;
- bitmap.DecodePixelHeight = 600;
- bitmap.EndInit();
- return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
- }
-
- var wallpaperColor = WallpaperPathRetrieval.GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
- }
+ get => WallpaperPathRetrieval.GetWallpaperBrush();
}
public ResultsViewModel PreviewResults
From ff45f5f7f5215dc30de11333ff6c42b1aeb7b554 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 25 Feb 2025 18:14:42 +0800
Subject: [PATCH 175/200] Cache image brush & Invoke on UI thread
---
Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index f79fea288..7c74552be 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
@@ -15,10 +16,16 @@ public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
- private static readonly Dictionary wallpaperCache = new();
+ private static readonly Dictionary wallpaperCache = new();
public static Brush GetWallpaperBrush()
{
+ // Invoke the method on the UI thread
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
+ }
+
var wallpaper = GetWallpaperPath();
if (wallpaper is not null && File.Exists(wallpaper))
{
@@ -28,7 +35,7 @@ public static class WallpaperPathRetrieval
wallpaperCache.TryGetValue(dateModified, out var cachedWallpaper);
if (cachedWallpaper != null)
{
- return new ImageBrush(cachedWallpaper) { Stretch = Stretch.UniformToFill };
+ return cachedWallpaper;
}
// We should not dispose the memory stream since the bitmap is still in use
@@ -40,8 +47,10 @@ public static class WallpaperPathRetrieval
bitmap.DecodePixelHeight = 600;
bitmap.EndInit();
bitmap.Freeze(); // Make the bitmap thread-safe
- wallpaperCache[dateModified] = bitmap;
- return new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ wallpaperBrush.Freeze(); // Make the brush thread-safe
+ wallpaperCache.Add(dateModified, wallpaperBrush);
+ return wallpaperBrush;
}
var wallpaperColor = GetWallpaperColor();
From 0fddb84735638940a9f3041a38800fd3e6de2c15 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 25 Feb 2025 19:41:41 +0800
Subject: [PATCH 176/200] Add wallpaper path in cache dictionary
---
Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 7c74552be..9f66a270c 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -16,7 +16,7 @@ public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
- private static readonly Dictionary wallpaperCache = new();
+ private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
public static Brush GetWallpaperBrush()
{
@@ -26,20 +26,20 @@ public static class WallpaperPathRetrieval
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}
- var wallpaper = GetWallpaperPath();
- if (wallpaper is not null && File.Exists(wallpaper))
+ var wallpaperPath = GetWallpaperPath();
+ if (wallpaperPath is not null && File.Exists(wallpaperPath))
{
- // Since the wallpaper file name is the same (TranscodedWallpaper),
- // we need to use the last modified date to differentiate them
- var dateModified = File.GetLastWriteTime(wallpaper);
- wallpaperCache.TryGetValue(dateModified, out var cachedWallpaper);
+ // Since the wallpaper file name can be the same (TranscodedWallpaper),
+ // we need to add the last modified date to differentiate them
+ var dateModified = File.GetLastWriteTime(wallpaperPath);
+ wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
if (cachedWallpaper != null)
{
return cachedWallpaper;
}
// We should not dispose the memory stream since the bitmap is still in use
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaper));
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = memStream;
@@ -49,7 +49,7 @@ public static class WallpaperPathRetrieval
bitmap.Freeze(); // Make the bitmap thread-safe
var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
wallpaperBrush.Freeze(); // Make the brush thread-safe
- wallpaperCache.Add(dateModified, wallpaperBrush);
+ wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
return wallpaperBrush;
}
From bf8f5d1e60463d41738860bdc293803396316570 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 15:26:20 +0800
Subject: [PATCH 177/200] Downgrade dependency injection version
---
Flow.Launcher/Flow.Launcher.csproj | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index f8ace91f8..6c2378f78 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -91,8 +91,8 @@
-
-
+
+
all
From 397c6ee639679c078c12db751178159c8a2988f3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 15:32:59 +0800
Subject: [PATCH 178/200] Add message box to show exception
---
Flow.Launcher/App.xaml.cs | 81 +++++++++++++++++++++---------
Flow.Launcher/Flow.Launcher.csproj | 1 +
2 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 8374fc9fe..277e5dc0c 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -35,31 +35,64 @@ namespace Flow.Launcher
public App()
{
// Initialize settings
- var storage = new FlowLauncherJsonStorage();
- _settings = storage.Load();
- _settings.SetStorage(storage);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+ try
+ {
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.SetStorage(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+ }
+ catch (Exception e)
+ {
+ ShowErrorMsgBoxAndFailFast("Cannot load setting storage, please check local data directory", e);
+ return;
+ }
// Configure the dependency injection container
- var host = Host.CreateDefaultBuilder()
- .UseContentRoot(AppContext.BaseDirectory)
- .ConfigureServices(services => services
- .AddSingleton(_ => _settings)
- .AddSingleton(sp => new Updater(sp.GetRequiredService(), Launcher.Properties.Settings.Default.GithubRepo))
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- ).Build();
- Ioc.Default.ConfigureServices(host.Services);
+ try
+ {
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton(sp => new Updater(sp.GetRequiredService(), Launcher.Properties.Settings.Default.GithubRepo))
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
+ }
+ catch (Exception e)
+ {
+ ShowErrorMsgBoxAndFailFast("Cannot configure dependency injection container, please open new issue in Flow.Launcher", e);
+ return;
+ }
// Initialize the public API and Settings first
- API = Ioc.Default.GetRequiredService();
- _settings.Initialize();
+ try
+ {
+ API = Ioc.Default.GetRequiredService();
+ _settings.Initialize();
+ }
+ catch (Exception e)
+ {
+ ShowErrorMsgBoxAndFailFast("Cannot initialize api and settings, please open new issue in Flow.Launcher", e);
+ return;
+ }
+ }
+
+ private static void ShowErrorMsgBoxAndFailFast(string message, Exception e)
+ {
+ // Firstly show users the message
+ MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error);
+
+ // Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info.
+ Environment.FailFast(message, e);
}
[STAThread]
@@ -132,17 +165,17 @@ namespace Flow.Launcher
{
// we try to enable auto-startup on first launch, or reenable if it was removed
// but the user still has the setting set
- if (_settings.StartFlowLauncherOnSystemStartup && !Helper.AutoStartup.IsEnabled)
+ if (_settings.StartFlowLauncherOnSystemStartup && !Infrastructure.AutoStartup.IsEnabled)
{
try
{
if (_settings.UseLogonTaskForStartup)
{
- Helper.AutoStartup.EnableViaLogonTask();
+ Infrastructure.AutoStartup.EnableViaLogonTask();
}
else
{
- Helper.AutoStartup.EnableViaRegistry();
+ Infrastructure.AutoStartup.EnableViaRegistry();
}
}
catch (Exception e)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index f2be60f7a..c2e515844 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -91,6 +91,7 @@
+
From 7cc32f3021549c39eb0943a8c1cc7c6908885f71 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 15:40:18 +0800
Subject: [PATCH 179/200] Fix build issue
---
Flow.Launcher/App.xaml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 277e5dc0c..447eca792 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -165,17 +165,17 @@ namespace Flow.Launcher
{
// we try to enable auto-startup on first launch, or reenable if it was removed
// but the user still has the setting set
- if (_settings.StartFlowLauncherOnSystemStartup && !Infrastructure.AutoStartup.IsEnabled)
+ if (_settings.StartFlowLauncherOnSystemStartup && !Helper.AutoStartup.IsEnabled)
{
try
{
if (_settings.UseLogonTaskForStartup)
{
- Infrastructure.AutoStartup.EnableViaLogonTask();
+ Helper.AutoStartup.EnableViaLogonTask();
}
else
{
- Infrastructure.AutoStartup.EnableViaRegistry();
+ Helper.AutoStartup.EnableViaRegistry();
}
}
catch (Exception e)
From 3fa88064bd572741c8590ce7a1064fb65324b65a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 18:30:33 +0800
Subject: [PATCH 180/200] Remove useless localization
---
Flow.Launcher/Languages/en.xaml | 3 ---
Flow.Launcher/ReportWindow.xaml.cs | 33 +++++-------------------------
2 files changed, 5 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 493528a89..5d2cb2d9e 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -386,9 +386,6 @@
Please open new issue in
1. Upload log file: {0}
2. Copy below exception message
- Date: {0}
- Exception:
- Length
Please wait...
diff --git a/Flow.Launcher/ReportWindow.xaml.cs b/Flow.Launcher/ReportWindow.xaml.cs
index 12ffe3ffc..6fe90783e 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -6,10 +6,10 @@ using System.Text;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
+using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
-using Flow.Launcher.Infrastructure.Exception;
namespace Flow.Launcher
{
@@ -55,12 +55,11 @@ namespace Flow.Launcher
ErrorTextbox.Document.Blocks.Add(paragraph);
StringBuilder content = new StringBuilder();
- content.AppendLine(RuntimeInfo());
+ content.AppendLine(ErrorReporting.RuntimeInfo());
+ content.AppendLine(ErrorReporting.DependenciesInfo());
content.AppendLine();
- content.AppendLine(DependenciesInfo());
- content.AppendLine();
- content.AppendLine(string.Format(App.API.GetTranslation("reportWindow_date"), DateTime.Now.ToString(CultureInfo.InvariantCulture)));
- content.AppendLine(App.API.GetTranslation("reportWindow_exception"));
+ content.AppendLine($"Date: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}");
+ content.AppendLine("Exception:");
content.AppendLine(exception.ToString());
paragraph = new Paragraph();
paragraph.Inlines.Add(content.ToString());
@@ -94,27 +93,5 @@ namespace Flow.Launcher
{
Close();
}
-
- private static string RuntimeInfo()
- {
- var info =
- $"""
- Flow Launcher {App.API.GetTranslation("reportWindow_version")}: {Constant.Version}
- OS {App.API.GetTranslation("reportWindow_version")}: {ExceptionFormatter.GetWindowsFullVersionFromRegistry()}
- IntPtr {App.API.GetTranslation("reportWindow_length")}: {IntPtr.Size}
- x64: {Environment.Is64BitOperatingSystem}
- """;
- return info;
- }
-
- private static string DependenciesInfo()
- {
- var info =
- $"""
- {App.API.GetTranslation("pythonFilePath")}: {Constant.PythonPath}
- {App.API.GetTranslation("nodeFilePath")}: {Constant.NodePath}
- """;
- return info;
- }
}
}
From ed5e0bb2d9a8c908f301d794ce2f4bcda8d2b8ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 20:11:27 +0800
Subject: [PATCH 181/200] Improve documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 11 +++++------
Flow.Launcher/ProgressBoxEx.xaml.cs | 14 +++++++-------
Flow.Launcher/PublicAPIInstance.cs | 2 +-
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 8376fd07b..ef22b697e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,17 +322,16 @@ namespace Flow.Launcher.Plugin
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK);
///
- /// Displays a standardised Flow message box.
- /// If there is issue when showing the message box, it will return null.
+ /// Displays a standardised Flow progress box.
///
- /// The caption of the message box.
+ /// The caption of the progress box.
///
/// Time-consuming task function, whose input is the action to report progress.
/// The input of the action is the progress value which is a double value between 0 and 100.
/// If there are any exceptions, this action will be null.
///
- /// When user closes the progress box manually by button or esc key, this action will be called.
- /// A progress box interface.
- public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
+ /// When user cancel the progress, this action will be called.
+ ///
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 755fc4a1f..2395bdf34 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -8,15 +8,15 @@ namespace Flow.Launcher
{
public partial class ProgressBoxEx : Window
{
- private readonly Action _forceClosed;
+ private readonly Action _cancelProgress;
- private ProgressBoxEx(Action forceClosed)
+ private ProgressBoxEx(Action cancelProgress)
{
- _forceClosed = forceClosed;
+ _cancelProgress = cancelProgress;
InitializeComponent();
}
- public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null)
+ public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null)
{
ProgressBoxEx prgBox = null;
try
@@ -25,7 +25,7 @@ namespace Flow.Launcher
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -35,7 +35,7 @@ namespace Flow.Launcher
}
else
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -113,7 +113,7 @@ namespace Flow.Launcher
private void ForceClose()
{
Close();
- _forceClosed?.Invoke();
+ _cancelProgress?.Invoke();
}
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7706a64ba..848d7f14c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ namespace Flow.Launcher
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
#endregion
From fb9980e90a87add97d37d6a48bdf276e171e094c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 10:39:57 +0800
Subject: [PATCH 182/200] Upgrade nuget packages
---
Flow.Launcher/Flow.Launcher.csproj | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index c2e515844..cc43bd2ac 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -91,9 +91,8 @@
-
-
-
+
+
all
@@ -105,7 +104,7 @@
-
+
From a153bb6baef1fe0a5c9ab5e4bfe25ed771ceed44 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 12:38:45 +0800
Subject: [PATCH 183/200] Test Jack251970.TaskScheduler package
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index cc43bd2ac..d77847bef 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From 406b1961b2b837512bec4ce74c0cc7ea4b07e7ea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 13:25:21 +0800
Subject: [PATCH 184/200] Test updated Jack251970.TaskScheduler package
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index d77847bef..33d13614f 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From 5c48acad8922d9367bce917246a5de5d067e98ea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 11:26:14 +0800
Subject: [PATCH 185/200] Add loading api functions for all plugins
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 10 ++++++++++
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 10 ++++++++++
2 files changed, 20 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index e0a0434a2..8df2ce9ed 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -175,5 +175,15 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
{
_api.BackToQueryResults();
}
+
+ public void StartLoadingBar()
+ {
+ _api.StartLoadingBar();
+ }
+
+ public void StopLoadingBar()
+ {
+ _api.StopLoadingBar();
+ }
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 07fc378c3..fd96c82c4 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -335,5 +335,15 @@ namespace Flow.Launcher.Plugin
/// When user closes the progress box manually by button or esc key, this action will be called.
/// A progress box interface.
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
+
+ ///
+ /// Start the loading bar in main window
+ ///
+ public void StartLoadingBar();
+
+ ///
+ /// Stop the loading bar in main window
+ ///
+ public void StopLoadingBar();
}
}
From 9dbc174994e77124c2b42b2864ab6ab1f4d8ab10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 15:34:59 +0800
Subject: [PATCH 186/200] Add cache size management & Add error handling
---
.../Helper/WallpaperPathRetrieval.cs | 69 ++++++++++++-------
1 file changed, 45 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 9f66a270c..eedc78eca 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -17,6 +17,7 @@ public static class WallpaperPathRetrieval
private static readonly int MAX_PATH = 260;
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
+ private const int MaxCacheSize = 3;
public static Brush GetWallpaperBrush()
{
@@ -26,35 +27,55 @@ public static class WallpaperPathRetrieval
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}
- var wallpaperPath = GetWallpaperPath();
- if (wallpaperPath is not null && File.Exists(wallpaperPath))
+ try
{
- // Since the wallpaper file name can be the same (TranscodedWallpaper),
- // we need to add the last modified date to differentiate them
- var dateModified = File.GetLastWriteTime(wallpaperPath);
- wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
- if (cachedWallpaper != null)
+ var wallpaperPath = GetWallpaperPath();
+ if (wallpaperPath is not null && File.Exists(wallpaperPath))
{
- return cachedWallpaper;
+ // Since the wallpaper file name can be the same (TranscodedWallpaper),
+ // we need to add the last modified date to differentiate them
+ var dateModified = File.GetLastWriteTime(wallpaperPath);
+ wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
+ if (cachedWallpaper != null)
+ {
+ return cachedWallpaper;
+ }
+
+ // We should not dispose the memory stream since the bitmap is still in use
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = memStream;
+ bitmap.DecodePixelWidth = 800;
+ bitmap.DecodePixelHeight = 600;
+ bitmap.EndInit();
+ bitmap.Freeze(); // Make the bitmap thread-safe
+ var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ wallpaperBrush.Freeze(); // Make the brush thread-safe
+
+ // Manage cache size
+ if (wallpaperCache.Count >= MaxCacheSize)
+ {
+ // Remove the oldest wallpaper from the cache
+ var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
+ if (oldestCache != default)
+ {
+ wallpaperCache.Remove(oldestCache);
+ }
+ }
+
+ wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ return wallpaperBrush;
}
- // We should not dispose the memory stream since the bitmap is still in use
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.DecodePixelWidth = 800;
- bitmap.DecodePixelHeight = 600;
- bitmap.EndInit();
- bitmap.Freeze(); // Make the bitmap thread-safe
- var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
- wallpaperBrush.Freeze(); // Make the brush thread-safe
- wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
- return wallpaperBrush;
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+ catch (Exception ex)
+ {
+ App.API.LogException(nameof(WallpaperPathRetrieval), "Error retrieving wallpaper", ex);
+ return new SolidColorBrush(Colors.Transparent);
}
-
- var wallpaperColor = GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
}
private static unsafe string GetWallpaperPath()
From c06042f96bee6f65fe1b4b761643a2e2bd495978 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 17:03:53 +0800
Subject: [PATCH 187/200] Fix API instance create twice issue & Make
PluginManager.API private
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 4 +++-
Flow.Launcher/MainWindow.xaml.cs | 2 +-
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 5 ++---
.../SettingPages/Views/SettingsPanePluginStore.xaml.cs | 3 +--
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 8 ++++----
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 6e7b5ec60..09711051e 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -29,7 +29,9 @@ namespace Flow.Launcher.Core.Plugin
public static readonly HashSet GlobalPlugins = new();
public static readonly Dictionary NonGlobalPlugins = new();
- public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService();
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
private static PluginsSettings Settings;
private static List _metadatas;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 41dc68fd9..3f1bae090 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -438,7 +438,7 @@ namespace Flow.Launcher
if (_settings.FirstLaunch)
{
_settings.FirstLaunch = false;
- PluginManager.API.SaveAppAllSettings();
+ App.API.SaveAppAllSettings();
OpenWelcomeWindow();
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index cb434f399..ade650284 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
-using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -77,7 +76,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[RelayCommand]
private void OpenSettingsFolder()
{
- PluginManager.API.OpenDirectory(Path.Combine(DataLocation.DataDirectory(), Constant.Settings));
+ App.API.OpenDirectory(Path.Combine(DataLocation.DataDirectory(), Constant.Settings));
}
[RelayCommand]
@@ -85,7 +84,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
{
string settingsFolderPath = Path.Combine(DataLocation.DataDirectory(), Constant.Settings);
string parentFolderPath = Path.GetDirectoryName(settingsFolderPath);
- PluginManager.API.OpenDirectory(parentFolderPath);
+ App.API.OpenDirectory(parentFolderPath);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index dfb4a7eaf..db4763319 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -3,7 +3,6 @@ using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
-using Flow.Launcher.Core.Plugin;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
@@ -49,7 +48,7 @@ public partial class SettingsPanePluginStore
private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
- PluginManager.API.OpenUrl(e.Uri.AbsoluteUri);
+ App.API.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 650a27610..6b0144a03 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -442,7 +442,7 @@ namespace Flow.Launcher.ViewModel
[RelayCommand]
private void SelectHelp()
{
- PluginManager.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
+ App.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
}
[RelayCommand]
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index bae9292bf..46f8e00a2 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -134,20 +134,20 @@ namespace Flow.Launcher.ViewModel
{
var directory = PluginPair.Metadata.PluginDirectory;
if (!string.IsNullOrEmpty(directory))
- PluginManager.API.OpenDirectory(directory);
+ App.API.OpenDirectory(directory);
}
[RelayCommand]
private void OpenSourceCodeLink()
{
- PluginManager.API.OpenUrl(PluginPair.Metadata.Website);
+ App.API.OpenUrl(PluginPair.Metadata.Website);
}
[RelayCommand]
private void OpenDeletePluginWindow()
{
- PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
- PluginManager.API.ShowMainWindow();
+ App.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
+ App.API.ShowMainWindow();
}
public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
From d8c547f7ef3a640b613778713508a9b111c90ab6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 18:10:58 +0800
Subject: [PATCH 188/200] Improve code quality
---
Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index eedc78eca..a3bd83a97 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -15,9 +15,9 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
+ private static readonly int MAX_CACHE_SIZE = 3;
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
- private const int MaxCacheSize = 3;
public static Brush GetWallpaperBrush()
{
@@ -54,7 +54,7 @@ public static class WallpaperPathRetrieval
wallpaperBrush.Freeze(); // Make the brush thread-safe
// Manage cache size
- if (wallpaperCache.Count >= MaxCacheSize)
+ if (wallpaperCache.Count >= MAX_CACHE_SIZE)
{
// Remove the oldest wallpaper from the cache
var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
From 4e4758677f2b533fb6ed107f948ff7d7a1ab2570 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 19:21:09 +0800
Subject: [PATCH 189/200] Remove unneccessary CreateSettingPanel by introducing
need check
---
Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 7 ++++++-
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 9 +++++++--
Flow.Launcher/ViewModel/PluginViewModel.cs | 8 ++++----
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
index ed8f94bcf..7248c6259 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
@@ -34,7 +34,7 @@ namespace Flow.Launcher.Core.Plugin
/// Represent the plugin that using JsonPRC
/// every JsonRPC plugin should has its own plugin instance
///
- internal abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable
+ public abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable
{
protected PluginInitContext Context;
public const string JsonRPC = "JsonRPC";
@@ -157,6 +157,11 @@ namespace Flow.Launcher.Core.Plugin
Settings?.Save();
}
+ public bool NeedCreateSettingPanel()
+ {
+ return Settings.NeedCreateSettingPanel();
+ }
+
public Control CreateSettingPanel()
{
return Settings.CreateSettingPanel();
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 2a4b22bf3..8412ba7e8 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -109,10 +109,15 @@ namespace Flow.Launcher.Core.Plugin
_storage.Save();
}
+ public bool NeedCreateSettingPanel()
+ {
+ // If there are no settings or the settings configuration is empty, return null
+ return Settings != null && Configuration != null && Configuration.Body.Count != 0;
+ }
+
public Control CreateSettingPanel()
{
- if (Settings == null || Settings.Count == 0)
- return null;
+ // No need to check if NeedCreateSettingPanel is true because CreateSettingPanel will only be called if it's true
var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 46f8e00a2..209a81395 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -90,13 +90,13 @@ namespace Flow.Launcher.ViewModel
private Control _bottomPart2;
public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginDisplayBottomData() : null;
- public bool HasSettingControl => PluginPair.Plugin is ISettingProvider settingProvider && settingProvider.CreateSettingPanel() != null;
+ public bool HasSettingControl => PluginPair.Plugin is ISettingProvider && (PluginPair.Plugin is not JsonRPCPluginBase jsonRPCPluginBase || jsonRPCPluginBase.NeedCreateSettingPanel());
public Control SettingControl
=> IsExpanded
? _settingControl
- ??= PluginPair.Plugin is not ISettingProvider settingProvider
- ? null
- : settingProvider.CreateSettingPanel()
+ ??= HasSettingControl
+ ? ((ISettingProvider)PluginPair.Plugin).CreateSettingPanel()
+ : null
: null;
private ImageSource _image = ImageLoader.MissingImage;
From 889f4cbfeb4959477c3c3db8bdaf66c527cb902e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 4 Mar 2025 11:08:09 +0800
Subject: [PATCH 190/200] Fix null reference exception when checking source
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f4c8a66da..4ceadec56 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -593,7 +593,10 @@ namespace Flow.Launcher.Plugin.PluginsManager
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
return url.StartsWith(acceptedSource) &&
- Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
+ Context.API.GetAllPlugins().Any(x =>
+ !string.IsNullOrEmpty(x.Metadata.Website) &&
+ x.Metadata.Website.StartsWith(constructedUrlPart)
+ );
}
internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
From 719d30ebf0a09e54a46948a786caa6069303ca0e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 6 Mar 2025 07:41:22 +0800
Subject: [PATCH 191/200] Use official Task Scheduler
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 33d13614f..8f6e47bbb 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From 69b7aeadeb09cebd6e576c4817e01fe324522af4 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 6 Mar 2025 20:07:01 +0800
Subject: [PATCH 192/200] Update dependabot.yml
---
.github/dependabot.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d9b39eb89..da4231f74 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -8,7 +8,8 @@ updates:
- package-ecosystem: "nuget" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
- interval: "weekly"
+ interval: "daily"
+ open-pull-requests-limit: 3
ignore:
- dependency-name: "squirrel-windows"
reviewers:
From f2c30347a762f3a29b176d6730081be3d64e3e14 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Sat, 8 Mar 2025 12:24:47 +0600
Subject: [PATCH 193/200] Add new sponsor to README
---
README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 02ffc7932..6611f55dc 100644
--- a/README.md
+++ b/README.md
@@ -334,11 +334,14 @@ Or download the [early access version](https://github.com/Flow-Launcher/Prerelea
-
-
+
+
+
+
+
From 8ca734ae065813062c119f78b8b8f2fb2d99f211 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 9 Mar 2025 03:18:48 +0000
Subject: [PATCH 194/200] Bump FSharp.Core from 9.0.101 to 9.0.201
Bumps [FSharp.Core](https://github.com/dotnet/fsharp) from 9.0.101 to 9.0.201.
- [Release notes](https://github.com/dotnet/fsharp/releases)
- [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md)
- [Commits](https://github.com/dotnet/fsharp/commits)
---
updated-dependencies:
- dependency-name: FSharp.Core
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index df2f4d2cb..5201d051a 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -54,7 +54,7 @@
-
+
From 66457b1dfb729a9ebed6e933f26ef9a3ecaa2709 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 9 Mar 2025 03:19:20 +0000
Subject: [PATCH 195/200] Bump MemoryPack from 1.21.3 to 1.21.4
Bumps [MemoryPack](https://github.com/Cysharp/MemoryPack) from 1.21.3 to 1.21.4.
- [Release notes](https://github.com/Cysharp/MemoryPack/releases)
- [Commits](https://github.com/Cysharp/MemoryPack/compare/1.21.3...1.21.4)
---
updated-dependencies:
- dependency-name: MemoryPack
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Infrastructure.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index 5d8b26425..b91da7114 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -59,7 +59,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
From c1a80158e609a2573b484793ea1baa499c699404 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 9 Mar 2025 07:24:13 +0000
Subject: [PATCH 196/200] Bump StreamJsonRpc from 2.20.20 to 2.21.10
Bumps [StreamJsonRpc](https://github.com/microsoft/vs-streamjsonrpc) from 2.20.20 to 2.21.10.
- [Release notes](https://github.com/microsoft/vs-streamjsonrpc/releases)
- [Commits](https://github.com/microsoft/vs-streamjsonrpc/commits)
---
updated-dependencies:
- dependency-name: StreamJsonRpc
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 5201d051a..e9f199d00 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -58,7 +58,7 @@
-
+
From 65d42bf7c06aa26bb5e10c54e6cfb59e1519bc92 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 9 Mar 2025 07:25:00 +0000
Subject: [PATCH 197/200] Bump Microsoft.Data.Sqlite from 9.0.1 to 9.0.2
Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 9.0.1 to 9.0.2.
- [Release notes](https://github.com/dotnet/efcore/releases)
- [Commits](https://github.com/dotnet/efcore/compare/v9.0.1...v9.0.2)
---
updated-dependencies:
- dependency-name: Microsoft.Data.Sqlite
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index d7a626e1d..df534cb3f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -95,7 +95,7 @@
-
+
From 8408a3cc544957d90033c34159f5a7391cbf135f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 9 Mar 2025 07:57:00 +0000
Subject: [PATCH 198/200] Bump System.Data.OleDb from 8.0.1 to 9.0.2
Bumps [System.Data.OleDb](https://github.com/dotnet/runtime) from 8.0.1 to 9.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v8.0.1...v9.0.2)
---
updated-dependencies:
- dependency-name: System.Data.OleDb
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.Explorer.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index 29925aeef..f5691cb73 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -45,7 +45,7 @@
-
+
From 869fe5f94ac512603a923b1dc282eadc26553538 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Mon, 10 Mar 2025 09:41:17 +0800
Subject: [PATCH 199/200] Revert "Bump System.Data.OleDb from 8.0.1 to 9.0.2"
---
.../Flow.Launcher.Plugin.Explorer.csproj | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index f5691cb73..549217027 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -45,7 +45,8 @@
-
+
+
From 1dfa15d325e9f43336dcbd6eac1ee934e15f9de7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 11 Mar 2025 22:13:52 +0000
Subject: [PATCH 200/200] Bump Microsoft.Data.Sqlite from 9.0.2 to 9.0.3
Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 9.0.2 to 9.0.3.
- [Release notes](https://github.com/dotnet/efcore/releases)
- [Commits](https://github.com/dotnet/efcore/compare/v9.0.2...v9.0.3)
---
updated-dependencies:
- dependency-name: Microsoft.Data.Sqlite
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index df534cb3f..b4e42fbcd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -95,7 +95,7 @@
-
+