Skip to content

Commit e04a040

Browse files
authored
Merge branch 'dev' into administrator_mode
2 parents 9823a2a + da4b961 commit e04a040

File tree

23 files changed

+844
-314
lines changed

23 files changed

+844
-314
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
4-
<!-- Work around https://github.com/dotnet/runtime/issues/109682 -->
4+
<!-- Workaround https://github.com/dotnet/runtime/issues/109682 -->
55
<CETCompat>false</CETCompat>
66
</PropertyGroup>
77
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Flow.Launcher.Plugin;
2+
3+
namespace Flow.Launcher.Core.Plugin;
4+
5+
public interface IResultUpdateRegister
6+
{
7+
/// <summary>
8+
/// Register a plugin to receive results updated event.
9+
/// </summary>
10+
/// <param name="pair"></param>
11+
void RegisterResultsUpdatedEvent(PluginPair pair);
12+
}

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 355 additions & 132 deletions
Large diffs are not rendered by default.

Flow.Launcher.Core/Plugin/PluginsLoader.cs

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSe
4848
return plugins;
4949
}
5050

51-
private static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
51+
private static List<PluginPair> DotNetPlugins(List<PluginMetadata> source)
5252
{
5353
var erroredPlugins = new List<string>();
5454

@@ -58,55 +58,57 @@ private static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source
5858
foreach (var metadata in metadatas)
5959
{
6060
var milliseconds = PublicApi.Instance.StopwatchLogDebug(ClassName, $"Constructor init cost for {metadata.Name}", () =>
61-
{
62-
Assembly assembly = null;
63-
IAsyncPlugin plugin = null;
61+
{
62+
Assembly assembly = null;
63+
IAsyncPlugin plugin = null;
6464

65-
try
66-
{
67-
var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath);
68-
assembly = assemblyLoader.LoadAssemblyAndDependencies();
65+
try
66+
{
67+
var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath);
68+
assembly = assemblyLoader.LoadAssemblyAndDependencies();
6969

70-
var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly,
71-
typeof(IAsyncPlugin));
70+
var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly,
71+
typeof(IAsyncPlugin));
7272

73-
plugin = Activator.CreateInstance(type) as IAsyncPlugin;
73+
plugin = Activator.CreateInstance(type) as IAsyncPlugin;
7474

75-
metadata.AssemblyName = assembly.GetName().Name;
76-
}
75+
metadata.AssemblyName = assembly.GetName().Name;
76+
}
7777
#if DEBUG
78-
catch (Exception)
79-
{
80-
throw;
81-
}
78+
catch (Exception)
79+
{
80+
throw;
81+
}
8282
#else
83-
catch (Exception e) when (assembly == null)
84-
{
85-
PublicApi.Instance.LogException(ClassName, $"Couldn't load assembly for the plugin: {metadata.Name}", e);
86-
}
87-
catch (InvalidOperationException e)
88-
{
89-
PublicApi.Instance.LogException(ClassName, $"Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e);
90-
}
91-
catch (ReflectionTypeLoadException e)
92-
{
93-
PublicApi.Instance.LogException(ClassName, $"The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e);
94-
}
95-
catch (Exception e)
96-
{
97-
PublicApi.Instance.LogException(ClassName, $"The following plugin has errored and can not be loaded: <{metadata.Name}>", e);
98-
}
83+
catch (Exception e) when (assembly == null)
84+
{
85+
PublicApi.Instance.LogException(ClassName, $"Couldn't load assembly for the plugin: {metadata.Name}", e);
86+
}
87+
catch (InvalidOperationException e)
88+
{
89+
PublicApi.Instance.LogException(ClassName, $"Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e);
90+
}
91+
catch (ReflectionTypeLoadException e)
92+
{
93+
PublicApi.Instance.LogException(ClassName, $"The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e);
94+
}
95+
catch (Exception e)
96+
{
97+
PublicApi.Instance.LogException(ClassName, $"The following plugin has errored and can not be loaded: <{metadata.Name}>", e);
98+
}
9999
#endif
100100

101-
if (plugin == null)
102-
{
103-
erroredPlugins.Add(metadata.Name);
104-
return;
105-
}
101+
if (plugin == null)
102+
{
103+
erroredPlugins.Add(metadata.Name);
104+
return;
105+
}
106+
107+
plugins.Add(new PluginPair { Plugin = plugin, Metadata = metadata });
108+
});
106109

107-
plugins.Add(new PluginPair { Plugin = plugin, Metadata = metadata });
108-
});
109110
metadata.InitTime += milliseconds;
111+
PublicApi.Instance.LogDebug(ClassName, $"Constructor cost for <{metadata.Name}> is <{metadata.InitTime}ms>");
110112
}
111113

112114
if (erroredPlugins.Count > 0)

Flow.Launcher.Core/Resource/Internationalization.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,22 @@ public static void UpdatePluginMetadataTranslations()
377377
}
378378
}
379379

380+
public static void UpdatePluginMetadataTranslation(PluginPair p)
381+
{
382+
// Update plugin metadata name & description
383+
if (p.Plugin is not IPluginI18n pluginI18N) return;
384+
try
385+
{
386+
p.Metadata.Name = pluginI18N.GetTranslatedPluginTitle();
387+
p.Metadata.Description = pluginI18N.GetTranslatedPluginDescription();
388+
pluginI18N.OnCultureInfoChanged(CultureInfo.CurrentCulture);
389+
}
390+
catch (Exception e)
391+
{
392+
PublicApi.Instance.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
393+
}
394+
}
395+
380396
#endregion
381397

382398
#region IDisposable

Flow.Launcher.Infrastructure/DialogJump/DialogJump.cs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Windows.Win32;
1414
using Windows.Win32.Foundation;
1515
using Windows.Win32.UI.Accessibility;
16+
using System.Collections.Concurrent;
1617

1718
namespace Flow.Launcher.Infrastructure.DialogJump
1819
{
@@ -60,12 +61,12 @@ public static class DialogJump
6061

6162
private static HWND _mainWindowHandle = HWND.Null;
6263

63-
private static readonly Dictionary<DialogJumpExplorerPair, IDialogJumpExplorerWindow> _dialogJumpExplorers = new();
64+
private static readonly ConcurrentDictionary<DialogJumpExplorerPair, IDialogJumpExplorerWindow> _dialogJumpExplorers = new();
6465

6566
private static DialogJumpExplorerPair _lastExplorer = null;
6667
private static readonly Lock _lastExplorerLock = new();
6768

68-
private static readonly Dictionary<DialogJumpDialogPair, IDialogJumpDialogWindow> _dialogJumpDialogs = new();
69+
private static readonly ConcurrentDictionary<DialogJumpDialogPair, IDialogJumpDialogWindow> _dialogJumpDialogs = new();
6970

7071
private static IDialogJumpDialogWindow _dialogWindow = null;
7172
private static readonly Lock _dialogWindowLock = new();
@@ -101,22 +102,13 @@ public static class DialogJump
101102

102103
#region Initialize & Setup
103104

104-
public static void InitializeDialogJump(IList<DialogJumpExplorerPair> dialogJumpExplorers,
105-
IList<DialogJumpDialogPair> dialogJumpDialogs)
105+
public static void InitializeDialogJump()
106106
{
107107
if (_initialized) return;
108108

109-
// Initialize Dialog Jump explorers & dialogs
110-
_dialogJumpExplorers.Add(WindowsDialogJumpExplorer, null);
111-
foreach (var explorer in dialogJumpExplorers)
112-
{
113-
_dialogJumpExplorers.Add(explorer, null);
114-
}
115-
_dialogJumpDialogs.Add(WindowsDialogJumpDialog, null);
116-
foreach (var dialog in dialogJumpDialogs)
117-
{
118-
_dialogJumpDialogs.Add(dialog, null);
119-
}
109+
// Initialize preinstalled Dialog Jump explorers & dialogs
110+
_dialogJumpExplorers.TryAdd(WindowsDialogJumpExplorer, null);
111+
_dialogJumpDialogs.TryAdd(WindowsDialogJumpDialog, null);
120112

121113
// Initialize main window handle
122114
_mainWindowHandle = Win32Helper.GetMainWindowHandle();
@@ -131,6 +123,29 @@ public static void InitializeDialogJump(IList<DialogJumpExplorerPair> dialogJump
131123
_initialized = true;
132124
}
133125

126+
public static void InitializeDialogJumpPlugin(PluginPair pair)
127+
{
128+
// Add Dialog Jump explorers & dialogs
129+
if (pair.Plugin is IDialogJumpExplorer explorer)
130+
{
131+
var dialogJumpExplorer = new DialogJumpExplorerPair
132+
{
133+
Plugin = explorer,
134+
Metadata = pair.Metadata
135+
};
136+
_dialogJumpExplorers.TryAdd(dialogJumpExplorer, null);
137+
}
138+
if (pair.Plugin is IDialogJumpDialog dialog)
139+
{
140+
var dialogJumpDialog = new DialogJumpDialogPair
141+
{
142+
Plugin = dialog,
143+
Metadata = pair.Metadata
144+
};
145+
_dialogJumpDialogs.TryAdd(dialogJumpDialog, null);
146+
}
147+
}
148+
134149
public static void SetupDialogJump(bool enabled)
135150
{
136151
if (enabled == _enabled) return;
@@ -828,9 +843,25 @@ private static bool CheckPath(string path, out bool file)
828843
return true;
829844
}
830845
// file: URI paths
831-
var localPath = path.StartsWith("file:", StringComparison.OrdinalIgnoreCase)
832-
? new Uri(path).LocalPath
833-
: path;
846+
string localPath;
847+
if (path.StartsWith("file:", StringComparison.OrdinalIgnoreCase))
848+
{
849+
// Try to create a URI from the path
850+
if (Uri.TryCreate(path, UriKind.Absolute, out var uri))
851+
{
852+
localPath = uri.LocalPath;
853+
}
854+
else
855+
{
856+
// If URI creation fails, treat it as a regular path
857+
// by removing the "file:" prefix
858+
localPath = path.Substring(5);
859+
}
860+
}
861+
else
862+
{
863+
localPath = path;
864+
}
834865
// Is folder?
835866
var isFolder = Directory.Exists(localPath);
836867
// Is file?

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Flow.Launcher.Infrastructure.Hotkey;
88
using Flow.Launcher.Infrastructure.Logger;
99
using Flow.Launcher.Infrastructure.Storage;
10+
using Flow.Launcher.Localization.Attributes;
1011
using Flow.Launcher.Plugin;
1112
using Flow.Launcher.Plugin.SharedModels;
1213

@@ -515,6 +516,21 @@ public bool ShowAtTopmost
515516
[JsonConverter(typeof(JsonStringEnumConverter))]
516517
public LastQueryMode LastQueryMode { get; set; } = LastQueryMode.Selected;
517518

519+
private HistoryStyle _historyStyle = HistoryStyle.Query;
520+
[JsonConverter(typeof(JsonStringEnumConverter))]
521+
public HistoryStyle HistoryStyle
522+
{
523+
get => _historyStyle;
524+
set
525+
{
526+
if (_historyStyle != value)
527+
{
528+
_historyStyle = value;
529+
OnPropertyChanged();
530+
}
531+
}
532+
}
533+
518534
[JsonConverter(typeof(JsonStringEnumConverter))]
519535
public AnimationSpeeds AnimationSpeed { get; set; } = AnimationSpeeds.Medium;
520536
public int CustomAnimationLength { get; set; } = 360;
@@ -697,4 +713,14 @@ public enum DialogJumpFileResultBehaviours
697713
FullPathOpen,
698714
Directory
699715
}
716+
717+
[EnumLocalize]
718+
public enum HistoryStyle
719+
{
720+
[EnumLocalizeKey(nameof(Localize.queryHistory))]
721+
Query,
722+
723+
[EnumLocalizeKey(nameof(Localize.executedHistory))]
724+
LastOpened
725+
}
700726
}

Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,21 @@ public interface IPublicAPI
182182
/// <summary>
183183
/// Get all loaded plugins
184184
/// </summary>
185+
/// <remarks>
186+
/// Will also return any plugins not fully initialized yet
187+
/// </remarks>
185188
/// <returns></returns>
186189
List<PluginPair> GetAllPlugins();
187190

191+
/// <summary>
192+
/// Get all initialized plugins
193+
/// </summary>
194+
/// <param name="includeFailed">
195+
/// Whether to include plugins that failed to initialize
196+
/// </param>
197+
/// <returns></returns>
198+
List<PluginPair> GetAllInitializedPlugins(bool includeFailed);
199+
188200
/// <summary>
189201
/// Registers a callback function for global keyboard events.
190202
/// </summary>

0 commit comments

Comments
 (0)