Skip to content

Commit 3596732

Browse files
committed
Merge remote-tracking branch 'origin/dev' into StopHidingScroller
2 parents fa8c3db + e6db8b8 commit 3596732

39 files changed

+757
-426
lines changed

Flow.Launcher.Core/Flow.Launcher.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
</ItemGroup>
5454

5555
<ItemGroup>
56-
<PackageReference Include="Droplex" Version="1.2.0" />
56+
<PackageReference Include="Droplex" Version="1.3.1" />
5757
<PackageReference Include="FSharp.Core" Version="4.7.1" />
5858
<PackageReference Include="squirrel.windows" Version="1.5.2" />
5959
</ItemGroup>
Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-

2-
/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Flow Launcher and other plugins,
1+
/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Flow Launcher and other plugins,
32
* like python or other self-execute program. But, we added addtional infos (proxy and so on) into rpc request. Also, we didn't use the
43
* "id" and "jsonrpc" in the request, since it's not so useful in our request model.
54
*
@@ -13,10 +12,12 @@
1312
*
1413
*/
1514

15+
using Flow.Launcher.Core.Resource;
1616
using System.Collections.Generic;
1717
using System.Linq;
1818
using System.Text.Json.Serialization;
1919
using Flow.Launcher.Plugin;
20+
using System.Text.Json;
2021

2122
namespace Flow.Launcher.Core.Plugin
2223
{
@@ -51,42 +52,15 @@ public class JsonRPCQueryResponseModel : JsonRPCResponseModel
5152

5253
public class JsonRPCRequestModel : JsonRPCModelBase
5354
{
55+
[JsonPropertyName("method")]
5456
public string Method { get; set; }
5557

58+
[JsonPropertyName("parameters")]
5659
public object[] Parameters { get; set; }
5760

5861
public override string ToString()
5962
{
60-
string rpc = string.Empty;
61-
if (Parameters != null && Parameters.Length > 0)
62-
{
63-
string parameters = $"[{string.Join(',', Parameters.Select(GetParameterByType))}]";
64-
rpc = $@"{{\""method\"":\""{Method}\"",\""parameters\"":{parameters}";
65-
}
66-
else
67-
{
68-
rpc = $@"{{\""method\"":\""{Method}\"",\""parameters\"":[]";
69-
}
70-
71-
return rpc;
72-
73-
}
74-
75-
private string GetParameterByType(object parameter)
76-
=> parameter switch
77-
{
78-
null => "null",
79-
string _ => $@"\""{ReplaceEscapes(parameter.ToString())}\""",
80-
bool _ => $@"{parameter.ToString().ToLower()}",
81-
_ => parameter.ToString()
82-
};
83-
84-
85-
private string ReplaceEscapes(string str)
86-
{
87-
return str.Replace(@"\", @"\\") //Escapes in ProcessStartInfo
88-
.Replace(@"\", @"\\") //Escapes itself when passed to client
89-
.Replace(@"""", @"\\""""");
63+
return JsonSerializer.Serialize(this);
9064
}
9165
}
9266

@@ -95,25 +69,16 @@ private string ReplaceEscapes(string str)
9569
/// </summary>
9670
public class JsonRPCServerRequestModel : JsonRPCRequestModel
9771
{
98-
public override string ToString()
99-
{
100-
string rpc = base.ToString();
101-
return rpc + "}";
102-
}
72+
10373
}
10474

10575
/// <summary>
10676
/// Json RPC Request(in query response) that client sent to Flow Launcher
10777
/// </summary>
10878
public class JsonRPCClientRequestModel : JsonRPCRequestModel
10979
{
80+
[JsonPropertyName("dontHideAfterAction")]
11081
public bool DontHideAfterAction { get; set; }
111-
112-
public override string ToString()
113-
{
114-
string rpc = base.ToString();
115-
return rpc + "}";
116-
}
11782
}
11883

11984
/// <summary>
@@ -125,4 +90,4 @@ public class JsonRPCResult : Result
12590
{
12691
public JsonRPCClientRequestModel JsonRPCAction { get; set; }
12792
}
128-
}
93+
}

Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Flow.Launcher.Core.Resource;
2+
using System;
23
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.IO;
@@ -45,14 +46,20 @@ public List<Result> LoadContextMenus(Result selectedResult)
4546
}
4647
}
4748

48-
49+
private static readonly JsonSerializerOptions _options = new()
50+
{
51+
Converters =
52+
{
53+
new JsonObjectConverter()
54+
}
55+
};
4956

5057
private async Task<List<Result>> DeserializedResultAsync(Stream output)
5158
{
5259
if (output == Stream.Null) return null;
5360

54-
JsonRPCQueryResponseModel queryResponseModel = await
55-
JsonSerializer.DeserializeAsync<JsonRPCQueryResponseModel>(output);
61+
var queryResponseModel = await
62+
JsonSerializer.DeserializeAsync<JsonRPCQueryResponseModel>(output, _options);
5663

5764
return ParseResults(queryResponseModel);
5865
}
@@ -61,17 +68,18 @@ private List<Result> DeserializedResult(string output)
6168
{
6269
if (string.IsNullOrEmpty(output)) return null;
6370

64-
JsonRPCQueryResponseModel queryResponseModel =
65-
JsonSerializer.Deserialize<JsonRPCQueryResponseModel>(output);
71+
var queryResponseModel =
72+
JsonSerializer.Deserialize<JsonRPCQueryResponseModel>(output, _options);
6673
return ParseResults(queryResponseModel);
6774
}
6875

76+
6977
private List<Result> ParseResults(JsonRPCQueryResponseModel queryResponseModel)
7078
{
7179
var results = new List<Result>();
7280
if (queryResponseModel.Result == null) return null;
7381

74-
if(!string.IsNullOrEmpty(queryResponseModel.DebugMessage))
82+
if (!string.IsNullOrEmpty(queryResponseModel.DebugMessage))
7583
{
7684
context.API.ShowMsg(queryResponseModel.DebugMessage);
7785
}
@@ -82,25 +90,31 @@ private List<Result> ParseResults(JsonRPCQueryResponseModel queryResponseModel)
8290
{
8391
if (result.JsonRPCAction == null) return false;
8492

85-
if (!string.IsNullOrEmpty(result.JsonRPCAction.Method))
93+
if (string.IsNullOrEmpty(result.JsonRPCAction.Method))
94+
{
95+
return !result.JsonRPCAction.DontHideAfterAction;
96+
}
97+
98+
if (result.JsonRPCAction.Method.StartsWith("Flow.Launcher."))
8699
{
87-
if (result.JsonRPCAction.Method.StartsWith("Flow.Launcher."))
100+
ExecuteFlowLauncherAPI(result.JsonRPCAction.Method["Flow.Launcher.".Length..],
101+
result.JsonRPCAction.Parameters);
102+
}
103+
else
104+
{
105+
var actionResponse = ExecuteCallback(result.JsonRPCAction);
106+
107+
if (string.IsNullOrEmpty(actionResponse))
88108
{
89-
ExecuteFlowLauncherAPI(result.JsonRPCAction.Method.Substring(4),
90-
result.JsonRPCAction.Parameters);
109+
return !result.JsonRPCAction.DontHideAfterAction;
91110
}
92-
else
111+
112+
var jsonRpcRequestModel = JsonSerializer.Deserialize<JsonRPCRequestModel>(actionResponse, _options);
113+
114+
if (jsonRpcRequestModel?.Method?.StartsWith("Flow.Launcher.") ?? false)
93115
{
94-
string actionReponse = ExecuteCallback(result.JsonRPCAction);
95-
JsonRPCRequestModel jsonRpcRequestModel =
96-
JsonSerializer.Deserialize<JsonRPCRequestModel>(actionReponse);
97-
if (jsonRpcRequestModel != null
98-
&& !string.IsNullOrEmpty(jsonRpcRequestModel.Method)
99-
&& jsonRpcRequestModel.Method.StartsWith("Flow.Launcher."))
100-
{
101-
ExecuteFlowLauncherAPI(jsonRpcRequestModel.Method.Substring(4),
102-
jsonRpcRequestModel.Parameters);
103-
}
116+
ExecuteFlowLauncherAPI(jsonRpcRequestModel.Method["Flow.Launcher.".Length..],
117+
jsonRpcRequestModel.Parameters);
104118
}
105119
}
106120

@@ -177,12 +191,14 @@ protected string Execute(ProcessStartInfo startInfo)
177191

178192
if (result.StartsWith("DEBUG:"))
179193
{
180-
MessageBox.Show(new Form { TopMost = true }, result.Substring(6));
194+
MessageBox.Show(new Form
195+
{
196+
TopMost = true
197+
}, result.Substring(6));
181198
return string.Empty;
182199
}
183200

184201
return result;
185-
186202
}
187203
catch (Exception e)
188204
{
@@ -248,10 +264,10 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
248264
}
249265
}
250266

251-
public Task InitAsync(PluginInitContext context)
267+
public virtual Task InitAsync(PluginInitContext context)
252268
{
253269
this.context = context;
254270
return Task.CompletedTask;
255271
}
256272
}
257-
}
273+
}

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public static class PluginManager
2121
private static IEnumerable<PluginPair> _contextMenuPlugins;
2222

2323
public static List<PluginPair> AllPlugins { get; private set; }
24-
public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>();
25-
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new Dictionary<string, PluginPair>();
24+
public static readonly HashSet<PluginPair> GlobalPlugins = new();
25+
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new ();
2626

2727
public static IPublicAPI API { private set; get; }
2828

@@ -118,7 +118,9 @@ public static async Task InitializePlugins(IPublicAPI api)
118118
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
119119
foreach (var plugin in AllPlugins)
120120
{
121-
foreach (var actionKeyword in plugin.Metadata.ActionKeywords)
121+
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
122+
// has multiple global and action keywords because we will only add them here once.
123+
foreach (var actionKeyword in plugin.Metadata.ActionKeywords.Distinct())
122124
{
123125
switch (actionKeyword)
124126
{
@@ -141,7 +143,7 @@ public static async Task InitializePlugins(IPublicAPI api)
141143
}
142144
}
143145

144-
public static List<PluginPair> ValidPluginsForQuery(Query query)
146+
public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
145147
{
146148
if (NonGlobalPlugins.ContainsKey(query.ActionKeyword))
147149
{
@@ -250,6 +252,8 @@ public static List<Result> GetContextMenusForPlugin(Result result)
250252

251253
public static bool ActionKeywordRegistered(string actionKeyword)
252254
{
255+
// this method is only checking for action keywords (defined as not '*') registration
256+
// hence the actionKeyword != Query.GlobalPluginWildcardSign logic
253257
return actionKeyword != Query.GlobalPluginWildcardSign
254258
&& NonGlobalPlugins.ContainsKey(actionKeyword);
255259
}
@@ -274,7 +278,7 @@ public static void AddActionKeyword(string id, string newActionKeyword)
274278
}
275279

276280
/// <summary>
277-
/// used to add action keyword for multiple action keyword plugin
281+
/// used to remove action keyword for multiple action keyword plugin
278282
/// e.g. web search
279283
/// </summary>
280284
public static void RemoveActionKeyword(string id, string oldActionkeyword)
@@ -283,9 +287,7 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
283287
if (oldActionkeyword == Query.GlobalPluginWildcardSign
284288
&& // Plugins may have multiple ActionKeywords that are global, eg. WebSearch
285289
plugin.Metadata.ActionKeywords
286-
.Where(x => x == Query.GlobalPluginWildcardSign)
287-
.ToList()
288-
.Count == 1)
290+
.Count(x => x == Query.GlobalPluginWildcardSign) == 1)
289291
{
290292
GlobalPlugins.Remove(plugin);
291293
}

0 commit comments

Comments
 (0)