Skip to content

Commit c64f3df

Browse files
authored
Merge branch 'dev' into multiple_topmost
2 parents 1cf264a + 2fdab61 commit c64f3df

29 files changed

+904
-227
lines changed

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static class PluginManager
2525
private static readonly string ClassName = nameof(PluginManager);
2626

2727
private static IEnumerable<PluginPair> _contextMenuPlugins;
28+
private static IEnumerable<PluginPair> _homePlugins;
2829

2930
public static List<PluginPair> AllPlugins { get; private set; }
3031
public static readonly HashSet<PluginPair> GlobalPlugins = new();
@@ -220,13 +221,16 @@ public static async Task InitializePluginsAsync()
220221
{
221222
API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
222223
pair.Metadata.Disabled = true;
224+
pair.Metadata.HomeDisabled = true;
223225
failedPlugins.Enqueue(pair);
224226
}
225227
}));
226228

227229
await Task.WhenAll(InitTasks);
228230

229231
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
232+
_homePlugins = GetPluginsForInterface<IAsyncHomeQuery>();
233+
230234
foreach (var plugin in AllPlugins)
231235
{
232236
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
@@ -274,6 +278,11 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
274278
};
275279
}
276280

281+
public static ICollection<PluginPair> ValidPluginsForHomeQuery()
282+
{
283+
return _homePlugins.ToList();
284+
}
285+
277286
public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Query query, CancellationToken token)
278287
{
279288
var results = new List<Result>();
@@ -318,6 +327,36 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
318327
return results;
319328
}
320329

330+
public static async Task<List<Result>> QueryHomeForPluginAsync(PluginPair pair, Query query, CancellationToken token)
331+
{
332+
var results = new List<Result>();
333+
var metadata = pair.Metadata;
334+
335+
try
336+
{
337+
var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Cost for {metadata.Name}",
338+
async () => results = await ((IAsyncHomeQuery)pair.Plugin).HomeQueryAsync(token).ConfigureAwait(false));
339+
340+
token.ThrowIfCancellationRequested();
341+
if (results == null)
342+
return null;
343+
UpdatePluginMetadata(results, metadata, query);
344+
345+
token.ThrowIfCancellationRequested();
346+
}
347+
catch (OperationCanceledException)
348+
{
349+
// null will be fine since the results will only be added into queue if the token hasn't been cancelled
350+
return null;
351+
}
352+
catch (Exception e)
353+
{
354+
API.LogException(ClassName, $"Failed to query home for plugin: {metadata.Name}", e);
355+
return null;
356+
}
357+
return results;
358+
}
359+
321360
public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata, Query query)
322361
{
323362
foreach (var r in results)
@@ -378,6 +417,11 @@ public static List<Result> GetContextMenusForPlugin(Result result)
378417
return results;
379418
}
380419

420+
public static bool IsHomePlugin(string id)
421+
{
422+
return _homePlugins.Any(p => p.Metadata.ID == id);
423+
}
424+
381425
public static bool ActionKeywordRegistered(string actionKeyword)
382426
{
383427
// this method is only checking for action keywords (defined as not '*') registration
Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using Flow.Launcher.Plugin;
44

@@ -8,10 +8,23 @@ public static class QueryBuilder
88
{
99
public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalPlugins)
1010
{
11+
// home query
12+
if (string.IsNullOrEmpty(text))
13+
{
14+
return new Query()
15+
{
16+
Search = string.Empty,
17+
RawQuery = string.Empty,
18+
SearchTerms = Array.Empty<string>(),
19+
ActionKeyword = string.Empty
20+
};
21+
}
22+
1123
// replace multiple white spaces with one white space
1224
var terms = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries);
1325
if (terms.Length == 0)
14-
{ // nothing was typed
26+
{
27+
// nothing was typed
1528
return null;
1629
}
1730

@@ -21,19 +34,21 @@ public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalP
2134
string[] searchTerms;
2235

2336
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
24-
{ // use non global plugin for query
37+
{
38+
// use non global plugin for query
2539
actionKeyword = possibleActionKeyword;
2640
search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..].TrimStart() : string.Empty;
2741
searchTerms = terms[1..];
2842
}
2943
else
30-
{ // non action keyword
44+
{
45+
// non action keyword
3146
actionKeyword = string.Empty;
3247
search = rawQuery.TrimStart();
3348
searchTerms = terms;
3449
}
3550

36-
return new Query ()
51+
return new Query()
3752
{
3853
Search = search,
3954
RawQuery = rawQuery,
@@ -42,4 +57,4 @@ public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalP
4257
};
4358
}
4459
}
45-
}
60+
}

Flow.Launcher.Core/Resource/Theme.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public Theme(IPublicAPI publicAPI, Settings settings)
7676
{
7777
_api.LogError(ClassName, "Current theme resource not found. Initializing with default theme.");
7878
_oldTheme = Constant.DefaultTheme;
79-
};
79+
}
8080
}
8181

8282
#endregion
@@ -126,7 +126,7 @@ public void UpdateFonts()
126126
// Load a ResourceDictionary for the specified theme.
127127
var themeName = _settings.Theme;
128128
var dict = GetThemeResourceDictionary(themeName);
129-
129+
130130
// Apply font settings to the theme resource.
131131
ApplyFontSettings(dict);
132132
UpdateResourceDictionary(dict);
@@ -152,11 +152,11 @@ private void ApplyFontSettings(ResourceDictionary dict)
152152
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.QueryBoxFontStyle);
153153
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
154154
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);
155-
155+
156156
SetFontProperties(queryBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, true);
157157
SetFontProperties(querySuggestionBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
158158
}
159-
159+
160160
if (dict["ItemTitleStyle"] is Style resultItemStyle &&
161161
dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle &&
162162
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
@@ -172,7 +172,7 @@ private void ApplyFontSettings(ResourceDictionary dict)
172172
SetFontProperties(resultHotkeyItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
173173
SetFontProperties(resultHotkeyItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
174174
}
175-
175+
176176
if (dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
177177
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle)
178178
{
@@ -197,7 +197,7 @@ private static void SetFontProperties(Style style, FontFamily fontFamily, FontSt
197197
// First, find the setters to remove and store them in a list
198198
var settersToRemove = style.Setters
199199
.OfType<Setter>()
200-
.Where(setter =>
200+
.Where(setter =>
201201
setter.Property == Control.FontFamilyProperty ||
202202
setter.Property == Control.FontStyleProperty ||
203203
setter.Property == Control.FontWeightProperty ||
@@ -227,18 +227,18 @@ private static void SetFontProperties(Style style, FontFamily fontFamily, FontSt
227227
{
228228
var settersToRemove = style.Setters
229229
.OfType<Setter>()
230-
.Where(setter =>
230+
.Where(setter =>
231231
setter.Property == TextBlock.FontFamilyProperty ||
232232
setter.Property == TextBlock.FontStyleProperty ||
233233
setter.Property == TextBlock.FontWeightProperty ||
234234
setter.Property == TextBlock.FontStretchProperty)
235235
.ToList();
236-
236+
237237
foreach (var setter in settersToRemove)
238238
{
239239
style.Setters.Remove(setter);
240240
}
241-
241+
242242
style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, fontFamily));
243243
style.Setters.Add(new Setter(TextBlock.FontStyleProperty, fontStyle));
244244
style.Setters.Add(new Setter(TextBlock.FontWeightProperty, fontWeight));
@@ -421,7 +421,7 @@ public bool ChangeTheme(string theme = null)
421421

422422
// Retrieve theme resource – always use the resource with font settings applied.
423423
var resourceDict = GetResourceDictionary(theme);
424-
424+
425425
UpdateResourceDictionary(resourceDict);
426426

427427
_settings.Theme = theme;

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ MONITORINFOEXW
4343
WM_ENTERSIZEMOVE
4444
WM_EXITSIZEMOVE
4545

46+
OleInitialize
47+
OleUninitialize
48+
4649
GetKeyboardLayout
4750
GetWindowThreadProcessId
4851
ActivateKeyboardLayout
@@ -53,4 +56,4 @@ INPUTLANGCHANGE_FORWARD
5356
LOCALE_TRANSIENT_KEYBOARD1
5457
LOCALE_TRANSIENT_KEYBOARD2
5558
LOCALE_TRANSIENT_KEYBOARD3
56-
LOCALE_TRANSIENT_KEYBOARD4
59+
LOCALE_TRANSIENT_KEYBOARD4
Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
using System;
22
using System.Text.Json.Serialization;
3+
using System.Threading.Tasks;
34

45
namespace Flow.Launcher.Infrastructure.UserSettings
56
{
7+
#region Base
8+
69
public abstract class ShortcutBaseModel
710
{
811
public string Key { get; set; }
912

10-
[JsonIgnore]
11-
public Func<string> Expand { get; set; } = () => { return ""; };
12-
1313
public override bool Equals(object obj)
1414
{
1515
return obj is ShortcutBaseModel other &&
@@ -22,16 +22,14 @@ public override int GetHashCode()
2222
}
2323
}
2424

25-
public class CustomShortcutModel : ShortcutBaseModel
25+
public class BaseCustomShortcutModel : ShortcutBaseModel
2626
{
2727
public string Value { get; set; }
2828

29-
[JsonConstructorAttribute]
30-
public CustomShortcutModel(string key, string value)
29+
public BaseCustomShortcutModel(string key, string value)
3130
{
3231
Key = key;
3332
Value = value;
34-
Expand = () => { return Value; };
3533
}
3634

3735
public void Deconstruct(out string key, out string value)
@@ -40,26 +38,69 @@ public void Deconstruct(out string key, out string value)
4038
value = Value;
4139
}
4240

43-
public static implicit operator (string Key, string Value)(CustomShortcutModel shortcut)
41+
public static implicit operator (string Key, string Value)(BaseCustomShortcutModel shortcut)
4442
{
4543
return (shortcut.Key, shortcut.Value);
4644
}
4745

48-
public static implicit operator CustomShortcutModel((string Key, string Value) shortcut)
46+
public static implicit operator BaseCustomShortcutModel((string Key, string Value) shortcut)
4947
{
50-
return new CustomShortcutModel(shortcut.Key, shortcut.Value);
48+
return new BaseCustomShortcutModel(shortcut.Key, shortcut.Value);
5149
}
5250
}
5351

54-
public class BuiltinShortcutModel : ShortcutBaseModel
52+
public class BaseBuiltinShortcutModel : ShortcutBaseModel
5553
{
5654
public string Description { get; set; }
5755

58-
public BuiltinShortcutModel(string key, string description, Func<string> expand)
56+
public BaseBuiltinShortcutModel(string key, string description)
5957
{
6058
Key = key;
6159
Description = description;
62-
Expand = expand ?? (() => { return ""; });
6360
}
6461
}
62+
63+
#endregion
64+
65+
#region Custom Shortcut
66+
67+
public class CustomShortcutModel : BaseCustomShortcutModel
68+
{
69+
[JsonIgnore]
70+
public Func<string> Expand { get; set; } = () => { return string.Empty; };
71+
72+
[JsonConstructor]
73+
public CustomShortcutModel(string key, string value) : base(key, value)
74+
{
75+
Expand = () => { return Value; };
76+
}
77+
}
78+
79+
#endregion
80+
81+
#region Builtin Shortcut
82+
83+
public class BuiltinShortcutModel : BaseBuiltinShortcutModel
84+
{
85+
[JsonIgnore]
86+
public Func<string> Expand { get; set; } = () => { return string.Empty; };
87+
88+
public BuiltinShortcutModel(string key, string description, Func<string> expand) : base(key, description)
89+
{
90+
Expand = expand ?? (() => { return string.Empty; });
91+
}
92+
}
93+
94+
public class AsyncBuiltinShortcutModel : BaseBuiltinShortcutModel
95+
{
96+
[JsonIgnore]
97+
public Func<Task<string>> ExpandAsync { get; set; } = () => { return Task.FromResult(string.Empty); };
98+
99+
public AsyncBuiltinShortcutModel(string key, string description, Func<Task<string>> expandAsync) : base(key, description)
100+
{
101+
ExpandAsync = expandAsync ?? (() => { return Task.FromResult(string.Empty); });
102+
}
103+
}
104+
105+
#endregion
65106
}

Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public void UpdatePluginSettings(List<PluginMetadata> metadatas)
6767
metadata.Disabled = settings.Disabled;
6868
metadata.Priority = settings.Priority;
6969
metadata.SearchDelayTime = settings.SearchDelayTime;
70+
metadata.HomeDisabled = settings.HomeDisabled;
7071
}
7172
else
7273
{
@@ -79,6 +80,7 @@ public void UpdatePluginSettings(List<PluginMetadata> metadatas)
7980
DefaultActionKeywords = metadata.ActionKeywords, // metadata provides default values
8081
ActionKeywords = metadata.ActionKeywords, // use default value
8182
Disabled = metadata.Disabled,
83+
HomeDisabled = metadata.HomeDisabled,
8284
Priority = metadata.Priority,
8385
DefaultSearchDelayTime = metadata.SearchDelayTime, // metadata provides default values
8486
SearchDelayTime = metadata.SearchDelayTime, // use default value
@@ -128,5 +130,6 @@ public class Plugin
128130
/// Used only to save the state of the plugin in settings
129131
/// </summary>
130132
public bool Disabled { get; set; }
133+
public bool HomeDisabled { get; set; }
131134
}
132135
}

0 commit comments

Comments
 (0)