mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge branch 'Flow-Launcher:dev' into dev
This commit is contained in:
commit
9ac822fe3d
9 changed files with 69 additions and 54 deletions
|
|
@ -115,7 +115,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
foreach (var result in queryResponseModel.Result)
|
||||
{
|
||||
result.Action = c =>
|
||||
result.AsyncAction = async c =>
|
||||
{
|
||||
UpdateSettings(result.SettingsChange);
|
||||
|
||||
|
|
@ -133,15 +133,15 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
else
|
||||
{
|
||||
var actionResponse = Request(result.JsonRPCAction);
|
||||
var actionResponse = await RequestAsync(result.JsonRPCAction);
|
||||
|
||||
if (string.IsNullOrEmpty(actionResponse))
|
||||
if (actionResponse.Length == 0)
|
||||
{
|
||||
return !result.JsonRPCAction.DontHideAfterAction;
|
||||
}
|
||||
|
||||
var jsonRpcRequestModel =
|
||||
JsonSerializer.Deserialize<JsonRPCRequestModel>(actionResponse, options);
|
||||
var jsonRpcRequestModel = await
|
||||
JsonSerializer.DeserializeAsync<JsonRPCRequestModel>(actionResponse, options);
|
||||
|
||||
if (jsonRpcRequestModel?.Method?.StartsWith("Flow.Launcher.") ?? false)
|
||||
{
|
||||
|
|
@ -166,19 +166,20 @@ namespace Flow.Launcher.Core.Plugin
|
|||
private void ExecuteFlowLauncherAPI(string method, object[] parameters)
|
||||
{
|
||||
var parametersTypeArray = parameters.Select(param => param.GetType()).ToArray();
|
||||
MethodInfo methodInfo = PluginManager.API.GetType().GetMethod(method, parametersTypeArray);
|
||||
if (methodInfo != null)
|
||||
var methodInfo = typeof(IPublicAPI).GetMethod(method, parametersTypeArray);
|
||||
if (methodInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
methodInfo.Invoke(PluginManager.API, parameters);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
methodInfo.Invoke(PluginManager.API, parameters);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if (DEBUG)
|
||||
throw;
|
||||
throw;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +242,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
protected async Task<Stream> ExecuteAsync(ProcessStartInfo startInfo, CancellationToken token = default)
|
||||
{
|
||||
Process process = null;
|
||||
bool disposed = false;
|
||||
using var exitTokenSource = new CancellationTokenSource();
|
||||
try
|
||||
{
|
||||
process = Process.Start(startInfo);
|
||||
|
|
@ -251,6 +252,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return Stream.Null;
|
||||
}
|
||||
|
||||
|
||||
await using var source = process.StandardOutput.BaseStream;
|
||||
|
||||
var buffer = BufferManager.GetStream();
|
||||
|
|
@ -259,7 +261,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
// Manually Check whether disposed
|
||||
if (!disposed && !process.HasExited)
|
||||
if (!exitTokenSource.IsCancellationRequested && !process.HasExited)
|
||||
process.Kill();
|
||||
});
|
||||
|
||||
|
|
@ -302,8 +304,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
finally
|
||||
{
|
||||
exitTokenSource.Cancel();
|
||||
process?.Dispose();
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,8 +367,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
var settingWindow = new UserControl();
|
||||
var mainPanel = new StackPanel
|
||||
{
|
||||
Margin = settingPanelMargin,
|
||||
Orientation = Orientation.Vertical
|
||||
Margin = settingPanelMargin, Orientation = Orientation.Vertical
|
||||
};
|
||||
settingWindow.Content = mainPanel;
|
||||
|
||||
|
|
@ -374,8 +375,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
var panel = new StackPanel
|
||||
{
|
||||
Orientation = Orientation.Horizontal,
|
||||
Margin = settingControlMargin
|
||||
Orientation = Orientation.Horizontal, Margin = settingControlMargin
|
||||
};
|
||||
var name = new TextBlock()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return null;
|
||||
}
|
||||
|
||||
var rawQuery = string.Join(Query.TermSeparator, terms);
|
||||
var rawQuery = text;
|
||||
string actionKeyword, search;
|
||||
string possibleActionKeyword = terms[0];
|
||||
string[] searchTerms;
|
||||
|
|
@ -24,13 +24,13 @@ namespace Flow.Launcher.Core.Plugin
|
|||
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
|
||||
{ // use non global plugin for query
|
||||
actionKeyword = possibleActionKeyword;
|
||||
search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..] : string.Empty;
|
||||
search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..].TrimStart() : string.Empty;
|
||||
searchTerms = terms[1..];
|
||||
}
|
||||
else
|
||||
{ // non action keyword
|
||||
actionKeyword = string.Empty;
|
||||
search = rawQuery;
|
||||
search = rawQuery.TrimStart();
|
||||
searchTerms = terms;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Flow.Launcher.Plugin
|
||||
|
|
@ -85,6 +86,14 @@ namespace Flow.Launcher.Plugin
|
|||
/// </summary>
|
||||
public Func<ActionContext, bool> Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Delegate. An Async action to take in the form of a function call when the result has been selected
|
||||
/// <returns>
|
||||
/// true to hide flowlauncher after select result
|
||||
/// </returns>
|
||||
/// </summary>
|
||||
public Func<ActionContext, ValueTask<bool>> AsyncAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Priority of the current result
|
||||
/// <value>default: 0</value>
|
||||
|
|
@ -169,5 +178,10 @@ namespace Flow.Launcher.Plugin
|
|||
/// Show message as ToolTip on result SubTitle hover over
|
||||
/// </summary>
|
||||
public string SubTitleToolTip { get; set; }
|
||||
|
||||
public ValueTask<bool> ExecuteAsync(ActionContext context)
|
||||
{
|
||||
return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ namespace Flow.Launcher.Test.Plugins
|
|||
foreach (var result in results)
|
||||
{
|
||||
Assert.IsNotNull(result);
|
||||
Assert.IsNotNull(result.Action);
|
||||
Assert.IsNotNull(result.AsyncAction);
|
||||
Assert.IsNotNull(result.Title);
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ namespace Flow.Launcher.Test.Plugins
|
|||
Assert.AreEqual(result1, referenceResult);
|
||||
|
||||
Assert.IsNotNull(result1);
|
||||
Assert.IsNotNull(result1.Action);
|
||||
Assert.IsNotNull(result1.AsyncAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Flow.Launcher.Test
|
|||
|
||||
Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
|
||||
|
||||
Assert.AreEqual("file.txt file2 file3", q.Search);
|
||||
Assert.AreEqual("file.txt file2 file3", q.Search);
|
||||
Assert.AreEqual(">", q.ActionKeyword);
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ namespace Flow.Launcher.Test
|
|||
|
||||
Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
|
||||
|
||||
Assert.AreEqual("> file.txt file2 file3", q.Search);
|
||||
Assert.AreEqual("> file.txt file2 file3", q.Search);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
Height="32"
|
||||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Source="{Binding Image}"
|
||||
Source="{Binding Image, TargetNullValue={x:Null}}"
|
||||
Stretch="Uniform"
|
||||
Visibility="{Binding ShowIcon}" />
|
||||
</Border>
|
||||
|
|
|
|||
|
|
@ -194,37 +194,38 @@ namespace Flow.Launcher.ViewModel
|
|||
PluginManager.API.OpenUrl("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/");
|
||||
});
|
||||
OpenSettingCommand = new RelayCommand(_ => { App.API.OpenSettingDialog(); });
|
||||
OpenResultCommand = new RelayCommand(index =>
|
||||
OpenResultCommand = new RelayCommand(async index =>
|
||||
{
|
||||
var results = SelectedResults;
|
||||
|
||||
if (index != null)
|
||||
{
|
||||
results.SelectedIndex = int.Parse(index.ToString());
|
||||
results.SelectedIndex = int.Parse(index.ToString()!);
|
||||
}
|
||||
|
||||
var result = results.SelectedItem?.Result;
|
||||
if (result != null) // SelectedItem returns null if selection is empty.
|
||||
if (result == null)
|
||||
{
|
||||
bool hideWindow = result.Action != null && result.Action(new ActionContext
|
||||
{
|
||||
SpecialKeyState = GlobalHotkey.CheckModifiers()
|
||||
});
|
||||
return;
|
||||
}
|
||||
var hideWindow = await result.ExecuteAsync(new ActionContext
|
||||
{
|
||||
SpecialKeyState = GlobalHotkey.CheckModifiers()
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
if (hideWindow)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
if (hideWindow)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
_userSelectedRecord.Add(result);
|
||||
_history.Add(result.OriginQuery.RawQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
_userSelectedRecord.Add(result);
|
||||
_history.Add(result.OriginQuery.RawQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -572,7 +573,7 @@ namespace Flow.Launcher.ViewModel
|
|||
if (currentCancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
||||
var query = QueryBuilder.Build(QueryText, PluginManager.NonGlobalPlugins);
|
||||
|
||||
// handle the exclusiveness of plugin using action keyword
|
||||
RemoveOldQueryResults(query);
|
||||
|
|
@ -664,7 +665,7 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
private void RemoveOldQueryResults(Query query)
|
||||
{
|
||||
if (_lastQuery.ActionKeyword != query.ActionKeyword)
|
||||
if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
|
||||
{
|
||||
Results.Clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: '1.9.3.{build}'
|
||||
version: '1.9.4.{build}'
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
|
|
|
|||
Loading…
Reference in a new issue