Skip to content

Commit be47d61

Browse files
authored
Merge branch 'dev' into update_all
2 parents 87f35d4 + 15b69a2 commit be47d61

File tree

18 files changed

+936
-890
lines changed

18 files changed

+936
-890
lines changed

.github/actions/spelling/expect.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
crowdin
22
DWM
33
workflows
4-
Wpf
54
wpf
65
actionkeyword
76
stackoverflow
@@ -20,9 +19,7 @@ Prioritise
2019
Segoe
2120
Google
2221
Customise
23-
UWP
2422
uwp
25-
Uwp
2623
Bokmal
2724
Bokm
2825
uninstallation
@@ -61,7 +58,6 @@ popup
6158
ptr
6259
pluginindicator
6360
TobiasSekan
64-
Img
6561
img
6662
resx
6763
bak
@@ -78,7 +74,6 @@ WCA_ACCENT_POLICY
7874
HGlobal
7975
dopusrt
8076
firefox
81-
Firefox
8277
msedge
8378
svgc
8479
ime
@@ -87,7 +82,6 @@ txb
8782
btn
8883
otf
8984
searchplugin
90-
Noresult
9185
wpftk
9286
mkv
9387
flac
@@ -108,4 +102,6 @@ Preinstalled
108102
errormetadatafile
109103
noresult
110104
pluginsmanager
111-
alreadyexists
105+
alreadyexists
106+
JsonRPC
107+
JsonRPCV2

.github/actions/spelling/patterns.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,6 @@
118118

119119
# UWP
120120
[Uu][Ww][Pp]
121+
122+
# version suffix <word>v#
123+
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))

.github/workflows/spelling.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
steps:
7474
- name: check-spelling
7575
id: spelling
76-
uses: check-spelling/check-spelling@v0.0.22
76+
uses: check-spelling/check-spelling@prerelease
7777
with:
7878
suppress_push_for_open_pull_request: 1
7979
checkout: true
@@ -91,10 +91,9 @@ jobs:
9191
extra_dictionaries:
9292
cspell:software-terms/dict/softwareTerms.txt
9393
cspell:win32/src/win32.txt
94-
cspell:php/src/php.txt
9594
cspell:filetypes/filetypes.txt
9695
cspell:csharp/csharp.txt
97-
cspell:dotnet/src/dotnet.txt
96+
cspell:dotnet/dict/dotnet.txt
9897
cspell:python/src/common/extra.txt
9998
cspell:python/src/python/python-lib.txt
10099
cspell:aws/aws.txt
@@ -130,7 +129,7 @@ jobs:
130129
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
131130
steps:
132131
- name: comment
133-
uses: check-spelling/check-spelling@v0.0.22
132+
uses: check-spelling/check-spelling@prerelease
134133
with:
135134
checkout: true
136135
spell_check_this: check-spelling/spell-check-this@main

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,19 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
212212
}
213213
catch (Exception e)
214214
{
215-
throw new FlowPluginException(metadata, e);
215+
Result r = new()
216+
{
217+
Title = $"{metadata.Name}: Failed to respond!",
218+
SubTitle = "Select this result for more info",
219+
IcoPath = Flow.Launcher.Infrastructure.Constant.ErrorIcon,
220+
PluginDirectory = metadata.PluginDirectory,
221+
ActionKeywordAssigned = query.ActionKeyword,
222+
PluginID = metadata.ID,
223+
OriginQuery = query,
224+
Action = _ => { throw new FlowPluginException(metadata, e);},
225+
Score = -100
226+
};
227+
results.Add(r);
216228
}
217229
return results;
218230
}

Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ internal abstract class ProcessStreamPluginV2 : JsonRPCPluginV2
1717

1818
protected abstract ProcessStartInfo StartInfo { get; set; }
1919

20-
public Process ClientProcess { get; set; }
20+
protected Process ClientProcess { get; set; }
2121

2222
public override async Task InitAsync(PluginInitContext context)
2323
{
@@ -33,6 +33,8 @@ public override async Task InitAsync(PluginInitContext context)
3333

3434
SetupPipe(ClientProcess);
3535

36+
ErrorStream = ClientProcess.StandardError;
37+
3638
await base.InitAsync(context);
3739
}
3840

Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@
5353
<PrivateAssets>all</PrivateAssets>
5454
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5555
</PackageReference>
56+
<PackageReference Include="MemoryPack" Version="1.10.0" />
5657
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.7.30" />
5758
<PackageReference Include="NLog" Version="4.7.10" />
5859
<PackageReference Include="NLog.Schema" Version="4.7.10" />
5960
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0" />
6061
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
61-
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
62+
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
6263
<!--ToolGood.Words.Pinyin v3.0.2.6 results in high memory usage when search with pinyin is enabled-->
6364
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
6465
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />

Flow.Launcher.Infrastructure/Image/ImageLoader.cs

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Linq;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using System.Windows.Media;
89
using System.Windows.Media.Imaging;
@@ -15,6 +16,7 @@ namespace Flow.Launcher.Infrastructure.Image
1516
public static class ImageLoader
1617
{
1718
private static readonly ImageCache ImageCache = new();
19+
private static SemaphoreSlim storageLock { get; } = new SemaphoreSlim(1, 1);
1820
private static BinaryStorage<Dictionary<(string, bool), int>> _storage;
1921
private static readonly ConcurrentDictionary<string, string> GuidToKey = new();
2022
private static IImageHashGenerator _hashGenerator;
@@ -25,24 +27,18 @@ public static class ImageLoader
2527
public const int FullIconSize = 256;
2628

2729

28-
private static readonly string[] ImageExtensions =
29-
{
30-
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico"
31-
};
30+
private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
3231

33-
public static void Initialize()
32+
public static async Task InitializeAsync()
3433
{
3534
_storage = new BinaryStorage<Dictionary<(string, bool), int>>("Image");
3635
_hashGenerator = new ImageHashGenerator();
3736

38-
var usage = LoadStorageToConcurrentDictionary();
37+
var usage = await LoadStorageToConcurrentDictionaryAsync();
3938

4039
ImageCache.Initialize(usage.ToDictionary(x => x.Key, x => x.Value));
4140

42-
foreach (var icon in new[]
43-
{
44-
Constant.DefaultIcon, Constant.MissingImgIcon
45-
})
41+
foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon })
4642
{
4743
ImageSource img = new BitmapImage(new Uri(icon));
4844
img.Freeze();
@@ -58,29 +54,41 @@ await Stopwatch.NormalAsync("|ImageLoader.Initialize|Preload images cost", async
5854
await LoadAsync(path, isFullImage);
5955
}
6056
});
61-
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
57+
Log.Info(
58+
$"|ImageLoader.Initialize|Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
6259
});
6360
}
6461

65-
public static void Save()
62+
public static async Task Save()
6663
{
67-
lock (_storage)
64+
await storageLock.WaitAsync();
65+
66+
try
6867
{
69-
_storage.Save(ImageCache.Data
68+
_storage.SaveAsync(ImageCache.Data
7069
.ToDictionary(
7170
x => x.Key,
7271
x => x.Value.usage));
7372
}
73+
finally
74+
{
75+
storageLock.Release();
76+
}
7477
}
7578

76-
private static ConcurrentDictionary<(string, bool), int> LoadStorageToConcurrentDictionary()
79+
private static async Task<ConcurrentDictionary<(string, bool), int>> LoadStorageToConcurrentDictionaryAsync()
7780
{
78-
lock (_storage)
81+
await storageLock.WaitAsync();
82+
try
7983
{
80-
var loaded = _storage.TryLoad(new Dictionary<(string, bool), int>());
84+
var loaded = await _storage.TryLoadAsync(new Dictionary<(string, bool), int>());
8185

8286
return new ConcurrentDictionary<(string, bool), int>(loaded);
8387
}
88+
finally
89+
{
90+
storageLock.Release();
91+
}
8492
}
8593

8694
private class ImageResult
@@ -129,6 +137,7 @@ private static async ValueTask<ImageResult> LoadInternalAsync(string path, bool
129137
ImageCache[path, loadFullImage] = image;
130138
return new ImageResult(image, ImageType.ImageFile);
131139
}
140+
132141
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
133142
{
134143
var imageSource = new BitmapImage(new Uri(path));
@@ -158,6 +167,7 @@ private static async ValueTask<ImageResult> LoadInternalAsync(string path, bool
158167

159168
return imageResult;
160169
}
170+
161171
private static async Task<BitmapImage> LoadRemoteImageAsync(bool loadFullImage, Uri uriResult)
162172
{
163173
// Download image from url
@@ -173,6 +183,7 @@ private static async Task<BitmapImage> LoadRemoteImageAsync(bool loadFullImage,
173183
image.DecodePixelHeight = SmallIconSize;
174184
image.DecodePixelWidth = SmallIconSize;
175185
}
186+
176187
image.StreamSource = buffer;
177188
image.EndInit();
178189
image.StreamSource = null;
@@ -188,8 +199,8 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
188199
if (Directory.Exists(path))
189200
{
190201
/* Directories can also have thumbnails instead of shell icons.
191-
* Generating thumbnails for a bunch of folder results while scrolling
192-
* could have a big impact on performance and Flow.Launcher responsibility.
202+
* Generating thumbnails for a bunch of folder results while scrolling
203+
* could have a big impact on performance and Flow.Launcher responsibility.
193204
* - Solution: just load the icon
194205
*/
195206
type = ImageType.Folder;
@@ -208,9 +219,9 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
208219
}
209220
else
210221
{
211-
/* Although the documentation for GetImage on MSDN indicates that
222+
/* Although the documentation for GetImage on MSDN indicates that
212223
* if a thumbnail is available it will return one, this has proved to not
213-
* be the case in many situations while testing.
224+
* be the case in many situations while testing.
214225
* - Solution: explicitly pass the ThumbnailOnly flag
215226
*/
216227
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
@@ -236,7 +247,8 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
236247
return new ImageResult(image, type);
237248
}
238249

239-
private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly, int size = SmallIconSize)
250+
private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly,
251+
int size = SmallIconSize)
240252
{
241253
return WindowsThumbnailProvider.GetThumbnail(
242254
path,
@@ -261,17 +273,19 @@ public static async ValueTask<ImageSource> LoadAsync(string path, bool loadFullI
261273

262274
var img = imageResult.ImageSource;
263275
if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache)
264-
{ // we need to get image hash
276+
{
277+
// we need to get image hash
265278
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null;
266279
if (hash != null)
267280
{
268-
269281
if (GuidToKey.TryGetValue(hash, out string key))
270-
{ // image already exists
282+
{
283+
// image already exists
271284
img = ImageCache[key, loadFullImage] ?? img;
272285
}
273286
else
274-
{ // new guid
287+
{
288+
// new guid
275289

276290
GuidToKey[hash] = path;
277291
}
@@ -289,7 +303,7 @@ private static BitmapImage LoadFullImage(string path)
289303
BitmapImage image = new BitmapImage();
290304
image.BeginInit();
291305
image.CacheOption = BitmapCacheOption.OnLoad;
292-
image.UriSource = new Uri(path);
306+
image.UriSource = new Uri(path);
293307
image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
294308
image.EndInit();
295309

@@ -314,8 +328,10 @@ private static BitmapImage LoadFullImage(string path)
314328
resizedHeight.EndInit();
315329
return resizedHeight;
316330
}
331+
317332
return resizedWidth;
318333
}
334+
319335
return image;
320336
}
321337
}

0 commit comments

Comments
 (0)