Merge branch 'dev' into nuget_package_upgrade

This commit is contained in:
Jack Ye 2025-08-30 16:27:15 +08:00 committed by GitHub
commit 528687cf63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 143 additions and 49 deletions

View file

@ -11,6 +11,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal class PythonEnvironment : AbstractPluginEnvironment
{
private static readonly string ClassName = nameof(PythonEnvironment);
internal override string Language => AllowedLanguage.Python;
internal override string EnvName => DataLocation.PythonEnvironmentName;
@ -39,9 +41,20 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
// 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
JTF.Run(() => DroplexPackage.Drop(App.python_3_11_4_embeddable, InstallPath));
JTF.Run(async () =>
{
try
{
await DroplexPackage.Drop(App.python_3_11_4_embeddable, InstallPath);
PluginsSettingsFilePath = ExecutablePath;
PluginsSettingsFilePath = ExecutablePath;
}
catch (System.Exception e)
{
API.ShowMsgError(API.GetTranslation("failToInstallPythonEnv"));
API.LogException(ClassName, "Failed to install Python environment", e);
}
});
}
internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)

View file

@ -11,6 +11,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal class TypeScriptEnvironment : AbstractPluginEnvironment
{
private static readonly string ClassName = nameof(TypeScriptEnvironment);
internal override string Language => AllowedLanguage.TypeScript;
internal override string EnvName => DataLocation.NodeEnvironmentName;
@ -34,9 +36,20 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
JTF.Run(() => DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath));
JTF.Run(async () =>
{
try
{
await DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath);
PluginsSettingsFilePath = ExecutablePath;
PluginsSettingsFilePath = ExecutablePath;
}
catch (System.Exception e)
{
API.ShowMsgError(API.GetTranslation("failToInstallTypeScriptEnv"));
API.LogException(ClassName, "Failed to install TypeScript environment", e);
}
});
}
internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)

View file

@ -11,6 +11,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal class TypeScriptV2Environment : AbstractPluginEnvironment
{
private static readonly string ClassName = nameof(TypeScriptV2Environment);
internal override string Language => AllowedLanguage.TypeScriptV2;
internal override string EnvName => DataLocation.NodeEnvironmentName;
@ -34,9 +36,20 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
JTF.Run(() => DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath));
JTF.Run(async () =>
{
try
{
await DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath);
PluginsSettingsFilePath = ExecutablePath;
PluginsSettingsFilePath = ExecutablePath;
}
catch (System.Exception e)
{
API.ShowMsgError(API.GetTranslation("failToInstallTypeScriptEnv"));
API.LogException(ClassName, "Failed to install TypeScript environment", e);
}
});
}
internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)

View file

@ -124,13 +124,9 @@ namespace Flow.Launcher.Core.Plugin
API.GetTranslation("pluginsHaveErrored") :
API.GetTranslation("pluginHasErrored");
_ = Task.Run(() =>
{
API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
API.GetTranslation("referToLogs"), string.Empty,
MessageBoxButton.OK, MessageBoxImage.Warning);
});
API.ShowMsgError($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
API.GetTranslation("referToLogs"));
}
return plugins;

View file

@ -17,6 +17,7 @@ namespace Flow.Launcher.Core.Resource
public static Language German = new Language("de", "Deutsch");
public static Language Korean = new Language("ko", "한국어");
public static Language Serbian = new Language("sr", "Srpski");
public static Language Serbian_Cyrillic = new Language("sr-Cyrl-RS", "Српски");
public static Language Portuguese_Portugal = new Language("pt-pt", "Português");
public static Language Portuguese_Brazil = new Language("pt-br", "Português (Brasil)");
public static Language Spanish = new Language("es", "Spanish");
@ -47,6 +48,7 @@ namespace Flow.Launcher.Core.Resource
German,
Korean,
Serbian,
Serbian_Cyrillic,
Portuguese_Portugal,
Portuguese_Brazil,
Spanish,
@ -79,7 +81,8 @@ namespace Flow.Launcher.Core.Resource
"da" => "System",
"de" => "System",
"ko" => "시스템",
"sr" => "Систем",
"sr" => "Sistem",
"sr-Cyrl-RS" => "Систем",
"pt-pt" => "Sistema",
"pt-br" => "Sistema",
"es" => "Sistema",

View file

@ -161,8 +161,8 @@
},
"Microsoft.Win32.SystemEvents": {
"type": "Transitive",
"resolved": "9.0.8",
"contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA=="
"resolved": "7.0.0",
"contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ=="
},
"Mono.Cecil": {
"type": "Transitive",
@ -222,10 +222,10 @@
},
"System.Drawing.Common": {
"type": "Transitive",
"resolved": "9.0.8",
"contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==",
"resolved": "7.0.0",
"contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
"dependencies": {
"Microsoft.Win32.SystemEvents": "9.0.8"
"Microsoft.Win32.SystemEvents": "7.0.0"
}
},
"System.IO.Pipelines": {

View file

@ -74,7 +74,9 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SharpVectors.Wpf" Version="1.8.5" />
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
<!-- Do not upgrade this to higher version since it can cause this issue on WinForm platform: -->
<!-- PlatformNotSupportedException: SystemEvents is not supported on this platform. -->
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.1.0.3" />
</ItemGroup>

View file

@ -108,11 +108,11 @@
},
"System.Drawing.Common": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
"dependencies": {
"Microsoft.Win32.SystemEvents": "9.0.8"
"Microsoft.Win32.SystemEvents": "7.0.0"
}
},
"ToolGood.Words.Pinyin": {
@ -156,8 +156,8 @@
},
"Microsoft.Win32.SystemEvents": {
"type": "Transitive",
"resolved": "9.0.8",
"contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA=="
"resolved": "7.0.0",
"contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ=="
},
"Microsoft.Windows.SDK.Win32Docs": {
"type": "Transitive",

View file

@ -57,7 +57,10 @@ namespace Flow.Launcher.Plugin
/// for user on the plugin result. If autocomplete action for example is tab, pressing tab will have
/// the default constructed autocomplete text (result's Title), or the text provided here if not empty.
/// </summary>
/// <remarks>When a value is not set, the <see cref="Title"/> will be used.</remarks>
/// <remarks>
/// When a value is not set, the <see cref="Title"/> will be used.
/// Please include the action keyword prefix when necessary because Flow does not prepend it automatically.
/// </remarks>
public string AutoCompleteText { get; set; }
/// <summary>
@ -257,6 +260,17 @@ namespace Flow.Launcher.Plugin
/// </summary>
public bool ShowBadge { get; set; } = false;
/// <summary>
/// This holds the text which can be shown as a query suggestion.
/// </summary>
/// <remarks>
/// When a value is not set, the <see cref="Title"/> will be used.
/// Do not include the action keyword prefix because Flow prepends it automatically.
/// If the it does not start with the query text, it will not be shown as a suggestion.
/// So make sure to set this value to start with the query text.
/// </remarks>
public string QuerySuggestionText { get; set; }
/// <summary>
/// Run this result, asynchronously
/// </summary>
@ -307,7 +321,8 @@ namespace Flow.Launcher.Plugin
Preview = Preview,
AddSelectedCount = AddSelectedCount,
RecordKey = RecordKey,
ShowBadge = ShowBadge
ShowBadge = ShowBadge,
QuerySuggestionText = QuerySuggestionText
};
}

View file

@ -297,6 +297,7 @@ namespace Flow.Launcher
});
}
[Conditional("RELEASE")]
private static void AutoPluginUpdates()
{
_ = Task.Run(async () =>

View file

@ -33,15 +33,39 @@ public class QuerySuggestionBoxConverter : IMultiValueConverter
{
var selectedResult = selectedItem.Result;
var selectedResultActionKeyword = string.IsNullOrEmpty(selectedResult.ActionKeywordAssigned) ? "" : selectedResult.ActionKeywordAssigned + " ";
var selectedResultPossibleSuggestion = selectedResultActionKeyword + selectedResult.Title;
if (!selectedResultPossibleSuggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
string selectedResultPossibleSuggestion = null;
// Firstly check if the result has QuerySuggestionText
if (!string.IsNullOrEmpty(selectedResult.QuerySuggestionText))
{
selectedResultPossibleSuggestion = selectedResultActionKeyword + selectedResult.QuerySuggestionText;
// If this QuerySuggestionText does not start with the queryText, set it to null
if (!selectedResultPossibleSuggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
{
selectedResultPossibleSuggestion = null;
}
}
// Then check Title as suggestion
if (string.IsNullOrEmpty(selectedResultPossibleSuggestion))
{
selectedResultPossibleSuggestion = selectedResultActionKeyword + selectedResult.Title;
// If this QuerySuggestionText does not start with the queryText, set it to null
if (!selectedResultPossibleSuggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
{
selectedResultPossibleSuggestion = null;
}
}
if (string.IsNullOrEmpty(selectedResultPossibleSuggestion))
return string.Empty;
// For AutocompleteQueryCommand.
// When user typed lower case and result title is uppercase, we still want to display suggestion
selectedItem.QuerySuggestionText = queryText + selectedResultPossibleSuggestion.Substring(queryText.Length);
selectedItem.QuerySuggestionText = string.Concat(queryText, selectedResultPossibleSuggestion.AsSpan(queryText.Length));
// Check if Text will be larger than our QueryTextBox
Typeface typeface = new Typeface(queryTextBox.FontFamily, queryTextBox.FontStyle, queryTextBox.FontWeight, queryTextBox.FontStretch);

View file

@ -34,6 +34,10 @@
<system:String x:Key="pleaseTryAgain">Please try again</system:String>
<system:String x:Key="parseProxyFailed">Unable to parse Http Proxy</system:String>
<!-- AbstractPluginEnvironment -->
<system:String x:Key="failToInstallTypeScriptEnv">Failed to install TypeScript environment. Please try again later</system:String>
<system:String x:Key="failToInstallPythonEnv">Failed to install Python environment. Please try again later.</system:String>
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey "{0}". The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</system:String>
<system:String x:Key="unregisterHotkeyFailed">Failed to unregister hotkey "{0}". Please try again or see log for details</system:String>

View file

@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@ -379,24 +380,35 @@ namespace Flow.Launcher
explorer.Start();
}
}
catch (COMException ex) when (ex.ErrorCode == unchecked((int)0x80004004))
{
/*
* The COMException with HResult 0x80004004 is E_ABORT (operation aborted).
* Shell APIs often return this when the operation is canceled or the shell cannot complete it cleanly.
* It most likely comes from Win32Helper.OpenFolderAndSelectFile(targetPath).
* Typical triggers:
* The target file/folder was deleted/moved between computing targetPath and the shell call.
* The folder is on an offline network/removable drive.
* Explorer is restarting/busy and aborts the request.
* A selection request to a new/closing Explorer window is canceled.
* Because it is commonly user- or environment-driven and not actionable,
* we should treat it as expected noise and ignore it to avoid bothering users.
*/
}
catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
{
LogError(ClassName, "File Manager not found");
ShowMsgBox(
string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
ShowMsgError(
GetTranslation("fileManagerNotFoundTitle"),
MessageBoxButton.OK,
MessageBoxImage.Error
string.Format(GetTranslation("fileManagerNotFound"), ex.Message)
);
}
catch (Exception ex)
{
LogException(ClassName, "Failed to open folder", ex);
ShowMsgBox(
string.Format(GetTranslation("folderOpenError"), ex.Message),
ShowMsgError(
GetTranslation("errorTitle"),
MessageBoxButton.OK,
MessageBoxImage.Error
string.Format(GetTranslation("folderOpenError"), ex.Message)
);
}
}
@ -424,11 +436,9 @@ namespace Flow.Launcher
{
var tabOrWindow = browserInfo.OpenInTab ? "tab" : "window";
LogException(ClassName, $"Failed to open URL in browser {tabOrWindow}: {path}, {inPrivate ?? browserInfo.EnablePrivate}, {browserInfo.PrivateArg}", e);
ShowMsgBox(
GetTranslation("browserOpenError"),
ShowMsgError(
GetTranslation("errorTitle"),
MessageBoxButton.OK,
MessageBoxImage.Error
GetTranslation("browserOpenError")
);
}
}

View file

@ -552,8 +552,8 @@
},
"Microsoft.Win32.SystemEvents": {
"type": "Transitive",
"resolved": "9.0.8",
"contentHash": "64oQBN8I8EOcyHGNt6+rlcqm4tlcKfqOpswtBCJZnpzBQ15L6IFKqjnbjbOWBpG9wKq9A/aC2LFSmSqplbwTYA=="
"resolved": "7.0.0",
"contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ=="
},
"Mono.Cecil": {
"type": "Transitive",
@ -677,10 +677,10 @@
},
"System.Drawing.Common": {
"type": "Transitive",
"resolved": "9.0.8",
"contentHash": "ineIJmF+yuBEHGft9R153J9kmBFaeEfFL5Put5nzENneRcGGPUb3MvM8zrZ5pERQ0jPPSE3Wqw/clXvOq2F/Kw==",
"resolved": "7.0.0",
"contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
"dependencies": {
"Microsoft.Win32.SystemEvents": "9.0.8"
"Microsoft.Win32.SystemEvents": "7.0.0"
}
},
"System.Globalization": {