From fcbf97275406c9775149be25a8c68c606871f6e3 Mon Sep 17 00:00:00 2001
From: pc223 <10551242+pc223@users.noreply.github.com>
Date: Tue, 13 Jul 2021 03:44:28 +0700
Subject: [PATCH 0001/1335] Testing new search order: System.Search.Rank
---
.../Search/WindowsIndex/QueryConstructor.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
index 20e85bbb598..808f8e7e38d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
@@ -114,7 +114,7 @@ public string QueryForAllFilesAndFolders(string userSearchString)
///
public const string QueryWhereRestrictionsForAllFilesAndFoldersSearch = "scope='file:'";
- public const string QueryOrderByFileNameRestriction = " ORDER BY System.FileName";
+ public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank";
///
From 5d3b0ba2c06ceeea0f9f6cae668068bef0e7763a Mon Sep 17 00:00:00 2001
From: pc223 <10551242+pc223@users.noreply.github.com>
Date: Tue, 13 Jul 2021 04:12:09 +0700
Subject: [PATCH 0002/1335] Should be DESC
---
.../Search/WindowsIndex/QueryConstructor.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
index 808f8e7e38d..c42a6019311 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
@@ -114,7 +114,7 @@ public string QueryForAllFilesAndFolders(string userSearchString)
///
public const string QueryWhereRestrictionsForAllFilesAndFoldersSearch = "scope='file:'";
- public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank";
+ public const string QueryOrderByFileNameRestriction = " ORDER BY System.Search.Rank DESC";
///
From bfee170d0fbeba908d9f228771af7a08351e7a10 Mon Sep 17 00:00:00 2001
From: Sparrkle
Date: Wed, 5 Oct 2022 16:20:41 +0900
Subject: [PATCH 0003/1335] Changed ProgressBar Storyboard (No Dispatcher)
---
Flow.Launcher/MainWindow.xaml | 1 -
Flow.Launcher/MainWindow.xaml.cs | 60 +++++++++++---------------------
2 files changed, 21 insertions(+), 40 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index dc3b3f1454b..7d8c195f33d 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -250,7 +250,6 @@
Height="2"
HorizontalAlignment="Right"
StrokeThickness="1"
- Style="{DynamicResource PendingLineStyle}"
Visibility="{Binding ProgressBarVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
X1="-150"
X2="-50"
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 332e0f5024a..1dd9fe34d6e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -28,9 +28,6 @@ namespace Flow.Launcher
public partial class MainWindow
{
#region Private Fields
-
- private readonly Storyboard _progressBarStoryboard = new Storyboard();
- private bool isProgressBarStoryboardPaused;
private Settings _settings;
private NotifyIcon _notifyIcon;
private ContextMenu contextMenu;
@@ -119,39 +116,9 @@ private void OnLoaded(object sender, RoutedEventArgs _)
_viewModel.LastQuerySelected = true;
}
- if (_viewModel.ProgressBarVisibility == Visibility.Visible && isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Begin(ProgressBar, true);
- isProgressBarStoryboardPaused = false;
- }
-
if(_settings.UseAnimation)
WindowAnimator();
}
- else if (!isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Stop(ProgressBar);
- isProgressBarStoryboardPaused = true;
- }
-
- break;
- }
- case nameof(MainViewModel.ProgressBarVisibility):
- {
- Dispatcher.Invoke(() =>
- {
- if (_viewModel.ProgressBarVisibility == Visibility.Hidden && !isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Stop(ProgressBar);
- isProgressBarStoryboardPaused = true;
- }
- else if (_viewModel.MainWindowVisibilityStatus &&
- isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Begin(ProgressBar, true);
- isProgressBarStoryboardPaused = false;
- }
- });
break;
}
case nameof(MainViewModel.QueryTextCursorMovedToEnd):
@@ -291,17 +258,32 @@ private void ToggleGameMode()
}
private void InitProgressbarAnimation()
{
- var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 150,
- new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
+ var progressBarStoryBoard = new Storyboard();
+
+ var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 150, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth + 50, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)"));
Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)"));
- _progressBarStoryboard.Children.Add(da);
- _progressBarStoryboard.Children.Add(da1);
- _progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever;
+ progressBarStoryBoard.Children.Add(da);
+ progressBarStoryBoard.Children.Add(da1);
+ progressBarStoryBoard.RepeatBehavior = RepeatBehavior.Forever;
+
+ da.Freeze();
+ da1.Freeze();
+
+ var beginStoryboard = new BeginStoryboard();
+ beginStoryboard.Storyboard = progressBarStoryBoard;
+
+ var trigger = new Trigger { Property = System.Windows.Shapes.Line.VisibilityProperty, Value = Visibility.Visible };
+ trigger.EnterActions.Add(beginStoryboard);
+
+ var progressStyle = new Style(typeof(System.Windows.Shapes.Line));
+ progressStyle.BasedOn = FindResource("PendingLineStyle") as Style;
+ progressStyle.Triggers.Add(trigger);
+
+ ProgressBar.Style = progressStyle;
_viewModel.ProgressBarVisibility = Visibility.Hidden;
- isProgressBarStoryboardPaused = true;
}
public void WindowAnimator()
{
From 6f0c2549cea809b0a1e406951f734daf4fb8cc0d Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Thu, 24 Nov 2022 14:01:32 -0600
Subject: [PATCH 0004/1335] also pause animation when exit visible
---
Flow.Launcher/MainWindow.xaml.cs | 151 ++++++++++++++++++-------------
1 file changed, 89 insertions(+), 62 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 245ab4d051f..efa43000bf2 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -36,6 +36,7 @@ namespace Flow.Launcher
public partial class MainWindow
{
#region Private Fields
+
private Settings _settings;
private NotifyIcon _notifyIcon;
private ContextMenu contextMenu;
@@ -50,7 +51,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
DataContext = mainVM;
_viewModel = mainVM;
_settings = settings;
-
+
InitializeComponent();
InitializePosition();
animationSound.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav"));
@@ -60,7 +61,7 @@ public MainWindow()
{
InitializeComponent();
}
-
+
private void OnCopy(object sender, ExecutedRoutedEventArgs e)
{
if (QueryTextBox.SelectionLength == 0)
@@ -108,29 +109,29 @@ private void OnLoaded(object sender, RoutedEventArgs _)
switch (e.PropertyName)
{
case nameof(MainViewModel.MainWindowVisibilityStatus):
+ {
+ if (_viewModel.MainWindowVisibilityStatus)
{
- if (_viewModel.MainWindowVisibilityStatus)
+ if (_settings.UseSound)
{
- if (_settings.UseSound)
- {
- animationSound.Position = TimeSpan.Zero;
- animationSound.Play();
- }
- UpdatePosition();
- Activate();
- QueryTextBox.Focus();
- _settings.ActivateTimes++;
- if (!_viewModel.LastQuerySelected)
- {
- QueryTextBox.SelectAll();
- _viewModel.LastQuerySelected = true;
- }
-
- if(_settings.UseAnimation)
- WindowAnimator();
+ animationSound.Position = TimeSpan.Zero;
+ animationSound.Play();
}
- break;
+ UpdatePosition();
+ Activate();
+ QueryTextBox.Focus();
+ _settings.ActivateTimes++;
+ if (!_viewModel.LastQuerySelected)
+ {
+ QueryTextBox.SelectAll();
+ _viewModel.LastQuerySelected = true;
+ }
+
+ if (_settings.UseAnimation)
+ WindowAnimator();
}
+ break;
+ }
case nameof(MainViewModel.QueryTextCursorMovedToEnd):
if (_viewModel.QueryTextCursorMovedToEnd)
{
@@ -211,35 +212,45 @@ private void InitializeNotifyIcon()
Visible = !_settings.HideNotifyIcon
};
contextMenu = new ContextMenu();
- var openIcon = new FontIcon { Glyph = "\ue71e" };
+ var openIcon = new FontIcon
+ {
+ Glyph = "\ue71e"
+ };
var open = new MenuItem
{
- Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")",
- Icon = openIcon
+ Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")", Icon = openIcon
+ };
+ var gamemodeIcon = new FontIcon
+ {
+ Glyph = "\ue7fc"
};
- var gamemodeIcon = new FontIcon { Glyph = "\ue7fc" };
var gamemode = new MenuItem
{
- Header = InternationalizationManager.Instance.GetTranslation("GameMode"),
- Icon = gamemodeIcon
+ Header = InternationalizationManager.Instance.GetTranslation("GameMode"), Icon = gamemodeIcon
+ };
+ var positionresetIcon = new FontIcon
+ {
+ Glyph = "\ue73f"
};
- var positionresetIcon = new FontIcon { Glyph = "\ue73f" };
var positionreset = new MenuItem
{
- Header = InternationalizationManager.Instance.GetTranslation("PositionReset"),
- Icon = positionresetIcon
+ Header = InternationalizationManager.Instance.GetTranslation("PositionReset"), Icon = positionresetIcon
+ };
+ var settingsIcon = new FontIcon
+ {
+ Glyph = "\ue713"
};
- var settingsIcon = new FontIcon { Glyph = "\ue713" };
var settings = new MenuItem
{
- Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"),
- Icon = settingsIcon
+ Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"), Icon = settingsIcon
+ };
+ var exitIcon = new FontIcon
+ {
+ Glyph = "\ue7e8"
};
- var exitIcon = new FontIcon { Glyph = "\ue7e8" };
var exit = new MenuItem
{
- Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"),
- Icon = exitIcon
+ Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"), Icon = exitIcon
};
open.Click += (o, e) => _viewModel.ToggleFlowLauncher();
@@ -300,10 +311,10 @@ private void ToggleGameMode()
}
private async void PositionReset()
{
- _viewModel.Show();
- await Task.Delay(300); // If don't give a time, Positioning will be weird.
- Left = HorizonCenter();
- Top = VerticalCenter();
+ _viewModel.Show();
+ await Task.Delay(300); // If don't give a time, Positioning will be weird.
+ Left = HorizonCenter();
+ Top = VerticalCenter();
}
private void InitProgressbarAnimation()
{
@@ -320,14 +331,30 @@ private void InitProgressbarAnimation()
da.Freeze();
da1.Freeze();
- var beginStoryboard = new BeginStoryboard();
- beginStoryboard.Storyboard = progressBarStoryBoard;
+ const string progressBarAnimationName = "ProgressBarAnimation";
+ var beginStoryboard = new BeginStoryboard
+ {
+ Name = progressBarAnimationName, Storyboard = progressBarStoryBoard
+ };
+
+ var stopStoryboard = new StopStoryboard()
+ {
+ BeginStoryboardName = progressBarAnimationName
+ };
- var trigger = new Trigger { Property = System.Windows.Shapes.Line.VisibilityProperty, Value = Visibility.Visible };
+ var trigger = new Trigger
+ {
+ Property = VisibilityProperty, Value = Visibility.Visible
+ };
trigger.EnterActions.Add(beginStoryboard);
+ trigger.ExitActions.Add(stopStoryboard);
+
- var progressStyle = new Style(typeof(System.Windows.Shapes.Line));
- progressStyle.BasedOn = FindResource("PendingLineStyle") as Style;
+ var progressStyle = new Style(typeof(System.Windows.Shapes.Line))
+ {
+ BasedOn = FindResource("PendingLineStyle") as Style
+ };
+ progressStyle.RegisterName(progressBarAnimationName, beginStoryboard);
progressStyle.Triggers.Add(trigger);
ProgressBar.Style = progressStyle;
@@ -343,7 +370,7 @@ public void WindowAnimator()
UpdatePosition();
Storyboard sb = new Storyboard();
Storyboard iconsb = new Storyboard();
- CircleEase easing = new CircleEase(); // or whatever easing class you want
+ CircleEase easing = new CircleEase(); // or whatever easing class you want
easing.EasingMode = EasingMode.EaseInOut;
var da = new DoubleAnimation
{
@@ -360,14 +387,14 @@ public void WindowAnimator()
Duration = TimeSpan.FromSeconds(0.25),
FillBehavior = FillBehavior.Stop
};
- var da3 = new DoubleAnimation
- {
- From = 12,
- To = 0,
- EasingFunction = easing,
- Duration = TimeSpan.FromSeconds(0.36),
- FillBehavior = FillBehavior.Stop
- };
+ var da3 = new DoubleAnimation
+ {
+ From = 12,
+ To = 0,
+ EasingFunction = easing,
+ Duration = TimeSpan.FromSeconds(0.36),
+ FillBehavior = FillBehavior.Stop
+ };
Storyboard.SetTarget(da, this);
Storyboard.SetTargetProperty(da, new PropertyPath(Window.OpacityProperty));
Storyboard.SetTargetProperty(da2, new PropertyPath(Window.TopProperty));
@@ -395,10 +422,10 @@ private void OnPreviewDragOver(object sender, DragEventArgs e)
private async void OnContextMenusForSettingsClick(object sender, RoutedEventArgs e)
{
_viewModel.Hide();
-
- if(_settings.UseAnimation)
+
+ if (_settings.UseAnimation)
await Task.Delay(100);
-
+
App.API.OpenSettingDialog();
}
@@ -416,7 +443,7 @@ private async void OnDeactivated(object sender, EventArgs e)
// and always after Settings window is closed.
if (_settings.UseAnimation)
await Task.Delay(100);
-
+
if (_settings.HideWhenDeactive)
{
_viewModel.Hide();
@@ -454,7 +481,7 @@ public void HideStartup()
_viewModel.Show();
}
}
-
+
public double HorizonCenter()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
@@ -536,9 +563,9 @@ private void OnKeyDown(object sender, KeyEventArgs e)
&& QueryTextBox.Text.Length > 0
&& QueryTextBox.CaretIndex == QueryTextBox.Text.Length)
{
- var queryWithoutActionKeyword =
+ var queryWithoutActionKeyword =
QueryBuilder.Build(QueryTextBox.Text.Trim(), PluginManager.NonGlobalPlugins).Search;
-
+
if (FilesFolders.IsLocationPathString(queryWithoutActionKeyword))
{
_viewModel.BackspaceCommand.Execute(null);
@@ -574,7 +601,7 @@ public void InitializeColorScheme()
private void QueryTextBox_KeyUp(object sender, KeyEventArgs e)
{
- if(_viewModel.QueryText != QueryTextBox.Text)
+ if (_viewModel.QueryText != QueryTextBox.Text)
{
BindingExpression be = QueryTextBox.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty);
be.UpdateSource();
From 1b31e9c9685abd0d1d556d260425fac4b5aff165 Mon Sep 17 00:00:00 2001
From: Odotocodot <48138990+Odotocodot@users.noreply.github.com>
Date: Thu, 30 Nov 2023 14:37:05 +0000
Subject: [PATCH 0005/1335] Create Flow Launcher Theme Selector plugin
---
...w.Launcher.Plugin.FlowThemeSelector.csproj | 37 +++++++
.../Main.cs | 91 ++++++++++++++++++
.../icon.png | Bin 0 -> 6625 bytes
.../plugin.json | 12 +++
4 files changed, 140 insertions(+)
create mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
create mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
create mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/icon.png
create mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
new file mode 100644
index 00000000000..ba0ddd6ab20
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
@@ -0,0 +1,37 @@
+
+
+
+
+ Library
+ net7.0-windows
+ true
+ false
+
+
+
+ ..\..\Output\Debug\Plugins\Flow.Launcher.Plugin.FlowThemeSelector
+
+
+
+ ..\..\Output\Release\Plugins\Flow.Launcher.Plugin.FlowThemeSelector
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
new file mode 100644
index 00000000000..6fd6472dbf6
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Flow.Launcher.Core.Resource;
+
+namespace Flow.Launcher.Plugin.FlowThemeSelector
+{
+ public class FlowThemeSelector : IPlugin, IReloadable, IDisposable
+ {
+ private PluginInitContext context;
+ private IEnumerable themes;
+
+ public void Init(PluginInitContext context)
+ {
+ this.context = context;
+ context.API.VisibilityChanged += OnVisibilityChanged;
+ }
+
+ public List Query(Query query)
+ {
+ if (query.IsReQuery)
+ {
+ LoadThemes();
+ }
+
+ if (string.IsNullOrWhiteSpace(query.Search))
+ {
+ return themes.Select(CreateThemeResult)
+ .OrderBy(x => x.Title)
+ .ToList();
+ }
+
+ return themes.Select(theme => (theme, matchResult: context.API.FuzzySearch(query.Search, theme)))
+ .Where(x => x.matchResult.IsSearchPrecisionScoreMet())
+ .Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
+ .OrderBy(x => x.Title)
+ .ToList();
+ }
+
+ private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs args)
+ {
+ if (args.IsVisible && !context.CurrentPluginMetadata.Disabled)
+ {
+ LoadThemes();
+ }
+ }
+
+ public void LoadThemes() => themes = ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension);
+
+ public static Result CreateThemeResult(string theme) => CreateThemeResult(theme, 0, null);
+
+ public static Result CreateThemeResult(string theme, int score, IList highlightData)
+ {
+ string title;
+ if (theme == ThemeManager.Instance.Settings.Theme)
+ {
+ title = $"{theme} ★";
+ score = 2000;
+ }
+ else
+ {
+ title = theme;
+ }
+
+ return new Result
+ {
+ Title = title,
+ TitleHighlightData = highlightData,
+ Glyph = new GlyphInfo("/Resources/#Segoe Fluent Icons", "\ue790"),
+ Score = score,
+ Action = c =>
+ {
+ ThemeManager.Instance.ChangeTheme(theme);
+ return true;
+ }
+ };
+ }
+
+ public void ReloadData() => LoadThemes();
+
+ public void Dispose()
+ {
+ if (context != null && context.API != null)
+ {
+ context.API.VisibilityChanged -= OnVisibilityChanged;
+ }
+ }
+
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/icon.png b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..704e9474eb29ffa1fcaeff9e24c60ee35155afd5
GIT binary patch
literal 6625
zcmV<786M_|P)?L~#_W&dT5+Df~tR%E=9kt)zb>9h)AYqsw`j&HD=X&5T
zo_x;9xxe?h&+}kl&}CiLWnI=~UDjn?)@5DRWnK1+nBx`2yKb4XkC_>=6)stFZLT1&5Y;r?b&_2|)x3Z7H-nk27~+~O4{^jFQ6z?V_@jHd8Y)Ztgd
zAyMTCRj|KUDX@>PUTc*idEMZjU{-l}$t_2|z%@sHoj|YmPJvGYPzAgAO4!Cpg|=~(
zvkidf4E|TmHCH~yHAlgAV>N=;8~pSZ;3sQ`UmpOwI1+?P*v3lIY~n?I4E~qQ?ULNw
zEvGJug70wnwavnJY!iGbb?az}+$Kgk!{Avr$18Zzja9eDm8E#l;qdDN&>Z}v7U0L%
z!&e5tCPwAa5?Duz_dK&D$u;Z0rtYk|EH_pi9v8l6t`J_Of!JC7CBBv~#whgirZXG4yg=vvTth_=(NKS1&!y!Y3XnCP6rBumjH<
zJoN@V@0P3h#XYwU?Sh}J8GvbdsW|e$3ju#E!;$+-;r-_#?5&&M5P+59iC82Yi`iu(
zF@zP}Dtw1F!j0o8{&s@M9l^Z(R>RQUyPpxCoY^qE8K;
zMjMhMdEK3*h|?85GgF3n>=W3nn1>&JUx0moETpC9JHY_6V;
zbKXJ(eqW=4zeG3=^UFuk>>pn|6vNqrF*xr-IK+#!YJI1WDhxjQCx#rqPp|Gi
zaxj0Yg!67;V*u9PhQ*4ju<|R?4*x<0EQp5)S9dmhgQ-Dy!HrcHqA&PNqU}?pSSp->
zRpLolEtyQq4Y`s<*Gn`Wi-lt`pFavSN{3@o$%h!l@x+IBJm7w7C>-KN6ns!ztik@-CqO74-zt
z2VqdYE1a)Rhkcv~4i}}Gax+c}hhr6R*(U|_=W4kAQUm7CRdCrSq1o^7RVi$@7GdCq
z0$6^217=Gv;r)e~=>PQ%ScO&8*L_%qs>2sjHwzMM?==4Ith&_{ewzazZ+(|b0+1}l
zh-*HyzRxQsK8ix0Q#JxKONV1BZx|+&e2CE;CH%n!Zg9EHfL;0zu#c;NJqduC+_a4q
z!{LW=IDIFC^Ij1cdqr^GBZAX+0yyj{gWZ?KH2dqzPyfX%^qrrMK1(xTbwSVopJsnZ
z1uW{}2h#w^tb#hBgUY-tW4N;v_gaEKI=2MJZ)`;2EnC#xcoTJ3-bMk-3CFTFV`NrI
z^8v`Hr2%kBW@A$ESWMv#qrk~^GWR12eoWB^7{MNb4+}joINue_+YH!W8wA_feAvfU
zz@8`_^<8dM1?+Z|&^k|m*Sq}=9_+Ri!-l|Lmj}yL*Ol4-Nf!FdNkOmKiLg9h-Yk4`
zC486#3efLd`NAg(-y=izANSlkUQ6(|T|0r_xo_ZM(erp%@B;q2^)LK&^(8#WeHjn3
zUV$vN8#bk#YPQG2NU4N#f*5WYAsAis0mc-0(o!>uGlVX-9~BOQXMsCB@|a-UV!-}}
z6KoRB!7fSwyI7H?)+hQtN(k%CcjzKZN{!Mv^mprx1vK*sd~>hM=(i{vedndYbVeeK
zr^Uk}xD1vdLM8l=Ch&s<=uZQ{Pk*8TaAVa)wgi9ce
zqxY;Nm`sU>@qz?c1eL+!yg)1b{^$7Ucc%RB_k+s&JsJ3y>gKdqcCw35m;V+X7QUc#
zlKr>;g}<)9hzFNn!h@Wb@gU%+zJpEFE!aht!!}w7yBHBIKN`E-7%>fiD6NSRhsqvm$1<9(<~MIWb~RE52Fdu=)E}`<}?8OM)<)^;1fT~N8dB0t2!J$
zGh6nKd#*yFb-~S+coZFE(a>_A9ub{wnS#{~Px%zJ_}-ufs2H3z=rn
zY%Ql$!-;IFE{fq0Cxm@;Iqaj#U>C`QT?Fw`*hZAm%x{D*eYCG1BY|~<00RPf=%EvOx4
zRxJuI+2OBiFVc*sPJX`f5*}Q7xiR}wU&Z~z*KjZHb=-@31GgfXwCp@`sFGX_rvwQc
zFN)wm7S~t->|>N}7cEfMd{TDQ;m2zps*wJUb%YQDLd#&`ork^)(rKnsl`}7mF1DoP
z^qQUklgY6#8Xtw8W5Up9_hp!$<-#nmtX25$pDst=)8(}tx-)jqQFyrLDE@9qYBJNS
zpY`(8g4pR~<;Xu9#WRn#yqFSG*
z9kSq(n%_`%wDk3@BP%d4jE?~!r7-*H7EI?P(?ym*C*{VNfG1f$HUd4zN1)HQmtc0L
z1ZHP>Fb^u%gdf-hKFNL(fKz2KJ;k%@umHHR>QYFB~YE8?BDzv3s35Nut^DEol*N+loV3+^{E|kM6mP9P5Mgx$a
z>WKSkuPW<&y%X?c(M@UsKm1MH4S5Te(DZ+qIJ_ejGgJm!e
zmgkCLd6ol2C}ox2y_qVOvNjqzb@K3#0dH=sQ;Jk3oqw0fvQ`#J(xhLqD?F4<@it#3}D
z6EBCk3Vc)e{Z#PZZw7wv6Q$_&YiYLL1K^gUNNj6^jg%lpvKSlVkK=Ci8%p5h8uf+}
zeE6HV8>%cjcZ1%-f6x5~Yr_NJ7%!sVfVRTdHb&C0=xV@kp|5|T0+t~HJ4P
zY!k(Es;sf}sNkCt|CO7sSNJYD^8Ri)^1s{K-E_&Q0V7okMv@pCV~(Rbyr(kTX~wI-
z2fu|s1K&pFITNf6I}XRV3gw0?sZysIo_536?CZC>(Q1^NP2krD;8z|@j`Pa&8UR<8
z!n<9qWztTd-vS93i6RV(y9wWjjktN9iJG9Es1EFjn}M!46tW3Jqi-sAxfjK7Ops8y
z*=G3hEx>PBbekNex7gQjEBtb;@J$1F=oP@N*6%4-jzZS%zCPK}rYcL3bD{`N@d7x-
z@!=F#4#(Jf=fg3+g2E@Y-zm9DPXkn~!`Ir^4;H}g6d&{Ulwj-n0_^_mI=)_f32Rs8
zV)D)#unOR*DV`?qezm%=Hz
zQmyQC&LAG~ufPVB}v?q?Z7=
z=g3F41b;+=2;RG6knyQEIOBJsaO`#@&-)4cc7RJf6SLCAGH;wBQ}Hk@fRrmXajDK+>8~zSseo3Ru{S1
z+=
ze6$3HM@o|Q6aYnbbMV*t=Rz=kCxtH+N9)8+~hiqVZ30v2|WDRXL>8)H_*px6e+*wpsB?_|qb=e#!-`nHYps
z<43Xew?+)NpM{yH3Gqqb7$#7XAY!>=ztMIWvM
z`-3$o9I_e(gI3|&Z9&RKSC0=%42+h94UCWuv56PGMtne|$kQrZ9PtQzEn2@}qjk0n
z@1Npg`I2M``pa1fD!)j7-#RlEo2N%Nz+XEl2%k?lgB4?c!^~NMF!mz>D560i@C^?a
z!{~6yXq^M#mZ@0WT#F%f?vJ$At9w2Cl3@gXWA@(}{5kRmtwi*cui>Q8VyJ1m)^Bd3
z6(#vX+kIPxi?_6<^)*_{BmgJ57`Hi#)^`GX^NeVE-84Olg5Nkb4C^O{(7I3Ik2?vk
zF##C5Iu=HLg)lx+1fwI30qEg-r?<`laLrPD|40DRs!%XyD}~J+u5t=~BZ}4FlkC4U
zjDm&7iy19~dnOYwg}GLn|U%n&Hvt>ywu9ZzZtw%g34-;n*-Wi~`><
zg?K0hzjjhER!=;KRpXVJPvCzt{y6&laves#g)kynuYzyrTcps-V@%9!d6fzJUGk6v9Jys&meK~SHS1a2M+D67Nwtb^T%1&$dZXPE3
zK?uoZ)Hc>-Rm$MV|l;+`eI9&Ez0jW=OWLnHWeHTLOONxKmg@_5{2}AIFkWN8zwF
z1xAPRVd%$hgzs03o`*QmI>T25;D*LVD}(fQDv>aAFN%h)qrj;Ttp~prY)=CJb0z#i
zO8B?jmLYP&PGz$#u~KKPZ`FqJKl8B4H(G+|WF68Y8`0*;-Bz!Rx04Tpqec1zioi3VzPuRamqyo(@krs7A&0*w^2p
z75;g_Hk}St0=O_eRtyvWBA6UuD>qtXq4gus$(5}vJ5Avq;-H&1+g5J@aLJTcKhoKx
zqk_tBf%C-*c!m_>n~kRsF>xny2d$(YHhw$4TK^k7g6_aRny(xaC)rQtciN-%qg&qP
zT833b4hR!{K-L7}W+9@XH1nI&`mK$TXzA;l_?N)MzgW4^I#R5m^&8;R0C3RVhjU49
z@KpgQYqqUSTFRt{pD3n>Dh{!HI7FAjA-WXyQN+odX1Q{7upWMbD*HR|P{l&qM(c6m
zAJc5Gslzu^!B=KK2R#mQ(ER{=iCzQ1%#`J6?dzwKv2iI40-0nWXS!r?)*)8u%9{T;
z@TD!nZ&Pboi`LgR!=r>>+79@|8t~sc$U%<-oVs`RbM*U+7&BAGYVkchq^n7e5fdeF
zB-0GU8|F5}4K@FX_Vt5W(E8fotFpi8p-KaMwH}YU+-!hPvfrohJH5hJ2B7w0n_q%N
zjuexslp8J5TF`lbN}?zD&Cl>O51-c#_(cuyd-xQ}jepF0NACe(WXO(o+)I$8YVak0
z4~&wWCi>nswDxVs2;sl2BZLkEBE;Vf2p7paYKBJxen1oW{!QRFqj;3?*+lt#rFZx=
z0O_(V9r+R@8=~`LBm$cliHEj(u#OVjuBI86I``+;+g{pu0D_=B=N3Z+A!l
zm>D%=JMtw+)-e*ceORSoYxiLlA?#&&p+eCy15|2@ZhPS$V56H)p_f5NnOkP1VY9D&
z)W=JZqNT;QkyS=*y%)<1!d)#Ms&tUtY^wDe;M3AmnBC#;3}U3!6l;6u=HtEuiIg3y
z2w|`G+=pebz`nDzesl12>_zIP$ZU`O5)
zdb=+0oO5b*kzQtaqNI;~P+<`yaBU5~wudG3qxI|Ivn&6zujt9XXWBWXda1EMqbhAlw5uDv9*4*^rS9op??V9)+|VH_i-PV
z&{^wK_-wrEeP^3NXPHxKt-V8H^?%zYH#J%e2X%qpFQ}rMS+JnEGqpbPclQ_i8g#Zf
zBvwtdPpG=zCaoVW`P({LvQwA8XB8xQy?>D4a@*x*^AAgCQ#^)k(E2L)Ay3Ua;T#jI
z7dQ1X*TeTxQAIF|Bv=O7~KI{
z|E$5`D>^6AGil~Q{Led6>v!MJ)=4-#^VUB|kfc@dXninRclg~76yELb&0cKqPq%*O
z_}nM1^}X4`?)y2+&i?FAh4nwn|F14uzrFCg9Vm?G{!2-Z&i>p_jrBWMF6l6>uLi&S
z0d`F{pTfDF{du1{>vx8Ku0yrH5Bu-#KJ1`(4;S?8?9cjCTK_YAm-kPX{jDGPk7#{X
zPjB|1&i;%~z4bX=ept_1pVjkV;bWae{3ESj4Cm$Er^=#qg6~^&|Gh&+XL|UsT{`>o
zJewAT7y6vw?d*Mm_eWc`eow!mKYRKXNA&PzFEBpZ0mD-NL^J-i+^AOocZ11sZgQ^x
z9^d#F_nz@FuFU9YNr{nv@g>6}C8rIK6s>*Fk3G1XPu@S{|37wFmvvc}by=5nS(kNL
fmvx!JvuOVh5a5F)ThAaT00000NkvXXu0mjfwnX-y
literal 0
HcmV?d00001
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
new file mode 100644
index 00000000000..f275d129c47
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
@@ -0,0 +1,12 @@
+{
+ "ID": "4DFA743E1086414BAB0AA3071D561D75",
+ "ActionKeyword": "flowtheme",
+ "Name": "Flow Launcher Theme Selector",
+ "Description": "Quickly switch your Flow Launcher theme.",
+ "Author": "Odotocodot",
+ "Version": "1.0.0",
+ "Language": "csharp",
+ "Website": "https://github.com/Flow-Launcher/Flow.Launcher",
+ "IcoPath": "icon.png",
+ "ExecuteFileName": "Flow.Launcher.Plugin.FlowThemeSelector.dll"
+}
\ No newline at end of file
From 49a71d7d53a3c66a3feac30f743f625f47059f83 Mon Sep 17 00:00:00 2001
From: Odotocodot <48138990+Odotocodot@users.noreply.github.com>
Date: Sat, 15 Jun 2024 12:16:36 +0100
Subject: [PATCH 0006/1335] Move Theme Selector into Sys plugin
---
...w.Launcher.Plugin.FlowThemeSelector.csproj | 37 ------------------
.../plugin.json | 12 ------
.../Flow.Launcher.Plugin.Sys.csproj | 1 +
.../Images/theme_selector.png} | Bin
.../Languages/en.xaml | 4 +-
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 29 +++++++++++++-
.../ThemeSelector.cs} | 24 +++++++-----
7 files changed, 45 insertions(+), 62 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
delete mode 100644 Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
rename Plugins/{Flow.Launcher.Plugin.FlowThemeSelector/icon.png => Flow.Launcher.Plugin.Sys/Images/theme_selector.png} (100%)
rename Plugins/{Flow.Launcher.Plugin.FlowThemeSelector/Main.cs => Flow.Launcher.Plugin.Sys/ThemeSelector.cs} (72%)
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
deleted file mode 100644
index ba0ddd6ab20..00000000000
--- a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Flow.Launcher.Plugin.FlowThemeSelector.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
- Library
- net7.0-windows
- true
- false
-
-
-
- ..\..\Output\Debug\Plugins\Flow.Launcher.Plugin.FlowThemeSelector
-
-
-
- ..\..\Output\Release\Plugins\Flow.Launcher.Plugin.FlowThemeSelector
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
-
- PreserveNewest
-
-
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json b/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
deleted file mode 100644
index f275d129c47..00000000000
--- a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/plugin.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "ID": "4DFA743E1086414BAB0AA3071D561D75",
- "ActionKeyword": "flowtheme",
- "Name": "Flow Launcher Theme Selector",
- "Description": "Quickly switch your Flow Launcher theme.",
- "Author": "Odotocodot",
- "Version": "1.0.0",
- "Language": "csharp",
- "Website": "https://github.com/Flow-Launcher/Flow.Launcher",
- "IcoPath": "icon.png",
- "ExecuteFileName": "Flow.Launcher.Plugin.FlowThemeSelector.dll"
-}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index c7a72218907..bba46638487 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -38,6 +38,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/icon.png b/Plugins/Flow.Launcher.Plugin.Sys/Images/theme_selector.png
similarity index 100%
rename from Plugins/Flow.Launcher.Plugin.FlowThemeSelector/icon.png
rename to Plugins/Flow.Launcher.Plugin.Sys/Images/theme_selector.png
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index 91f32a844f8..2a266f8f651 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -27,6 +27,7 @@
Flow Launcher Tips
Flow Launcher UserData Folder
Toggle Game Mode
+ Set the Flow Launcher Theme
Shutdown Computer
@@ -49,8 +50,9 @@
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
Toggle Game Mode
+ Quickly change the Flow Launcher theme
-
+
Success
All Flow Launcher settings saved
Reloaded all applicable plugin data
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 1ec07915d2b..0dbb46be9f2 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -18,9 +18,10 @@
namespace Flow.Launcher.Plugin.Sys
{
- public class Main : IPlugin, ISettingProvider, IPluginI18n
+ public class Main : IPlugin, ISettingProvider, IPluginI18n, IDisposable
{
private PluginInitContext context;
+ private ThemeSelector themeSelector;
private Dictionary KeywordTitleMappings = new Dictionary();
#region DllImport
@@ -58,6 +59,11 @@ public Control CreateSettingPanel()
public List Query(Query query)
{
+ if(query.Search.StartsWith(ThemeSelector.Keyword))
+ {
+ return themeSelector.Query(query);
+ }
+
var commands = Commands();
var results = new List();
foreach (var c in commands)
@@ -106,6 +112,7 @@ private string GetDynamicTitle(Query query, Result result)
public void Init(PluginInitContext context)
{
this.context = context;
+ themeSelector = new ThemeSelector(context);
KeywordTitleMappings = new Dictionary{
{"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
{"Restart", "flowlauncher_plugin_sys_restart_computer_cmd"},
@@ -126,7 +133,8 @@ public void Init(PluginInitContext context)
{"Open Log Location", "flowlauncher_plugin_sys_open_log_location_cmd"},
{"Flow Launcher Tips", "flowlauncher_plugin_sys_open_docs_tips_cmd"},
{"Flow Launcher UserData Folder", "flowlauncher_plugin_sys_open_userdata_location_cmd"},
- {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"}
+ {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"},
+ {"Set Flow Launcher Theme", "flowlauncher_plugin_sys_theme_selector_cmd"}
};
}
@@ -426,6 +434,18 @@ private List Commands()
context.API.ToggleGameMode();
return true;
}
+ },
+ new Result
+ {
+ Title = "Set Flow Launcher Theme",
+ SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_theme_selector"),
+ IcoPath = "Images\\theme_selector.png",
+ Glyph = new GlyphInfo("/Resources/#Segoe Fluent Icons", "\ue790"),
+ Action = c =>
+ {
+ context.API.ChangeQuery($"{ThemeSelector.Keyword} ");
+ return false;
+ }
}
});
@@ -441,5 +461,10 @@ public string GetTranslatedPluginDescription()
{
return context.API.GetTranslation("flowlauncher_plugin_sys_plugin_description");
}
+
+ public void Dispose()
+ {
+ themeSelector.Dispose();
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
similarity index 72%
rename from Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
rename to Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 6fd6472dbf6..24d17486e91 100644
--- a/Plugins/Flow.Launcher.Plugin.FlowThemeSelector/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -4,14 +4,16 @@
using System.Linq;
using Flow.Launcher.Core.Resource;
-namespace Flow.Launcher.Plugin.FlowThemeSelector
+namespace Flow.Launcher.Plugin.Sys
{
- public class FlowThemeSelector : IPlugin, IReloadable, IDisposable
+ public class ThemeSelector : IReloadable, IDisposable
{
- private PluginInitContext context;
+ public const string Keyword = "fltheme";
+
+ private readonly PluginInitContext context;
private IEnumerable themes;
- public void Init(PluginInitContext context)
+ public ThemeSelector(PluginInitContext context)
{
this.context = context;
context.API.VisibilityChanged += OnVisibilityChanged;
@@ -24,14 +26,16 @@ public List Query(Query query)
LoadThemes();
}
- if (string.IsNullOrWhiteSpace(query.Search))
+ string search = query.Search[(query.Search.IndexOf(Keyword, StringComparison.Ordinal) + Keyword.Length + 1)..];
+
+ if (string.IsNullOrWhiteSpace(search))
{
return themes.Select(CreateThemeResult)
.OrderBy(x => x.Title)
.ToList();
}
- return themes.Select(theme => (theme, matchResult: context.API.FuzzySearch(query.Search, theme)))
+ return themes.Select(theme => (theme, matchResult: context.API.FuzzySearch(search, theme)))
.Where(x => x.matchResult.IsSearchPrecisionScoreMet())
.Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
.OrderBy(x => x.Title)
@@ -46,11 +50,12 @@ private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs args)
}
}
- public void LoadThemes() => themes = ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension);
+ private void LoadThemes()
+ => themes = ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension);
- public static Result CreateThemeResult(string theme) => CreateThemeResult(theme, 0, null);
+ private static Result CreateThemeResult(string theme) => CreateThemeResult(theme, 0, null);
- public static Result CreateThemeResult(string theme, int score, IList highlightData)
+ private static Result CreateThemeResult(string theme, int score, IList highlightData)
{
string title;
if (theme == ThemeManager.Instance.Settings.Theme)
@@ -86,6 +91,5 @@ public void Dispose()
context.API.VisibilityChanged -= OnVisibilityChanged;
}
}
-
}
}
From 7a0be2c6103939312eeead86c3a1e01a3d618a3f Mon Sep 17 00:00:00 2001
From: Odotocodot <48138990+Odotocodot@users.noreply.github.com>
Date: Mon, 17 Jun 2024 16:50:00 +0100
Subject: [PATCH 0007/1335] Remove Reloadable from theme selector
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 24d17486e91..75825042153 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -6,7 +6,7 @@
namespace Flow.Launcher.Plugin.Sys
{
- public class ThemeSelector : IReloadable, IDisposable
+ public class ThemeSelector : IDisposable
{
public const string Keyword = "fltheme";
@@ -82,8 +82,6 @@ private static Result CreateThemeResult(string theme, int score, IList high
};
}
- public void ReloadData() => LoadThemes();
-
public void Dispose()
{
if (context != null && context.API != null)
From 9786fd7bab67e575925c7e908e43c227e1a1c6a4 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 9 Nov 2024 20:06:33 +1100
Subject: [PATCH 0008/1335] add sponsor to readme
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add sponsor 🥇
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 0f1e084bdd9..02ffc79328a 100644
--- a/README.md
+++ b/README.md
@@ -350,6 +350,7 @@ Or download the [early access version](https://github.com/Flow-Launcher/Prerelea
+
From 09d8c1db0ef161560be91ac41bb7e736429c274b Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 11 Nov 2024 14:24:57 +0900
Subject: [PATCH 0009/1335] Add line for Highcontrast mode
---
Flow.Launcher/App.xaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Flow.Launcher/App.xaml b/Flow.Launcher/App.xaml
index 13e943c95ef..17c0ae0d50a 100644
--- a/Flow.Launcher/App.xaml
+++ b/Flow.Launcher/App.xaml
@@ -20,6 +20,11 @@
+
+
+
+
+
From 5a80adcbfec1309b537721ab9e98f9d07187c135 Mon Sep 17 00:00:00 2001
From: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
Date: Sun, 17 Nov 2024 23:59:43 -0600
Subject: [PATCH 0010/1335] Send a reload request with ctx when reloading
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 5a6633525e7..ae4fd639d07 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -133,10 +133,16 @@ private void SetupJsonRPC()
RPC.StartListening();
}
- public virtual Task ReloadDataAsync()
+ public virtual async Task ReloadDataAsync()
{
SetupJsonRPC();
- return Task.CompletedTask;
+ try
+ {
+ await RPC.InvokeAsync("reload", context);
+ }
+ catch (RemoteMethodNotFoundException e)
+ {
+ }
}
public virtual async ValueTask DisposeAsync()
From 4fbd74a14d14cc680a85d25b18a30cdc200229b1 Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Mon, 18 Nov 2024 17:07:57 +0500
Subject: [PATCH 0011/1335] [WebSearch] Add copy URL to menu
---
.../Images/copylink.png | Bin 0 -> 3242 bytes
.../Languages/en.xaml | 3 +-
.../Languages/ru.xaml | 3 +-
.../Flow.Launcher.Plugin.WebSearch/Main.cs | 26 ++++++++++++++++--
4 files changed, 27 insertions(+), 5 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.WebSearch/Images/copylink.png
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Images/copylink.png b/Plugins/Flow.Launcher.Plugin.WebSearch/Images/copylink.png
new file mode 100644
index 0000000000000000000000000000000000000000..3218c94c9a0fb53f923197042c20cc994b22d5c9
GIT binary patch
literal 3242
zcmbVPc{G%JAD=tJWGP5d`;006Mf
z%F@({KOWq?MTPm#B1-Tue^6kXd9a=7eryh&Nd{m^bOISUU=w4IAs5Xjppw~m5SJQ6W1+c5;P1R>{(N&A3I=^QVFwz4
ze~9w1bpYY$OfpDc2M!^^U@(wAN{56e;E4o+HV6Sjz@acC6pnCc!_ndB>d=|~P&f*Og2E6`1OmdhfUv@7Y&;i2V=4b)
zFeS5yObUZdq0>N{jCcY)glz=oOZ^c8m0@f97cq_XGgJJWLAiJa6s`kO^MILzqPVf%qx^0`rsi&yF??`D)PiObY*0@Ij_@VhEK?V_TUT
zf%$KANE8y9Kt%ELNYI1m8o&tRCj^g|Fyzj*!*uMgKVI0Q2{
z)jObzfWysjSU3`8pnnJpGe3Ys=^irpg|(uw*mxR|{L43m@B1ef_m5aKj!DL|=}Z?o
zJ?K{%I0VqybXEYJ0Yd2Nz(5-A6dH-nVQFrj(T|W#$xKQpnPkqSQ$gR8jHdjJfd4J{
zA9&LLn>;9A6m+vv{;P6+ZSl)-bNW{!@E3oz5}C&DA11$1xP|ym06?_e$`tFu9hmb9
z3{rHL|JrdSW9Z}OB!jAM2iIdRdKzXiLOjr3s*q@asb!QUews1i(GS7k+Vs9`Nf-HN1cJ9jjKGZ`#7*>UUSKHZAU
z{^5}E2VFxMLm3!W{k-9Ol)vBEjN4h6j}UZQfy+Wju>hGDDp#!<5VX)P?7$)?=S+0s
zR^N>1v&p4?cA7OF-Frt@27x2$=M9dEA}^Mv7^Io~21K)g$~Ux~PJHBbt!vgy3^7MO
zGFxVz?lGVE;<>gV7kGazg;nU~(^7pb{iLGZ;@dSZY3_m5FUu-dr6GU^kHu~p6M}%9
z=gv60iA&B3&ANfldyd!dI=JV;$Vl}K+lHw)wb|mZ-WB)eejOk89$3&R!UH4wlG0-@
z+-afv%Hl31wpM)+?w?g#2!{Px=P5QNFK3c9c|28WQTdf|L(Ak;W?b~|w?E}__x7q~vB76kG(~!W{
zWN7I>X3mX-YZO|>CWH)Ue
zN!qwATCz(vj*@7!hqXmk?s&M>X8_Q+U`0+n%-Yce!7V@X+RQX^X)Sx#c72GMK+~W^
zSw8oLn;^R2^joY1&U&{$XwWytvR;Zc^SR)iP;q!fRS)1=FUYJ{^V!ovNcDT0A;+d~
zWkL4B-9d%nX)?gtVwB9@A)^{r_5cg8I0ukxnIt?{&
ziHyXTgDU$m+R@;7oV9$?TV8nyuBJ11Du%=$iAufAvI0_-279GDl0BZ;C~ox(s}!@!
zj?Z}fsznO4+@A2|$waa?^{F3q#
zaepN}u*i#GEgrn`Y_E!4LmpiBNo!g9j6ERE{q=T>Y`cO#<8G$r`3b^CmzCWw)N1?l4@D(uH~+8MJB-5A%Rs?=PORZ0K)NvL`-trV!XR)
zv+jglU*Q5Azwo?#!$yX?V_{C5doEsfp`(|B{^V2B<@qV-g%C=l`OA?O%;2;f%za%W
z(e_}3;qG;pTG!|+7yf*#MdMYCe*y#VdpcaAxaagQ6?)n9UX1=7XtWxI@zwA$vl8L8
zmRvd~FT1URd+0N&-*ZdVwZnDxDkiDB_R7v*%rx9*9`8~b4rsH@m~2^53@HjQSKGK8
zZKCOOe>Jcugi#yXIKS2ZNwdR}h|L)(lWiZ`j3i&yf|2@FlHG2%L!g&1R-PT@#RE`M
zEv71|{C!g8N4i*(aet@hk;a-XqQ*>q(-TviAb8_pc%M*&R&us{cTrhHvy+WYd_=^{
zQ0i1o$%fw2f~U~Bn~K3B$i2}$lj}`bS-X~8bxZRzg3F>_JH*$KICb&YubWx}a0lb}
zO(|!D)>cGN{amUC5sc6b}=xKmfx7IK>;*i-p9JT@K
zH_$7BaqreziZn^Os)aCxVS#zm$!l
zuUJj{_#=4Zlp}|8)y3rB1pq!lgjQ!&eeH9{6LN$LctX5tmxMp6h~vkfLp{8%X%3&>
zLx_qm`Ea^ucE{0WL}b^_qI2G-04cGI>cU|thbLoI(StQve{=`bY?!%xv{vKZ=MaTZ
zo$>%x&0E`%>(Mf=#cb`P>f@vgbBu*Zs+X+?IcFK!i6(uf`n2p1ISSX#^gMe#v5>h$
zS$}vcV^vUA{$cv{7at!T=g^9dxd&yZ&XtADR76Q9_r<=vvSq+ou)I%!zAU^x?w~*o
z!axGQs#m&|rWPnf4-xv8QxXHPANnhaGrW#LW;V3#DlR^`T5T^RbvW)IJt6(LCeY9|
z)?&hr9eO;d_rct>g^HztASZ@}I+WvU5hr1-+?#BimhByRcmA4vd-3~_#x2r?&z3rO
zP?uNFTABeS6w>8%z~9%lewVX`mbTvfpg%Sy$l5b3qIbai
z5>jtLXHB(NL*P25d}i$W8^o%@Re?{0K!^U}kct-ol%S#3yeWb0WYJ5;fxxZ^zV+
z+80`sm^EoT)5|;|CbA2dq`CIQR=o41gu^vARhjX_Nzxh5cl%a$vr~F&<)wb%Qj0L&ek#|SL9;3CBzqxHo9`S_dpRU}0
z;=+dgg>NFS)(Gbx538!xnI(R6tDLZzc=%3aoRt|ge-pceaaf+UNdSR-V9zhDT2PS?6Zl;^7=3BY^4=-g0BR6Bu0mw?bMn6F$}>y7n?`
zk7oGj4fu9CPhRPflG1o!xo-Fn2d~gL15BOe>ZCc;)?EfIvdWe-V?{efy-V;-uFLtt
zD@|&S(UUtdH%pu~Za%jbXVe=QF8j5pt7;!8tr$6Vnn>#^Xk+0U=G1-U
tZoO{?HSJz0(Q3fW&j#(;6%(K^!0cZ>DW!Smyf^
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
index a2ec9405a16..b8757f67b1a 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Скопировать URL-адрес
+ Скопировать URL поиска в буфер обмена
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index 39aa1738fca..9b3dd06f505 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -11,7 +11,7 @@
namespace Flow.Launcher.Plugin.WebSearch
{
- public class Main : IAsyncPlugin, ISettingProvider, IPluginI18n, IResultUpdated
+ public class Main : IAsyncPlugin, ISettingProvider, IPluginI18n, IResultUpdated, IContextMenu
{
private PluginInitContext _context;
@@ -76,7 +76,8 @@ public async Task> QueryAsync(Query query, CancellationToken token)
_context.API.OpenUrl(searchSource.Url.Replace("{q}", Uri.EscapeDataString(keyword)));
return true;
- }
+ },
+ ContextData = searchSource.Url.Replace("{q}", Uri.EscapeDataString(keyword)),
};
results.Add(result);
@@ -139,11 +140,30 @@ private async Task> SuggestionsAsync(string keyword, string
_context.API.OpenUrl(searchSource.Url.Replace("{q}", Uri.EscapeDataString(o)));
return true;
- }
+ },
+ ContextData = searchSource.Url.Replace("{q}", Uri.EscapeDataString(o)),
});
return resultsFromSuggestion;
}
+ public List LoadContextMenus(Result selected)
+ {
+ return new List() {
+ new Result
+ {
+ Title = _context.API.GetTranslation("flowlauncher_plugin_websearch_copyurl_title"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_websearch_copyurl_subtitle"),
+ IcoPath = "Images/copylink.png",
+ Action = c =>
+ {
+ _context.API.CopyToClipboard(selected.ContextData as string);
+
+ return true;
+ }
+ },
+ };
+ }
+
public Task InitAsync(PluginInitContext context)
{
return Task.Run(Init);
From 386ac9735f3a53f3fbd12a3a8c01523c49cae818 Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Mon, 18 Nov 2024 17:43:22 +0500
Subject: [PATCH 0012/1335] [WebSearch] sanitize ContextData
---
Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index 9b3dd06f505..bf5fadc5451 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -148,6 +148,7 @@ private async Task> SuggestionsAsync(string keyword, string
public List LoadContextMenus(Result selected)
{
+ if (selected?.ContextData == null || selected.ContextData is not string) return new List();
return new List() {
new Result
{
From c701419a954bbb4597e525184c60303cf6ba2d10 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 22:08:47 +0000
Subject: [PATCH 0013/1335] Bump FSharp.Core from 8.0.401 to 9.0.100
Bumps [FSharp.Core](https://github.com/dotnet/fsharp) from 8.0.401 to 9.0.100.
- [Release notes](https://github.com/dotnet/fsharp/releases)
- [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md)
- [Commits](https://github.com/dotnet/fsharp/commits)
---
updated-dependencies:
- dependency-name: FSharp.Core
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 082d7da6700..02cd5057032 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -54,7 +54,7 @@
-
+
From ba96d1a8309152a2be2136637d0a593807c78efb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 22:09:21 +0000
Subject: [PATCH 0014/1335] Bump Microsoft.Data.Sqlite from 8.0.10 to 9.0.0
Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 8.0.10 to 9.0.0.
- [Release notes](https://github.com/dotnet/efcore/releases)
- [Commits](https://github.com/dotnet/efcore/compare/v8.0.10...v9.0.0)
---
updated-dependencies:
- dependency-name: Microsoft.Data.Sqlite
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index 6f30e5d88a9..03ac0491f96 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -95,7 +95,7 @@
-
+
From c8540f1a0afc678057ba29d1a9b5500cb85f93ee Mon Sep 17 00:00:00 2001
From: Yeela Lifshitz <52451294+yeelali14@users.noreply.github.com>
Date: Tue, 19 Nov 2024 16:22:30 +0200
Subject: [PATCH 0015/1335] Suggest fix regex in gitstream CM file
---
.cm/gitstream.cm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.cm/gitstream.cm b/.cm/gitstream.cm
index fe7e777c8e1..767982e3bcc 100644
--- a/.cm/gitstream.cm
+++ b/.cm/gitstream.cm
@@ -10,7 +10,7 @@ triggers:
branch:
- l10n_dev
- dev
- - r/(?i)(Dependabot|Renovate)/
+ - r/([Dd]ependabot|[Rr]enovate)/
automations:
From 3c3087793a354c3b2b687a9f5ba1b9e4e69bd40a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 21 Nov 2024 19:18:05 +0800
Subject: [PATCH 0016/1335] add new public api for chaning the query list back
to query results list
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 ++++++
Flow.Launcher/PublicAPIInstance.cs | 2 ++
Flow.Launcher/ViewModel/MainViewModel.cs | 10 +++++++++-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index c95a8ce7b23..e5df91ae978 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -298,5 +298,11 @@ public interface IPublicAPI
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
+
+ ///
+ /// Back to the query results.
+ /// This method should run when selected item is from context menu or history.
+ ///
+ public void BackToQueryResults();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 20b02ddee8b..8a07e7a5c0a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -318,6 +318,8 @@ public bool IsGameModeOn()
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
+ public void BackToQueryResults() => _mainVM.BackToQueryResults();
+
#endregion
#region Private Methods
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6c17e21f0d2..445484347ad 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -484,6 +484,14 @@ private void Esc()
}
}
+ public void BackToQueryResults()
+ {
+ if (!SelectedIsFromQueryResults())
+ {
+ SelectedResults = Results;
+ }
+ }
+
[RelayCommand]
public void ToggleGameMode()
{
From 6df0837906b07e7c84084fa8ceb6e49ce7ce5529 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 21 Nov 2024 19:18:15 +0800
Subject: [PATCH 0017/1335] improve requery doc
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index e5df91ae978..f3d7731223d 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -294,7 +294,7 @@ public interface IPublicAPI
///
/// Reloads the query.
- /// This method should run
+ /// This method should run when selected item is from query results.
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
From 6b6b0faadfcdda46d213e107f9eb17fe50b65843 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 21 Nov 2024 22:07:35 +0800
Subject: [PATCH 0018/1335] fix possible content frame navigation issue
---
Flow.Launcher/SettingWindow.xaml | 1 +
Flow.Launcher/SettingWindow.xaml.cs | 24 ++++++++++++++++++++++--
Flow.Launcher/WelcomeWindow.xaml | 15 ++++++++-------
Flow.Launcher/WelcomeWindow.xaml.cs | 9 +++++++--
4 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index f6381b46586..a81d9e0d108 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -171,6 +171,7 @@
IsPaneToggleButtonVisible="False"
IsSettingsVisible="False"
IsTabStop="False"
+ Loaded="NavView_Loaded"
OpenPaneLength="240"
PaneDisplayMode="Left"
SelectionChanged="NavigationView_SelectionChanged">
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 4cc125fa4af..cb3f1e4a113 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -29,7 +29,6 @@ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
_api = api;
InitializePosition();
InitializeComponent();
- NavView.SelectedItem = NavView.MenuItems[0]; /* Set First Page */
}
private void OnLoaded(object sender, RoutedEventArgs e)
@@ -169,7 +168,11 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
else
{
var selectedItem = (NavigationViewItem)args.SelectedItem;
- if (selectedItem == null) return;
+ if (selectedItem == null)
+ {
+ NavView_Loaded(sender, null); /* Reset First Page */
+ return;
+ }
var pageType = selectedItem.Name switch
{
@@ -186,5 +189,22 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
}
}
+ private void NavView_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (ContentFrame.IsLoaded)
+ {
+ ContentFrame_Loaded(sender, e);
+ }
+ else
+ {
+ ContentFrame.Loaded += ContentFrame_Loaded;
+ }
+ }
+
+ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
+ {
+ NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
+ }
+
public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
}
diff --git a/Flow.Launcher/WelcomeWindow.xaml b/Flow.Launcher/WelcomeWindow.xaml
index 003dac5bcd8..d8cb38149a8 100644
--- a/Flow.Launcher/WelcomeWindow.xaml
+++ b/Flow.Launcher/WelcomeWindow.xaml
@@ -43,12 +43,12 @@
Grid.Column="0"
Width="16"
Height="16"
- Margin="10,4,4,4"
+ Margin="10 4 4 4"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Images/app.png" />
@@ -97,7 +98,7 @@
Grid.Row="1"
Background="{DynamicResource Color00B}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
- BorderThickness="0,1,0,0">
+ BorderThickness="0 1 0 0">
@@ -111,7 +112,7 @@
VerticalAlignment="Center">
Date: Fri, 22 Nov 2024 09:26:12 +0800
Subject: [PATCH 0019/1335] Revert xaml style in welcome window.
---
Flow.Launcher/WelcomeWindow.xaml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/WelcomeWindow.xaml b/Flow.Launcher/WelcomeWindow.xaml
index d8cb38149a8..208fc807fd9 100644
--- a/Flow.Launcher/WelcomeWindow.xaml
+++ b/Flow.Launcher/WelcomeWindow.xaml
@@ -43,12 +43,12 @@
Grid.Column="0"
Width="16"
Height="16"
- Margin="10 4 4 4"
+ Margin="10,4,4,4"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Images/app.png" />
+ BorderThickness="0,1,0,0">
@@ -112,7 +112,7 @@
VerticalAlignment="Center">
Date: Fri, 22 Nov 2024 11:20:12 +0800
Subject: [PATCH 0020/1335] Fix System.OperationCanceledException Issue (#3091)
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 29 ++++++++++++++------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 8bf1830e334..db3c2d222fa 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -60,15 +60,26 @@ public async Task> QueryAsync(Query query, CancellationToken token)
var result = await cache.GetOrCreateAsync(query.Search, async entry =>
{
var resultList = await Task.Run(() =>
- _win32s.Cast()
- .Concat(_uwps)
- .AsParallel()
- .WithCancellation(token)
- .Where(HideUninstallersFilter)
- .Where(p => p.Enabled)
- .Select(p => p.Result(query.Search, Context.API))
- .Where(r => r?.Score > 0)
- .ToList());
+ {
+ try
+ {
+ return _win32s.Cast()
+ .Concat(_uwps)
+ .AsParallel()
+ .WithCancellation(token)
+ .Where(HideUninstallersFilter)
+ .Where(p => p.Enabled)
+ .Select(p => p.Result(query.Search, Context.API))
+ .Where(r => r?.Score > 0)
+ .ToList();
+ }
+ catch (OperationCanceledException)
+ {
+ // Fix #3091: System.OperationCanceledException Issue
+ return emptyResults;
+ }
+
+ });
resultList = resultList.Any() ? resultList : emptyResults;
From 4e3fd84f064e1d8f9188fd0cbfc32064d357bf93 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 23 Nov 2024 21:32:42 +0800
Subject: [PATCH 0021/1335] Remove useless comment
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index db3c2d222fa..4ea91f4e8dc 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -75,11 +75,11 @@ public async Task> QueryAsync(Query query, CancellationToken token)
}
catch (OperationCanceledException)
{
- // Fix #3091: System.OperationCanceledException Issue
+ Log.Warn("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
return emptyResults;
}
- });
+ }, token);
resultList = resultList.Any() ? resultList : emptyResults;
From 9cb464df0557f645609da14b37a734a7f49430c8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 24 Nov 2024 09:21:27 +0800
Subject: [PATCH 0022/1335] Add debug log for exception.
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 4ea91f4e8dc..e311a0b94e3 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -75,7 +75,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
}
catch (OperationCanceledException)
{
- Log.Warn("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
+ Log.Debug("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
return emptyResults;
}
From 3ae960d275e82c88f5aabe57ad9405f028e8ceb4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 24 Nov 2024 16:11:53 +0800
Subject: [PATCH 0023/1335] Replace System.Windows.Message with MessageBoxEx
---
Flow.Launcher.Core/Configuration/Portable.cs | 13 +++++++------
.../MessageBoxEx.xaml | 4 ++--
.../MessageBoxEx.xaml.cs | 15 +--------------
.../Resource/Internationalization.cs | 3 ++-
Flow.Launcher.Core/Resource/Theme.cs | 4 ++--
Flow.Launcher.Core/Updater.cs | 7 ++++---
Flow.Launcher/ActionKeywords.xaml.cs | 3 ++-
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 4 ++--
Flow.Launcher/CustomShortcutSetting.xaml.cs | 5 +++--
Flow.Launcher/Helper/HotKeyMapper.cs | 4 ++--
Flow.Launcher/PriorityChangeWindow.xaml.cs | 5 +++--
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 18 ++++++++++--------
.../ViewModels/SettingsPaneProxyViewModel.cs | 3 +--
.../ViewModels/SettingsPaneThemeViewModel.cs | 4 ++--
15 files changed, 44 insertions(+), 50 deletions(-)
rename {Flow.Launcher => Flow.Launcher.Core}/MessageBoxEx.xaml (98%)
rename {Flow.Launcher => Flow.Launcher.Core}/MessageBoxEx.xaml.cs (93%)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index b58154dcb23..544cf25094e 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,6 +9,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core.Configuration
{
@@ -40,7 +41,7 @@ public void DisablePortableMode()
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- MessageBox.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
+ MessageBoxEx.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +65,7 @@ public void EnablePortableMode()
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- MessageBox.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
+ MessageBoxEx.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -159,9 +160,9 @@ public void PreStartCleanUpAfterPortabilityUpdate()
{
FilesFolders.RemoveFolderIfExists(roamingDataDir);
- if (MessageBox.Show("Flow Launcher has detected you enabled portable mode, " +
+ if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
- MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ MessageBoxType.YesNo) == MessageBoxResult.Yes)
{
FilesFolders.OpenPath(Constant.RootDirectory);
@@ -174,7 +175,7 @@ public void PreStartCleanUpAfterPortabilityUpdate()
{
FilesFolders.RemoveFolderIfExists(portableDataDir);
- MessageBox.Show("Flow Launcher has detected you disabled portable mode, " +
+ MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +187,7 @@ public bool CanUpdatePortability()
if (roamingLocationExists && portableLocationExists)
{
- MessageBox.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ MessageBoxEx.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
similarity index 98%
rename from Flow.Launcher/MessageBoxEx.xaml
rename to Flow.Launcher.Core/MessageBoxEx.xaml
index f466a640e28..ca543271bc8 100644
--- a/Flow.Launcher/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -1,9 +1,9 @@
path can't be found");
if (theme != defaultTheme)
{
- MessageBox.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -120,7 +120,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- MessageBox.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 3f64b273e4c..34545c771da 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,6 +17,7 @@
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core
{
@@ -53,7 +54,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- MessageBox.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ MessageBoxEx.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -70,7 +71,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination);
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination))
- MessageBox.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +84,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (MessageBox.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxType.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index 371b2dd07c9..ba47a4ded22 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -2,6 +2,7 @@
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -43,7 +44,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
else
{
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBox.Show(msg);
+ MessageBoxEx.Show(msg);
}
}
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 5db6115ade1..81e7600b8fa 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -6,7 +6,7 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.ViewModel;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -63,7 +63,7 @@ public void UpdateItem(CustomPluginHotkey item)
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
Close();
return;
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 531b29d50b6..dec3506eb35 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -3,6 +3,7 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -42,13 +43,13 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
{
if (String.IsNullOrEmpty(Key) || String.IsNullOrEmpty(Value))
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
return;
}
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
return;
}
DialogResult = !update || originalKey != Key || originalValue != Value;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 21ddf276ad3..8b30b8be1f5 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -4,8 +4,8 @@
using NHotkey;
using NHotkey.Wpf;
using Flow.Launcher.Core.Resource;
-using System.Windows;
using Flow.Launcher.ViewModel;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Helper;
@@ -46,7 +46,7 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
{
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
- MessageBox.Show(errorMsg,errorMsgTitle);
+ MessageBoxEx.Show(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs
index 2d0966de4d2..2154b058d1c 100644
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs
@@ -5,6 +5,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -23,7 +24,7 @@ public PriorityChangeWindow(string pluginId, PluginViewModel pluginViewModel)
this.pluginViewModel = pluginViewModel;
if (plugin == null)
{
- MessageBox.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
+ MessageBoxEx.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
Close();
}
}
@@ -43,7 +44,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs e)
else
{
string msg = translater.GetTranslation("invalidPriority");
- MessageBox.Show(msg);
+ MessageBoxEx.Show(msg);
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index c314b42ee68..6e6cbce4d7b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -11,7 +11,7 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using static Flow.Launcher.MessageBoxEx;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.SettingPages.ViewModels;
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index a4488a0377a..669cd078433 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -7,6 +7,8 @@
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Core;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -41,16 +43,16 @@ private void CustomHotkeyDelete()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
),
InternationalizationManager.Instance.GetTranslation("delete"),
- MessageBoxButton.YesNo
+ MessageBoxType.YesNo
);
if (result is MessageBoxResult.Yes)
@@ -66,7 +68,7 @@ private void CustomHotkeyEdit()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -87,16 +89,16 @@ private void CustomShortcutDelete()
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
),
InternationalizationManager.Instance.GetTranslation("delete"),
- MessageBoxButton.YesNo
+ MessageBoxType.YesNo
);
if (result is MessageBoxResult.Yes)
@@ -111,7 +113,7 @@ private void CustomShortcutEdit()
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index 2dd57809db2..1c840fb2703 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -1,5 +1,4 @@
using System.Net;
-using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Resource;
@@ -23,7 +22,7 @@ public SettingsPaneProxyViewModel(Settings settings, Updater updater)
private void OnTestProxyClicked()
{
var message = TestProxy();
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation(message));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation(message));
}
private string TestProxy()
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index f2e52dbaed9..8a835ba7cbb 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Windows;
-using System.Windows.Controls;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -15,6 +14,7 @@
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using ModernWpf;
+using Flow.Launcher.Core;
using ThemeManager = Flow.Launcher.Core.Resource.ThemeManager;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
@@ -49,7 +49,7 @@ public bool DropShadowEffect
{
if (ThemeManager.Instance.BlurEnabled && value)
{
- MessageBox.Show(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
+ MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
return;
}
From 6feca10bdbc3dbce3f4b8cc48fe9f3aebe23b3ad Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 24 Nov 2024 16:30:35 +0800
Subject: [PATCH 0024/1335] Improve MessageBoxEx paramters as
System.Windows.MessageBox for readability
---
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 30 ++++++++++++-------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index 18b1ae07f9c..3e04657dc45 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -37,39 +37,39 @@ public enum MessageBoxImage
/// 1 parameter
- public static MessageBoxResult Show(string msg)
+ public static MessageBoxResult Show(string messageBoxText)
{
- return Show(string.Empty, msg, MessageBoxButton.OK, MessageBoxImage.None);
+ return Show(string.Empty, messageBoxText, MessageBoxButton.OK, MessageBoxImage.None);
}
// 2 parameter
- public static MessageBoxResult Show(string caption, string text)
+ public static MessageBoxResult Show(string messageBoxText, string title)
{
- return Show(caption, text, MessageBoxButton.OK, MessageBoxImage.None);
+ return Show(messageBoxText, title, MessageBoxButton.OK, MessageBoxImage.None);
}
/// 3 parameter
- public static MessageBoxResult Show(string caption, string msg, MessageBoxType type)
+ public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxType type)
{
switch (type)
{
case MessageBoxType.ConfirmationWithYesNo:
- return Show(caption, msg, MessageBoxButton.YesNo,
+ return Show(messageBoxText, title, MessageBoxButton.YesNo,
MessageBoxImage.Question);
case MessageBoxType.YesNo:
- return Show(caption, msg, MessageBoxButton.YesNo,
+ return Show(messageBoxText, title, MessageBoxButton.YesNo,
MessageBoxImage.Question);
case MessageBoxType.ConfirmationWithYesNoCancel:
- return Show(caption, msg, MessageBoxButton.YesNoCancel,
+ return Show(messageBoxText, title, MessageBoxButton.YesNoCancel,
MessageBoxImage.Question);
case MessageBoxType.Information:
- return Show(caption, msg, MessageBoxButton.OK,
+ return Show(messageBoxText, title, MessageBoxButton.OK,
MessageBoxImage.Information);
case MessageBoxType.Error:
- return Show(caption, msg, MessageBoxButton.OK,
+ return Show(messageBoxText, title, MessageBoxButton.OK,
MessageBoxImage.Error);
case MessageBoxType.Warning:
- return Show(caption, msg, MessageBoxButton.OK,
+ return Show(messageBoxText, title, MessageBoxButton.OK,
MessageBoxImage.Warning);
default:
return MessageBoxResult.No;
@@ -77,12 +77,12 @@ public static MessageBoxResult Show(string caption, string msg, MessageBoxType t
}
// 4 parameter, Final Display Message.
- public static MessageBoxResult Show(string caption, string text, MessageBoxButton button, MessageBoxImage image)
+ public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxButton button, MessageBoxImage image)
{
msgBox = new MessageBoxEx();
- msgBox.TitleTextBlock.Text = text;
- msgBox.DescTextBlock.Text = caption;
- msgBox.Title = text;
+ msgBox.TitleTextBlock.Text = title;
+ msgBox.DescTextBlock.Text = messageBoxText;
+ msgBox.Title = title;
SetVisibilityOfButtons(button);
SetImageOfMessageBox(image);
msgBox.ShowDialog();
From ab087bd927c8e4c75db90115151ce1b11cefe6c7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 24 Nov 2024 22:08:50 +0800
Subject: [PATCH 0025/1335] Remove useless columns
---
Flow.Launcher.Core/MessageBoxEx.xaml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index ca543271bc8..2788a76489a 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -33,14 +33,11 @@
-
-
-
Date: Sun, 24 Nov 2024 22:12:43 +0800
Subject: [PATCH 0026/1335] Improve OK MessageBoxEx display style
---
Flow.Launcher.Core/MessageBoxEx.xaml | 23 +++++++++++++++++++----
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 18 +++++++++++++-----
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index 2788a76489a..3467b3a0cc4 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -60,8 +60,12 @@
-
-
+
+
+
+
+
+
@@ -91,14 +95,25 @@
-
+
+
Date: Mon, 25 Nov 2024 10:38:43 +0800
Subject: [PATCH 0027/1335] Replace System.Windows.MessageBox with MessageBoxEx
---
Flow.Launcher.Core/Configuration/Portable.cs | 10 +++----
.../Environments/AbstractPluginEnvironment.cs | 8 ++++--
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 7 +++--
Flow.Launcher.Core/Updater.cs | 4 +--
.../SharedCommands/FilesFolders.cs | 27 ++++++++++--------
.../Flow.Launcher.Plugin.Calculator/Main.cs | 4 +--
.../ContextMenu.cs | 12 ++++----
.../Everything/EverythingDownloadHelper.cs | 9 ++++--
.../Search/ResultManager.cs | 11 ++++----
.../ViewModels/SettingsViewModel.cs | 4 +--
.../Views/ActionKeywordSetting.xaml.cs | 9 +++---
.../PluginsManager.cs | 28 ++++++++++---------
.../AddProgramSource.xaml.cs | 3 +-
.../Flow.Launcher.Plugin.Program.csproj | 1 +
.../ProgramSuffixes.xaml.cs | 5 ++--
.../Views/ProgramSetting.xaml.cs | 8 ++++--
.../Flow.Launcher.Plugin.Sys.csproj | 1 +
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 13 +++++----
.../SearchSourceSetting.xaml.cs | 13 +++++----
.../SearchSourceViewModel.cs | 2 +-
.../SettingsControl.xaml.cs | 6 ++--
25 files changed, 108 insertions(+), 85 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 544cf25094e..2a1db10e7ea 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -96,13 +96,13 @@ public void RemoveUninstallerEntry()
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation);
+ FilesFolders.CopyAll(fromLocation, toLocation, MessageBoxEx.Show);
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation);
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
}
public void CreateShortcuts()
@@ -158,13 +158,13 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir);
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, MessageBoxEx.Show);
if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxType.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory);
+ FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
Environment.Exit(0);
}
@@ -173,7 +173,7 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir);
+ FilesFolders.RemoveFolderIfExists(portableDataDir, MessageBoxEx.Show);
MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 30e812c6f05..433df6f97a4 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -6,8 +6,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -57,7 +59,7 @@ internal IEnumerable Setup()
EnvName,
Environment.NewLine
);
- if (MessageBox.Show(noRuntimeMessage, string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
+ if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxType.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +84,7 @@ internal IEnumerable Setup()
}
else
{
- MessageBox.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +100,7 @@ private void EnsureLatestInstalled(string expectedPath, string currentPath, stri
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath);
+ FilesFolders.RemoveFolderIfExists(installedDirPath, MessageBoxEx.Show);
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 5676e12f525..96c29646e8f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ internal PythonEnvironment(List pluginMetadataList, PluginsSetti
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath);
+ FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 70341f711f1..0d6f109e07f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ internal TypeScriptEnvironment(List pluginMetadataList, PluginsS
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath);
+ FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 11ed94d3f4d..582a4407c45 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ internal TypeScriptV2Environment(List pluginMetadataList, Plugin
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath);
+ FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 91cb36a0e3c..5c4eaa1dadc 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath);
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 0f2e4f996cb..495d25e1b6d 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -3,7 +3,7 @@
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
-using System.Windows.Forms;
+using System.Windows;
using Flow.Launcher.Core.ExternalPlugins.Environments;
#pragma warning disable IDE0005
using Flow.Launcher.Infrastructure.Logger;
@@ -11,6 +11,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
+using MessageBoxImage = Flow.Launcher.Core.MessageBoxEx.MessageBoxImage;
namespace Flow.Launcher.Core.Plugin
{
@@ -119,10 +120,10 @@ public static IEnumerable DotNetPlugins(List source)
_ = Task.Run(() =>
{
- MessageBox.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
- MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ MessageBoxButton.OK, MessageBoxImage.Warning);
});
}
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 34545c771da..5a980c5e22a 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -69,8 +69,8 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination);
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination))
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show);
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show))
MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
index dd8c4b11232..fb2578e6d79 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -21,7 +21,8 @@ public static class FilesFolders
///
///
///
- public static void CopyAll(this string sourcePath, string targetPath)
+ ///
+ public static void CopyAll(this string sourcePath, string targetPath, Func messageBoxExShow)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourcePath);
@@ -54,7 +55,7 @@ public static void CopyAll(this string sourcePath, string targetPath)
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(targetPath, subdir.Name);
- CopyAll(subdir.FullName, temppath);
+ CopyAll(subdir.FullName, temppath, messageBoxExShow);
}
}
catch (Exception)
@@ -62,7 +63,7 @@ public static void CopyAll(this string sourcePath, string targetPath)
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
+ messageBoxExShow(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
RemoveFolderIfExists(targetPath);
#endif
}
@@ -75,8 +76,9 @@ public static void CopyAll(this string sourcePath, string targetPath)
///
///
///
+ ///
///
- public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath)
+ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath, Func messageBoxExShow)
{
try
{
@@ -96,7 +98,7 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
+ messageBoxExShow(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
return false;
#endif
}
@@ -107,7 +109,8 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat
/// Deletes a folder if it exists
///
///
- public static void RemoveFolderIfExists(this string path)
+ ///
+ public static void RemoveFolderIfExists(this string path, Func messageBoxExShow)
{
try
{
@@ -119,7 +122,7 @@ public static void RemoveFolderIfExists(this string path)
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
+ messageBoxExShow(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
#endif
}
}
@@ -148,7 +151,8 @@ public static bool FileExists(this string filePath)
/// Open a directory window (using the OS's default handler, usually explorer)
///
///
- public static void OpenPath(string fileOrFolderPath)
+ ///
+ public static void OpenPath(string fileOrFolderPath, Func messageBoxExShow)
{
var psi = new ProcessStartInfo
{
@@ -166,7 +170,7 @@ public static void OpenPath(string fileOrFolderPath)
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Unable to open the path {0}, please check if it exists", fileOrFolderPath));
+ messageBoxExShow(string.Format("Unable to open the path {0}, please check if it exists", fileOrFolderPath));
#endif
}
}
@@ -175,9 +179,10 @@ public static void OpenPath(string fileOrFolderPath)
/// Open a file with associated application
///
/// File path
+ ///
/// Working directory
/// Open as Administrator
- public static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false)
+ public static void OpenFile(string filePath, Func messageBoxExShow, string workingDir = "", bool asAdmin = false)
{
var psi = new ProcessStartInfo
{
@@ -196,7 +201,7 @@ public static void OpenFile(string filePath, string workingDir = "", bool asAdmi
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Unable to open the path {0}, please check if it exists", filePath));
+ messageBoxExShow(string.Format("Unable to open the path {0}, please check if it exists", filePath));
#endif
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
index 5077e60614d..54a6f7a44b7 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -3,11 +3,11 @@
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
-using System.Windows;
using System.Windows.Controls;
using Mages.Core;
using Flow.Launcher.Plugin.Calculator.ViewModels;
using Flow.Launcher.Plugin.Calculator.Views;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Calculator
{
@@ -101,7 +101,7 @@ public List Query(Query query)
}
catch (ExternalException)
{
- MessageBox.Show("Copy failed, please try later");
+ MessageBoxEx.Show("Copy failed, please try later");
return false;
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index f061ca183cf..8c40cac9ab0 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -10,11 +10,9 @@
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using System.Linq;
using Flow.Launcher.Plugin.Explorer.Helper;
-using MessageBox = System.Windows.Forms.MessageBox;
-using MessageBoxIcon = System.Windows.Forms.MessageBoxIcon;
-using MessageBoxButton = System.Windows.Forms.MessageBoxButtons;
-using DialogResult = System.Windows.Forms.DialogResult;
using Flow.Launcher.Plugin.Explorer.ViewModels;
+using Flow.Launcher.Core;
+using MessageBoxImage = Flow.Launcher.Core.MessageBoxEx.MessageBoxImage;
namespace Flow.Launcher.Plugin.Explorer
{
@@ -177,12 +175,12 @@ public List LoadContextMenus(Result selectedResult)
{
try
{
- if (MessageBox.Show(
+ if (MessageBoxEx.Show(
string.Format(Context.API.GetTranslation("plugin_explorer_delete_folder_link"), record.FullPath),
string.Empty,
MessageBoxButton.YesNo,
- MessageBoxIcon.Warning)
- == DialogResult.No)
+ MessageBoxImage.Warning)
+ == MessageBoxResult.No)
return false;
if (isFile)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
index ef923632d3f..b890e6e18a6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
@@ -1,10 +1,13 @@
using Droplex;
+using Flow.Launcher.Core;
using Flow.Launcher.Plugin.SharedCommands;
using Microsoft.Win32;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using System.Windows;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.Explorer.Search.Everything;
@@ -19,10 +22,10 @@ public static async Task PromptDownloadIfNotInstallAsync(string installe
if (string.IsNullOrEmpty(installedLocation))
{
- if (System.Windows.Forms.MessageBox.Show(
+ if (MessageBoxEx.Show(
string.Format(api.GetTranslation("flowlauncher_plugin_everything_installing_select"), Environment.NewLine),
api.GetTranslation("flowlauncher_plugin_everything_installing_title"),
- System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
+ MessageBoxType.YesNo) == MessageBoxResult.Yes)
{
var dlg = new System.Windows.Forms.OpenFileDialog
{
@@ -50,7 +53,7 @@ public static async Task PromptDownloadIfNotInstallAsync(string installe
installedLocation = "C:\\Program Files\\Everything\\Everything.exe";
- FilesFolders.OpenPath(installedLocation);
+ FilesFolders.OpenPath(installedLocation, MessageBoxEx.Show);
return installedLocation;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 1e7555a8d49..bffe75c290b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -12,6 +12,7 @@
using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Views;
using Peter;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Explorer.Search
{
@@ -123,7 +124,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBox.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -137,7 +138,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBox.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -152,7 +153,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBox.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -315,7 +316,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
}
catch (Exception ex)
{
- MessageBox.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_openfile_error"));
+ MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_openfile_error"));
}
return true;
@@ -337,7 +338,7 @@ private static bool IsMedia(string extension)
private static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false)
{
IncrementEverythingRunCounterIfNeeded(filePath);
- FilesFolders.OpenFile(filePath, workingDir, asAdmin);
+ FilesFolders.OpenFile(filePath, MessageBoxEx.Show, workingDir, asAdmin);
}
private static void OpenFolder(string folderPath, string fileNameOrFilePath = null)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 309f7a6f7ac..49b4a9fa23e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -1,4 +1,5 @@
#nullable enable
+using Flow.Launcher.Core;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
@@ -14,7 +15,6 @@
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
-using MessageBox = System.Windows.Forms.MessageBox;
namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
@@ -358,7 +358,7 @@ private void EditLink(object commandParameter)
private void ShowUnselectedMessage()
{
var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index 9e86ce4b482..fdfe1638a48 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -1,8 +1,9 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Explorer.Views
{
@@ -62,10 +63,10 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e)
switch (CurrentActionKeyword.KeywordProperty, KeywordEnabled)
{
case (Settings.ActionKeyword.FileContentSearchActionKeyword, true):
- MessageBox.Show(api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
+ MessageBoxEx.Show(api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
return;
case (Settings.ActionKeyword.QuickAccessActionKeyword, true):
- MessageBox.Show(api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
+ MessageBoxEx.Show(api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
return;
}
@@ -77,7 +78,7 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e)
}
// The keyword is not valid, so show message
- MessageBox.Show(api.GetTranslation("newActionKeywordsHasBeenAssigned"));
+ MessageBoxEx.Show(api.GetTranslation("newActionKeywordsHasBeenAssigned"));
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 2d71329b4b9..fcba3ebee4a 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -12,6 +13,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.PluginsManager
{
@@ -131,8 +133,8 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
Environment.NewLine);
}
- if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (MessageBoxEx.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
+ MessageBoxType.YesNo) == MessageBoxResult.No)
return;
// at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
@@ -265,9 +267,9 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
Environment.NewLine);
}
- if (MessageBox.Show(message,
+ if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxButton.YesNo) != MessageBoxResult.Yes)
+ MessageBoxType.YesNo) != MessageBoxResult.Yes)
{
return false;
}
@@ -360,9 +362,9 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
resultsForUpdate.Count());
}
- if (MessageBox.Show(message,
+ if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
+ MessageBoxType.YesNo) == MessageBoxResult.No)
{
return false;
}
@@ -474,12 +476,12 @@ internal List InstallFromWeb(string url)
if (Settings.WarnFromUnknownSource)
{
if (!InstallSourceKnown(plugin.UrlDownload)
- && MessageBox.Show(string.Format(
+ && MessageBoxEx.Show(string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"),
Environment.NewLine),
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
+ MessageBoxType.YesNo) == MessageBoxResult.No)
return false;
}
@@ -511,13 +513,13 @@ internal List InstallFromLocalPath(string localPath)
if (Settings.WarnFromUnknownSource)
{
if (!InstallSourceKnown(plugin.Website)
- && MessageBox.Show(string.Format(
+ && MessageBoxEx.Show(string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning"),
Environment.NewLine),
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.No)
+ MessageBoxType.YesNo) == MessageBoxResult.No)
return false;
}
@@ -648,9 +650,9 @@ internal List RequestUninstall(string search)
Environment.NewLine);
}
- if (MessageBox.Show(message,
+ if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"),
- MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ MessageBoxType.YesNo) == MessageBoxResult.Yes)
{
Application.Current.MainWindow.Hide();
Uninstall(x.Metadata);
diff --git a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
index be8b768bd8f..fef16cb33ce 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
@@ -1,4 +1,5 @@
using System.Windows;
+using Flow.Launcher.Core;
using Flow.Launcher.Plugin.Program.ViewModels;
namespace Flow.Launcher.Plugin.Program
@@ -32,7 +33,7 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
var (modified, msg) = ViewModel.AddOrUpdate();
if (modified == false && msg != null)
{
- MessageBox.Show(msg); // Invalid
+ MessageBoxEx.Show(msg); // Invalid
return;
}
DialogResult = modified;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
index 4d88eef2c97..68363c1faf5 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
@@ -54,6 +54,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
index 31565c8b086..af1df8e71a6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Windows;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Program
{
@@ -39,14 +40,14 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
if (suffixes.Length == 0 && UseCustomSuffixes)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_program_suffixes_cannot_empty");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
return;
}
if (protocols.Length == 0 && UseCustomProtocols)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_protocols_cannot_empty");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
return;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 7570d6b4d33..e85b7534e4c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -10,6 +10,8 @@
using System.ComponentModel;
using System.Windows.Data;
using Flow.Launcher.Plugin.Program.ViewModels;
+using Flow.Launcher.Core;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.Program.Views
{
@@ -178,7 +180,7 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
if (selectedProgramSource == null)
{
string msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- MessageBox.Show(msg);
+ MessageBoxEx.Show(msg);
}
else
{
@@ -283,7 +285,7 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
if (selectedItems.Count == 0)
{
string msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- MessageBox.Show(msg);
+ MessageBoxEx.Show(msg);
return;
}
@@ -292,7 +294,7 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
var msg = string.Format(
context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source"));
- if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (MessageBoxEx.Show(msg, string.Empty, MessageBoxType.YesNo) == MessageBoxResult.No)
{
return;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index b797b3cf43a..4e804e82c48 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -37,6 +37,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 1ec07915d2b..72f3639ffca 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -7,6 +7,7 @@
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
+using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -14,7 +15,7 @@
using Application = System.Windows.Application;
using Control = System.Windows.Controls.Control;
using FormsApplication = System.Windows.Forms.Application;
-using MessageBox = System.Windows.MessageBox;
+using MessageBoxImage = Flow.Launcher.Core.MessageBoxEx.MessageBoxImage;
namespace Flow.Launcher.Plugin.Sys
{
@@ -143,7 +144,7 @@ private List Commands()
IcoPath = "Images\\shutdown.png",
Action = c =>
{
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -163,7 +164,7 @@ private List Commands()
IcoPath = "Images\\restart.png",
Action = c =>
{
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -183,7 +184,7 @@ private List Commands()
IcoPath = "Images\\restart_advanced.png",
Action = c =>
{
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer_advanced"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -202,7 +203,7 @@ private List Commands()
IcoPath = "Images\\logoff.png",
Action = c =>
{
- var result = MessageBox.Show(
+ var result = MessageBoxEx.Show(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_logoff_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -279,7 +280,7 @@ private List Commands()
var result = SHEmptyRecycleBin(new WindowInteropHelper(Application.Current.MainWindow).Handle, 0);
if (result != (uint) HRESULT.S_OK && result != (uint) 0x8000FFFF)
{
- MessageBox.Show($"Error emptying recycle bin, error code: {result}\n" +
+ MessageBoxEx.Show($"Error emptying recycle bin, error code: {result}\n" +
"please refer to https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137",
"Error",
MessageBoxButton.OK, MessageBoxImage.Error);
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index 60863ee8281..8336f4b9a2b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -2,6 +2,7 @@
using System.Windows;
using Microsoft.Win32;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.WebSearch
{
@@ -55,17 +56,17 @@ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
if (string.IsNullOrEmpty(_searchSource.Title))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_title");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
else if (string.IsNullOrEmpty(_searchSource.Url))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_url");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
else if (string.IsNullOrEmpty(_searchSource.ActionKeyword))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_action_keyword");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
else if (_action == Action.Add)
{
@@ -92,7 +93,7 @@ private void AddSearchSource()
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
}
@@ -113,7 +114,7 @@ private void EditSearchSource()
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBox.Show(warning);
+ MessageBoxEx.Show(warning);
}
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
@@ -138,7 +139,7 @@ private async void OnSelectIconClick(object sender, RoutedEventArgs e)
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
{
if (_viewModel.ShouldProvideHint(selectedNewIconImageFullPath))
- MessageBox.Show(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));
+ MessageBoxEx.Show(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));
imgPreviewIcon.Source = await _viewModel.LoadPreviewIconAsync(selectedNewIconImageFullPath);
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
index 105e7dd6803..0495772d540 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
@@ -41,7 +41,7 @@ public void CopyNewImageToUserDataDirectoryIfRequired(
#if DEBUG
throw;
#else
- MessageBox.Show(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
+ Flow.Launcher.Core.MessageBoxEx.Show(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
#endif
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
index 7caa5beb3ad..7e4edf65325 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
@@ -1,8 +1,10 @@
-using System.Windows;
+using System.Windows;
using System.Windows.Controls;
using Flow.Launcher.Core.Plugin;
using System.ComponentModel;
using System.Windows.Data;
+using Flow.Launcher.Core;
+using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.WebSearch
{
@@ -36,7 +38,7 @@ private void OnDeleteSearchSearchClick(object sender, RoutedEventArgs e)
var warning = _context.API.GetTranslation("flowlauncher_plugin_websearch_delete_warning");
var formated = string.Format(warning, selected.Title);
- var result = MessageBox.Show(formated, string.Empty, MessageBoxButton.YesNo);
+ var result = MessageBoxEx.Show(formated, string.Empty, MessageBoxType.YesNo);
if (result == MessageBoxResult.Yes)
{
var id = _context.CurrentPluginMetadata.ID;
From 4bc9e86a27a7f7568543cf3c98e8f88caf18c5db Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 25 Nov 2024 12:06:33 +0800
Subject: [PATCH 0028/1335] Improve MessageBoxEx style as
System.Windows.MessageBox
---
Flow.Launcher.Core/MessageBoxEx.xaml | 16 ++++++++--------
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 6 +++---
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index 3467b3a0cc4..8edb0873d49 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -125,29 +125,29 @@
VerticalAlignment="Center"
Orientation="Horizontal">
+ Content="{DynamicResource commonOK}" />
+ Content="{DynamicResource commonYes}" />
+ Content="{DynamicResource commonNo}" />
+ Content="{DynamicResource commonCancel}" />
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index 911e6b5b81b..1a986be4ce6 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -125,16 +125,16 @@ private static void SetVisibilityOfButtons(MessageBoxButton button)
case MessageBoxButton.OKCancel:
msgBox.btnNo.Visibility = Visibility.Collapsed;
msgBox.btnYes.Visibility = Visibility.Collapsed;
- msgBox.btnCancel.Focus();
+ msgBox.btnOk.Focus();
break;
case MessageBoxButton.YesNo:
msgBox.btnOk.Visibility = Visibility.Collapsed;
msgBox.btnCancel.Visibility = Visibility.Collapsed;
- msgBox.btnNo.Focus();
+ msgBox.btnYes.Focus();
break;
case MessageBoxButton.YesNoCancel:
msgBox.btnOk.Visibility = Visibility.Collapsed;
- msgBox.btnCancel.Focus();
+ msgBox.btnYes.Focus();
break;
default:
break;
From e183682d41b026bf4c1833f045c23252b769a787 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 25 Nov 2024 22:58:41 +0000
Subject: [PATCH 0029/1335] Bump Microsoft.VisualStudio.Threading from 17.10.48
to 17.12.19
Bumps [Microsoft.VisualStudio.Threading](https://github.com/microsoft/vs-threading) from 17.10.48 to 17.12.19.
- [Release notes](https://github.com/microsoft/vs-threading/releases)
- [Commits](https://github.com/microsoft/vs-threading/commits)
---
updated-dependencies:
- dependency-name: Microsoft.VisualStudio.Threading
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Infrastructure.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index d9cb5893aaf..ec35ef9d679 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -55,7 +55,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
From f3c21d5842df3dcea1d7835547afd2b9dbba5cc3 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 25 Nov 2024 22:59:12 +0000
Subject: [PATCH 0030/1335] Bump Microsoft.Extensions.Caching.Memory from 8.0.1
to 9.0.0
Bumps [Microsoft.Extensions.Caching.Memory](https://github.com/dotnet/runtime) from 8.0.1 to 9.0.0.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v8.0.1...v9.0.0)
---
updated-dependencies:
- dependency-name: Microsoft.Extensions.Caching.Memory
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.Program.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
index 4d88eef2c97..c0ad63cfeb4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
@@ -60,7 +60,7 @@
-
+
\ No newline at end of file
From c3e676f130a3e76f1517ce5937ab91864bcbae09 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 25 Nov 2024 23:00:08 +0000
Subject: [PATCH 0031/1335] Bump Microsoft.NET.Test.Sdk from 17.11.1 to 17.12.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.11.1 to 17.12.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.11.1...v17.12.0)
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
index a4bc4ab19a3..8286e142e67 100644
--- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj
+++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
@@ -54,7 +54,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
\ No newline at end of file
From dcea54ab83de0cf55469328a6891f6fd9a7ae340 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 26 Nov 2024 19:28:39 +0800
Subject: [PATCH 0032/1335] Fix parameter bug under release mode
---
Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
index fb2578e6d79..6e00b8a27b8 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -64,7 +64,7 @@ public static void CopyAll(this string sourcePath, string targetPath, Func
Date: Tue, 26 Nov 2024 21:31:13 +0800
Subject: [PATCH 0033/1335] Replace Flow.Launcher.Core.MessageBoxType &
MessageBoxImage with System.Windows.MessageBoxButton & MessageBoxImage Remove
useless warning file
---
Flow.Launcher.Core/Configuration/Portable.cs | 3 +-
.../Environments/AbstractPluginEnvironment.cs | 4 +-
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 49 ++----------------
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 1 -
.../Resource/Internationalization.cs | 3 +-
Flow.Launcher.Core/Updater.cs | 3 +-
Flow.Launcher/Images/warning.png | Bin 738 -> 0 bytes
.../ViewModels/SettingsPaneAboutViewModel.cs | 3 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 5 +-
.../ContextMenu.cs | 1 -
.../Everything/EverythingDownloadHelper.cs | 3 +-
.../PluginsManager.cs | 13 +++--
.../Views/ProgramSetting.xaml.cs | 3 +-
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 1 -
.../SettingsControl.xaml.cs | 3 +-
15 files changed, 20 insertions(+), 75 deletions(-)
delete mode 100644 Flow.Launcher/Images/warning.png
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 2a1db10e7ea..d7c73fb46ac 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,7 +9,6 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core.Configuration
{
@@ -162,7 +161,7 @@ public void PreStartCleanUpAfterPortabilityUpdate()
if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
- MessageBoxType.YesNo) == MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 433df6f97a4..6d41e23834e 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -4,12 +4,10 @@
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -59,7 +57,7 @@ internal IEnumerable Setup()
EnvName,
Environment.NewLine
);
- if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxType.YesNo) == MessageBoxResult.No)
+ if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index 1a986be4ce6..b87302ca55a 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -13,25 +13,6 @@ public MessageBoxEx()
InitializeComponent();
}
- public enum MessageBoxType
- {
- ConfirmationWithYesNo = 0,
- ConfirmationWithYesNoCancel,
- YesNo,
- Information,
- Error,
- Warning
- }
-
- public enum MessageBoxImage
- {
- Warning = 0,
- Question,
- Information,
- Error,
- None
- }
-
static MessageBoxEx msgBox;
static MessageBoxResult _result = MessageBoxResult.No;
@@ -49,31 +30,9 @@ public static MessageBoxResult Show(string messageBoxText, string title)
}
/// 3 parameter
- public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxType type)
+ public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxButton type)
{
- switch (type)
- {
- case MessageBoxType.ConfirmationWithYesNo:
- return Show(messageBoxText, title, MessageBoxButton.YesNo,
- MessageBoxImage.Question);
- case MessageBoxType.YesNo:
- return Show(messageBoxText, title, MessageBoxButton.YesNo,
- MessageBoxImage.Question);
- case MessageBoxType.ConfirmationWithYesNoCancel:
- return Show(messageBoxText, title, MessageBoxButton.YesNoCancel,
- MessageBoxImage.Question);
- case MessageBoxType.Information:
- return Show(messageBoxText, title, MessageBoxButton.OK,
- MessageBoxImage.Information);
- case MessageBoxType.Error:
- return Show(messageBoxText, title, MessageBoxButton.OK,
- MessageBoxImage.Error);
- case MessageBoxType.Warning:
- return Show(messageBoxText, title, MessageBoxButton.OK,
- MessageBoxImage.Warning);
- default:
- return MessageBoxResult.No;
- }
+ return Show(messageBoxText, title, type, MessageBoxImage.None);
}
// 4 parameter, Final Display Message.
@@ -144,8 +103,8 @@ private static void SetImageOfMessageBox(MessageBoxImage image)
{
switch (image)
{
- case MessageBoxImage.Warning:
- msgBox.SetImage("Warning.png");
+ case MessageBoxImage.Exclamation:
+ msgBox.SetImage("Exclamation.png");
msgBox.Img.Visibility = Visibility.Visible;
break;
case MessageBoxImage.Question:
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 495d25e1b6d..7973c66baa7 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -11,7 +11,6 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
-using MessageBoxImage = Flow.Launcher.Core.MessageBoxEx.MessageBoxImage;
namespace Flow.Launcher.Core.Plugin
{
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index e634dc9dd55..1505e84f819 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -11,7 +11,6 @@
using Flow.Launcher.Plugin;
using System.Globalization;
using System.Threading.Tasks;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core.Resource
{
@@ -125,7 +124,7 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (MessageBoxEx.Show(text, string.Empty, MessageBoxType.YesNo) == MessageBoxResult.No)
+ if (MessageBoxEx.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 5a980c5e22a..b92d8656873 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,7 +17,6 @@
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Core
{
@@ -84,7 +83,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxType.YesNo) == MessageBoxResult.Yes)
+ if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
diff --git a/Flow.Launcher/Images/warning.png b/Flow.Launcher/Images/warning.png
deleted file mode 100644
index 8d29625ee731a16a1c29ecc6cd5f505a449f0069..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 738
zcmV<80v-K{P)kh?ZJ9v_+5#4%NNw-R79O38FZ;HlsS!NjIyLIO)*2?WT0erCr?W
zAm}1V5NRF6h=V;_^CTCMc)5G;_x^+?a5uhtclZ7Le(yf_IKq%0H01e_0UUJ)vkqh(
zu&h9~gwhHqD#vF*x%KG0Xf2X|@Yb@}iI?}K1EPW=C|?6nu>&BQ5Wl9$N7FS#e*mia
zmjK=RKWytMEgUQjJV3N`a=D$vpsldog}O@!=N%A1p#p-J7*Zf0FZ2f%Ky2kp5Y%~b
z(~jJ4pXLq&R}fA+Ac8^-gehq_fjW8N^uPg#YW@L0%dB98GR=oiSaTJVoOGZ^o2q0E
zwdw{SQJX3XH(Ip@NYm!c<=KA(XNn6
zfCH^s0m!uZ@Wpw2sGpJpw9i^<)eb(3?9)N*X^#C}#Ot+D}B+KjIc;|^$Ql?A}jrh0*E%+Sy(
z4}hUfjd;wdJgq7LxY~@TYV3|+y?QPhUR>D2$X{^4U
zh=y-m{fxQG-^>6MT1^Ge)uvfG=2ep2YC3>L^_j8w(L6f8Tt PromptDownloadIfNotInstallAsync(string installe
if (MessageBoxEx.Show(
string.Format(api.GetTranslation("flowlauncher_plugin_everything_installing_select"), Environment.NewLine),
api.GetTranslation("flowlauncher_plugin_everything_installing_title"),
- MessageBoxType.YesNo) == MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
var dlg = new System.Windows.Forms.OpenFileDialog
{
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fcba3ebee4a..fd978c6d116 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -13,7 +13,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.PluginsManager
{
@@ -134,7 +133,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
if (MessageBoxEx.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
- MessageBoxType.YesNo) == MessageBoxResult.No)
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
return;
// at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
@@ -269,7 +268,7 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxType.YesNo) != MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) != MessageBoxResult.Yes)
{
return false;
}
@@ -364,7 +363,7 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- MessageBoxType.YesNo) == MessageBoxResult.No)
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return false;
}
@@ -481,7 +480,7 @@ internal List InstallFromWeb(string url)
Environment.NewLine),
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning_title"),
- MessageBoxType.YesNo) == MessageBoxResult.No)
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
}
@@ -519,7 +518,7 @@ internal List InstallFromLocalPath(string localPath)
Environment.NewLine),
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning_title"),
- MessageBoxType.YesNo) == MessageBoxResult.No)
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
}
@@ -652,7 +651,7 @@ internal List RequestUninstall(string search)
if (MessageBoxEx.Show(message,
Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"),
- MessageBoxType.YesNo) == MessageBoxResult.Yes)
+ MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Application.Current.MainWindow.Hide();
Uninstall(x.Metadata);
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index e85b7534e4c..c7595c49dc8 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -11,7 +11,6 @@
using System.Windows.Data;
using Flow.Launcher.Plugin.Program.ViewModels;
using Flow.Launcher.Core;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.Program.Views
{
@@ -294,7 +293,7 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
var msg = string.Format(
context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source"));
- if (MessageBoxEx.Show(msg, string.Empty, MessageBoxType.YesNo) == MessageBoxResult.No)
+ if (MessageBoxEx.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 72f3639ffca..94e83315bea 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -15,7 +15,6 @@
using Application = System.Windows.Application;
using Control = System.Windows.Controls.Control;
using FormsApplication = System.Windows.Forms.Application;
-using MessageBoxImage = Flow.Launcher.Core.MessageBoxEx.MessageBoxImage;
namespace Flow.Launcher.Plugin.Sys
{
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
index 7e4edf65325..75f43601331 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
@@ -4,7 +4,6 @@
using System.ComponentModel;
using System.Windows.Data;
using Flow.Launcher.Core;
-using static Flow.Launcher.Core.MessageBoxEx;
namespace Flow.Launcher.Plugin.WebSearch
{
@@ -38,7 +37,7 @@ private void OnDeleteSearchSearchClick(object sender, RoutedEventArgs e)
var warning = _context.API.GetTranslation("flowlauncher_plugin_websearch_delete_warning");
var formated = string.Format(warning, selected.Title);
- var result = MessageBoxEx.Show(formated, string.Empty, MessageBoxType.YesNo);
+ var result = MessageBoxEx.Show(formated, string.Empty, MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
var id = _context.CurrentPluginMetadata.ID;
From 32c138b9fda815fc9dd91a8709a946c6b0400dfd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 26 Nov 2024 22:02:24 +0800
Subject: [PATCH 0034/1335] Improve MessageBoxEx show function, making
experience like System.Windows.MessageBox
---
Flow.Launcher.Core/MessageBoxEx.xaml | 2 +-
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 91 +++++++++++++++----------
2 files changed, 56 insertions(+), 37 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index 8edb0873d49..10326c68729 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -21,7 +21,7 @@
-
+
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index b87302ca55a..4e50f466432 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -16,62 +16,52 @@ public MessageBoxEx()
static MessageBoxEx msgBox;
static MessageBoxResult _result = MessageBoxResult.No;
-
/// 1 parameter
public static MessageBoxResult Show(string messageBoxText)
{
- return Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None);
+ return Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
}
// 2 parameter
- public static MessageBoxResult Show(string messageBoxText, string title)
+ public static MessageBoxResult Show(string messageBoxText, string caption)
{
- return Show(messageBoxText, title, MessageBoxButton.OK, MessageBoxImage.None);
+ return Show(messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
}
/// 3 parameter
- public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxButton type)
+ public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
{
- return Show(messageBoxText, title, type, MessageBoxImage.None);
+ return Show(messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.OK);
}
- // 4 parameter, Final Display Message.
- public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxButton button, MessageBoxImage image)
+ // 4 parameter
+ public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
+ {
+ return Show(messageBoxText, caption, button, icon, MessageBoxResult.OK);
+ }
+
+ // 5 parameter, Final Display Message.
+ public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
msgBox = new MessageBoxEx();
- if (title == string.Empty && button == MessageBoxButton.OK && image == MessageBoxImage.None)
+ if (caption == string.Empty && button == MessageBoxButton.OK && icon == MessageBoxImage.None)
{
msgBox.DescOnlyTextBlock.Text = messageBoxText;
msgBox.Title = messageBoxText;
}
else
{
- msgBox.TitleTextBlock.Text = title;
+ msgBox.TitleTextBlock.Text = caption;
msgBox.DescTextBlock.Text = messageBoxText;
- msgBox.Title = title;
- SetImageOfMessageBox(image);
+ msgBox.Title = caption;
+ SetImageOfMessageBox(icon);
}
- SetVisibilityOfButtons(button);
+ SetVisibilityOfButtons(button, defaultResult);
msgBox.ShowDialog();
return _result;
}
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- if (sender == btnOk)
- _result = MessageBoxResult.OK;
- else if (sender == btnYes)
- _result = MessageBoxResult.Yes;
- else if (sender == btnNo)
- _result = MessageBoxResult.No;
- else if (sender == btnCancel)
- _result = MessageBoxResult.Cancel;
- else
- _result = MessageBoxResult.None;
- msgBox.Close();
- msgBox = null;
- }
- private static void SetVisibilityOfButtons(MessageBoxButton button)
+ private static void SetVisibilityOfButtons(MessageBoxButton button, MessageBoxResult defaultResult)
{
switch (button)
{
@@ -84,24 +74,36 @@ private static void SetVisibilityOfButtons(MessageBoxButton button)
case MessageBoxButton.OKCancel:
msgBox.btnNo.Visibility = Visibility.Collapsed;
msgBox.btnYes.Visibility = Visibility.Collapsed;
- msgBox.btnOk.Focus();
+ if (defaultResult == MessageBoxResult.Cancel)
+ msgBox.btnCancel.Focus();
+ else
+ msgBox.btnOk.Focus();
break;
case MessageBoxButton.YesNo:
msgBox.btnOk.Visibility = Visibility.Collapsed;
msgBox.btnCancel.Visibility = Visibility.Collapsed;
- msgBox.btnYes.Focus();
+ if (defaultResult == MessageBoxResult.No)
+ msgBox.btnNo.Focus();
+ else
+ msgBox.btnYes.Focus();
break;
case MessageBoxButton.YesNoCancel:
msgBox.btnOk.Visibility = Visibility.Collapsed;
- msgBox.btnYes.Focus();
+ if (defaultResult == MessageBoxResult.No)
+ msgBox.btnNo.Focus();
+ else if (defaultResult == MessageBoxResult.Cancel)
+ msgBox.btnCancel.Focus();
+ else
+ msgBox.btnYes.Focus();
break;
default:
break;
}
}
- private static void SetImageOfMessageBox(MessageBoxImage image)
+
+ private static void SetImageOfMessageBox(MessageBoxImage icon)
{
- switch (image)
+ switch (icon)
{
case MessageBoxImage.Exclamation:
msgBox.SetImage("Exclamation.png");
@@ -124,23 +126,40 @@ private static void SetImageOfMessageBox(MessageBoxImage image)
break;
}
}
+
private void SetImage(string imageName)
{
string uri = Constant.ProgramDirectory + "/Images/" + imageName;
var uriSource = new Uri(uri, UriKind.RelativeOrAbsolute);
Img.Source = new BitmapImage(uriSource);
}
- private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
+
+ private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
DialogResult = false;
Close();
}
- private void Button_Cancel(object sender, RoutedEventArgs e)
+ private void Button_Click(object sender, RoutedEventArgs e)
{
+ if (sender == btnOk)
+ _result = MessageBoxResult.OK;
+ else if (sender == btnYes)
+ _result = MessageBoxResult.Yes;
+ else if (sender == btnNo)
+ _result = MessageBoxResult.No;
+ else if (sender == btnCancel)
+ _result = MessageBoxResult.Cancel;
+ else
+ _result = MessageBoxResult.None;
msgBox.Close();
msgBox = null;
}
+ private void Button_Cancel(object sender, RoutedEventArgs e)
+ {
+ msgBox.Close();
+ msgBox = null;
+ }
}
}
From 7cb17ab4048d40e22ac394fed29f0641087edbe3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 26 Nov 2024 22:34:30 +0800
Subject: [PATCH 0035/1335] Improve title display experience & Fix three button
dialog display issue & Improve close button behaviour
---
Flow.Launcher.Core/MessageBoxEx.xaml | 15 +++++++------
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 29 +++++++++++++++++++------
2 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index 10326c68729..fff107a68a4 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -75,7 +75,7 @@
Grid.Column="0"
Width="18"
Height="18"
- Margin="0 0 0 0"
+ Margin="0 0 10 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
RenderOptions.BitmapScalingMode="Fant"
@@ -85,7 +85,7 @@
x:Name="TitleTextBlock"
Grid.Column="1"
MaxWidth="400"
- Margin="10 0 26 0"
+ Margin="0 0 26 0"
VerticalAlignment="Center"
FontFamily="Segoe UI"
FontSize="20"
@@ -112,7 +112,8 @@
VerticalAlignment="Center"
FontSize="14"
TextAlignment="Left"
- TextWrapping="Wrap" />
+ TextWrapping="Wrap"
+ Visibility="Collapsed" />
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index 4e50f466432..b94d594ee04 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -8,14 +8,16 @@ namespace Flow.Launcher.Core
{
public partial class MessageBoxEx : Window
{
- public MessageBoxEx()
+ private static MessageBoxEx msgBox;
+ private static MessageBoxResult _result = MessageBoxResult.None;
+ private static MessageBoxButton _button;
+
+ private MessageBoxEx(MessageBoxButton button)
{
+ _button = button;
InitializeComponent();
}
- static MessageBoxEx msgBox;
- static MessageBoxResult _result = MessageBoxResult.No;
-
/// 1 parameter
public static MessageBoxResult Show(string messageBoxText)
{
@@ -43,17 +45,18 @@ public static MessageBoxResult Show(string messageBoxText, string caption, Messa
// 5 parameter, Final Display Message.
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
- msgBox = new MessageBoxEx();
+ msgBox = new MessageBoxEx(button);
if (caption == string.Empty && button == MessageBoxButton.OK && icon == MessageBoxImage.None)
{
- msgBox.DescOnlyTextBlock.Text = messageBoxText;
msgBox.Title = messageBoxText;
+ msgBox.DescOnlyTextBlock.Visibility = Visibility.Visible;
+ msgBox.DescOnlyTextBlock.Text = messageBoxText;
}
else
{
+ msgBox.Title = caption;
msgBox.TitleTextBlock.Text = caption;
msgBox.DescTextBlock.Text = messageBoxText;
- msgBox.Title = caption;
SetImageOfMessageBox(icon);
}
SetVisibilityOfButtons(button, defaultResult);
@@ -136,6 +139,12 @@ private void SetImage(string imageName)
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
+ if (_button == MessageBoxButton.YesNo)
+ return;
+ else if (_button == MessageBoxButton.OK)
+ _result = MessageBoxResult.OK;
+ else
+ _result = MessageBoxResult.Cancel;
DialogResult = false;
Close();
}
@@ -158,6 +167,12 @@ private void Button_Click(object sender, RoutedEventArgs e)
private void Button_Cancel(object sender, RoutedEventArgs e)
{
+ if (_button == MessageBoxButton.YesNo)
+ return;
+ else if (_button == MessageBoxButton.OK)
+ _result = MessageBoxResult.OK;
+ else
+ _result = MessageBoxResult.Cancel;
msgBox.Close();
msgBox = null;
}
From 7ba8d58bfcc8d94316dbc947b4304a7dd7b83265 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 09:20:28 +0800
Subject: [PATCH 0036/1335] Improve result handle & Improve exception support
---
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 68 +++++++++++++++++++------
1 file changed, 53 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index b94d594ee04..bca20c06730 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -3,6 +3,7 @@
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure;
+using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Core
{
@@ -10,7 +11,8 @@ public partial class MessageBoxEx : Window
{
private static MessageBoxEx msgBox;
private static MessageBoxResult _result = MessageBoxResult.None;
- private static MessageBoxButton _button;
+
+ private readonly MessageBoxButton _button;
private MessageBoxEx(MessageBoxButton button)
{
@@ -45,26 +47,40 @@ public static MessageBoxResult Show(string messageBoxText, string caption, Messa
// 5 parameter, Final Display Message.
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
- msgBox = new MessageBoxEx(button);
- if (caption == string.Empty && button == MessageBoxButton.OK && icon == MessageBoxImage.None)
+ if (!Application.Current.Dispatcher.CheckAccess())
{
- msgBox.Title = messageBoxText;
- msgBox.DescOnlyTextBlock.Visibility = Visibility.Visible;
- msgBox.DescOnlyTextBlock.Text = messageBoxText;
+ return Application.Current.Dispatcher.Invoke(() => Show(messageBoxText, caption, button, icon, defaultResult));
}
- else
+
+ try
+ {
+ msgBox = new MessageBoxEx(button);
+ if (caption == string.Empty && button == MessageBoxButton.OK && icon == MessageBoxImage.None)
+ {
+ msgBox.Title = messageBoxText;
+ msgBox.DescOnlyTextBlock.Visibility = Visibility.Visible;
+ msgBox.DescOnlyTextBlock.Text = messageBoxText;
+ }
+ else
+ {
+ msgBox.Title = caption;
+ msgBox.TitleTextBlock.Text = caption;
+ msgBox.DescTextBlock.Text = messageBoxText;
+ SetImageOfMessageBox(icon);
+ }
+ SetButtonVisibilityFocusAndResult(button, defaultResult);
+ msgBox.ShowDialog();
+ return _result;
+ }
+ catch (Exception e)
{
- msgBox.Title = caption;
- msgBox.TitleTextBlock.Text = caption;
- msgBox.DescTextBlock.Text = messageBoxText;
- SetImageOfMessageBox(icon);
+ Log.Error($"|MessageBoxEx.Show|An error occurred: {e.Message}");
+ msgBox = null;
+ return MessageBoxResult.None;
}
- SetVisibilityOfButtons(button, defaultResult);
- msgBox.ShowDialog();
- return _result;
}
- private static void SetVisibilityOfButtons(MessageBoxButton button, MessageBoxResult defaultResult)
+ private static void SetButtonVisibilityFocusAndResult(MessageBoxButton button, MessageBoxResult defaultResult)
{
switch (button)
{
@@ -73,31 +89,53 @@ private static void SetVisibilityOfButtons(MessageBoxButton button, MessageBoxRe
msgBox.btnNo.Visibility = Visibility.Collapsed;
msgBox.btnYes.Visibility = Visibility.Collapsed;
msgBox.btnOk.Focus();
+ _result = MessageBoxResult.OK;
break;
case MessageBoxButton.OKCancel:
msgBox.btnNo.Visibility = Visibility.Collapsed;
msgBox.btnYes.Visibility = Visibility.Collapsed;
if (defaultResult == MessageBoxResult.Cancel)
+ {
msgBox.btnCancel.Focus();
+ _result = MessageBoxResult.Cancel;
+ }
else
+ {
msgBox.btnOk.Focus();
+ _result = MessageBoxResult.OK;
+ }
break;
case MessageBoxButton.YesNo:
msgBox.btnOk.Visibility = Visibility.Collapsed;
msgBox.btnCancel.Visibility = Visibility.Collapsed;
if (defaultResult == MessageBoxResult.No)
+ {
msgBox.btnNo.Focus();
+ _result = MessageBoxResult.No;
+ }
else
+ {
msgBox.btnYes.Focus();
+ _result = MessageBoxResult.Yes;
+ }
break;
case MessageBoxButton.YesNoCancel:
msgBox.btnOk.Visibility = Visibility.Collapsed;
if (defaultResult == MessageBoxResult.No)
+ {
msgBox.btnNo.Focus();
+ _result = MessageBoxResult.No;
+ }
else if (defaultResult == MessageBoxResult.Cancel)
+ {
msgBox.btnCancel.Focus();
+ _result = MessageBoxResult.Cancel;
+ }
else
+ {
msgBox.btnYes.Focus();
+ _result = MessageBoxResult.Yes;
+ }
break;
default:
break;
From 9b75acdf217b0f93c942d7cbde5e31015158378d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 10:07:03 +0800
Subject: [PATCH 0037/1335] Add ShowMsgBox functions in public api
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 77 +++++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 14 ++++
2 files changed, 91 insertions(+)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index c95a8ce7b23..a747ba34023 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -7,6 +7,7 @@
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
namespace Flow.Launcher.Plugin
{
@@ -298,5 +299,81 @@ public interface IPublicAPI
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
+
+ ///
+ /// Displays a message box that has a message and that returns a result.
+ ///
+ /// A System.String that specifies the text to display.
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies which message box button
+ /// is clicked by the user.
+ ///
+ public MessageBoxResult ShowMsgBox(string messageBoxText);
+
+ ///
+ /// Displays a message box that has a message and title bar caption; and that returns
+ /// a result.
+ ///
+ /// A System.String that specifies the text to display.
+ /// A System.String that specifies the title bar caption to display.
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies which message box button
+ /// is clicked by the user.
+ ///
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption);
+
+ ///
+ /// Displays a message box that has a message, title bar caption, and button; and
+ /// that returns a result.
+ ///
+ /// A System.String that specifies the text to display.
+ /// A System.String that specifies the title bar caption to display.
+ ///
+ /// A System.Windows.MessageBoxButton value that specifies which button or buttons
+ /// to display.
+ ///
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies which message box button
+ /// is clicked by the user.
+ ///
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button);
+
+ ///
+ /// Displays a message box that has a message, title bar caption, button, and icon;
+ /// and that returns a result.
+ ///
+ /// A System.String that specifies the text to display.
+ /// A System.String that specifies the title bar caption to display.
+ ///
+ /// A System.Windows.MessageBoxButton value that specifies which button or buttons
+ /// to display.
+ ///
+ /// A System.Windows.MessageBoxImage value that specifies the icon to display.
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies which message box button
+ /// is clicked by the user.
+ ///
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
+
+ ///
+ /// Displays a message box that has a message, title bar caption, button, and icon;
+ /// and that accepts a default message box result and returns a result.
+ ///
+ /// A System.String that specifies the text to display.
+ /// A System.String that specifies the title bar caption to display.
+ ///
+ /// A System.Windows.MessageBoxButton value that specifies which button or buttons
+ /// to display.
+ ///
+ /// A System.Windows.MessageBoxImage value that specifies the icon to display.
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies the default result of
+ /// the message box.
+ ///
+ ///
+ /// A System.Windows.MessageBoxResult value that specifies which message box button
+ /// is clicked by the user.
+ ///
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 20b02ddee8b..33739bda210 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -25,6 +25,7 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -318,6 +319,19 @@ public bool IsGameModeOn()
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
+ public MessageBoxResult ShowMsgBox(string messageBoxText) => MessageBoxEx.Show(messageBoxText);
+
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption) => MessageBoxEx.Show(messageBoxText, caption);
+
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button) =>
+ MessageBoxEx.Show(messageBoxText, caption, button);
+
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon) =>
+ MessageBoxEx.Show(messageBoxText, caption, button, icon);
+
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) =>
+ MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
+
#endregion
#region Private Methods
From 534a1117aa5c6b913a7965e9c3ce238ad522c290 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 12:21:34 +0800
Subject: [PATCH 0038/1335] Use public api to call ShowMsgBox functions &
remove useless Core project import
---
Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 3 +--
.../Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 3 +--
.../Search/Everything/EverythingDownloadHelper.cs | 5 ++---
.../Search/ResultManager.cs | 12 +++++-------
.../ViewModels/SettingsViewModel.cs | 3 +--
.../Views/ActionKeywordSetting.xaml.cs | 7 +++----
.../PluginsManager.cs | 15 +++++++--------
.../AddProgramSource.xaml.cs | 3 +--
.../Flow.Launcher.Plugin.Program.csproj | 1 -
.../ProgramSuffixes.xaml.cs | 5 ++---
.../Views/ProgramSetting.xaml.cs | 7 +++----
.../Flow.Launcher.Plugin.Sys.csproj | 1 -
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 12 +++++-------
.../SearchSourceSetting.xaml.cs | 13 ++++++-------
.../SettingsControl.xaml.cs | 3 +--
15 files changed, 38 insertions(+), 55 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
index 54a6f7a44b7..7f42eacf6db 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
@@ -7,7 +7,6 @@
using Mages.Core;
using Flow.Launcher.Plugin.Calculator.ViewModels;
using Flow.Launcher.Plugin.Calculator.Views;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Calculator
{
@@ -101,7 +100,7 @@ public List Query(Query query)
}
catch (ExternalException)
{
- MessageBoxEx.Show("Copy failed, please try later");
+ Context.API.ShowMsgBox("Copy failed, please try later");
return false;
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index b13d89f2c89..feccc74c8e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -11,7 +11,6 @@
using System.Linq;
using Flow.Launcher.Plugin.Explorer.Helper;
using Flow.Launcher.Plugin.Explorer.ViewModels;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Explorer
{
@@ -174,7 +173,7 @@ public List LoadContextMenus(Result selectedResult)
{
try
{
- if (MessageBoxEx.Show(
+ if (Context.API.ShowMsgBox(
string.Format(Context.API.GetTranslation("plugin_explorer_delete_folder_link"), record.FullPath),
string.Empty,
MessageBoxButton.YesNo,
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
index ddeec006410..d2f760f93bd 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
@@ -1,5 +1,4 @@
using Droplex;
-using Flow.Launcher.Core;
using Flow.Launcher.Plugin.SharedCommands;
using Microsoft.Win32;
using System;
@@ -21,7 +20,7 @@ public static async Task PromptDownloadIfNotInstallAsync(string installe
if (string.IsNullOrEmpty(installedLocation))
{
- if (MessageBoxEx.Show(
+ if (api.ShowMsgBox(
string.Format(api.GetTranslation("flowlauncher_plugin_everything_installing_select"), Environment.NewLine),
api.GetTranslation("flowlauncher_plugin_everything_installing_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
@@ -52,7 +51,7 @@ public static async Task PromptDownloadIfNotInstallAsync(string installe
installedLocation = "C:\\Program Files\\Everything\\Everything.exe";
- FilesFolders.OpenPath(installedLocation, MessageBoxEx.Show);
+ FilesFolders.OpenPath(installedLocation, api.ShowMsgBox);
return installedLocation;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index bffe75c290b..d42c477e158 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -5,14 +5,12 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using System.Windows.Input;
using Path = System.IO.Path;
using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Views;
using Peter;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Explorer.Search
{
@@ -124,7 +122,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -138,7 +136,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -153,7 +151,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
}
catch (Exception ex)
{
- MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
+ Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_opendir_error"));
return false;
}
}
@@ -316,7 +314,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
}
catch (Exception ex)
{
- MessageBoxEx.Show(ex.Message, Context.API.GetTranslation("plugin_explorer_openfile_error"));
+ Context.API.ShowMsgBox(ex.Message, Context.API.GetTranslation("plugin_explorer_openfile_error"));
}
return true;
@@ -338,7 +336,7 @@ private static bool IsMedia(string extension)
private static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false)
{
IncrementEverythingRunCounterIfNeeded(filePath);
- FilesFolders.OpenFile(filePath, MessageBoxEx.Show, workingDir, asAdmin);
+ FilesFolders.OpenFile(filePath, Context.API.ShowMsgBox, workingDir, asAdmin);
}
private static void OpenFolder(string folderPath, string fileNameOrFilePath = null)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 49b4a9fa23e..d2b85e6877d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -1,5 +1,4 @@
#nullable enable
-using Flow.Launcher.Core;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
@@ -358,7 +357,7 @@ private void EditLink(object commandParameter)
private void ShowUnselectedMessage()
{
var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
- MessageBoxEx.Show(warning);
+ Context.API.ShowMsgBox(warning);
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index fdfe1638a48..34a5b276008 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -3,7 +3,6 @@
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Explorer.Views
{
@@ -63,10 +62,10 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e)
switch (CurrentActionKeyword.KeywordProperty, KeywordEnabled)
{
case (Settings.ActionKeyword.FileContentSearchActionKeyword, true):
- MessageBoxEx.Show(api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
+ api.ShowMsgBox(api.GetTranslation("plugin_explorer_globalActionKeywordInvalid"));
return;
case (Settings.ActionKeyword.QuickAccessActionKeyword, true):
- MessageBoxEx.Show(api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
+ api.ShowMsgBox(api.GetTranslation("plugin_explorer_quickaccess_globalActionKeywordInvalid"));
return;
}
@@ -78,7 +77,7 @@ private void OnDoneButtonClick(object sender, RoutedEventArgs e)
}
// The keyword is not valid, so show message
- MessageBoxEx.Show(api.GetTranslation("newActionKeywordsHasBeenAssigned"));
+ api.ShowMsgBox(api.GetTranslation("newActionKeywordsHasBeenAssigned"));
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fd978c6d116..305d248d3e8 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -132,7 +131,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
Environment.NewLine);
}
- if (MessageBoxEx.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
+ if (Context.API.ShowMsgBox(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
MessageBoxButton.YesNo) == MessageBoxResult.No)
return;
@@ -266,7 +265,7 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
Environment.NewLine);
}
- if (MessageBoxEx.Show(message,
+ if (Context.API.ShowMsgBox(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
MessageBoxButton.YesNo) != MessageBoxResult.Yes)
{
@@ -361,7 +360,7 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
resultsForUpdate.Count());
}
- if (MessageBoxEx.Show(message,
+ if (Context.API.ShowMsgBox(message,
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
MessageBoxButton.YesNo) == MessageBoxResult.No)
{
@@ -475,7 +474,7 @@ internal List InstallFromWeb(string url)
if (Settings.WarnFromUnknownSource)
{
if (!InstallSourceKnown(plugin.UrlDownload)
- && MessageBoxEx.Show(string.Format(
+ && Context.API.ShowMsgBox(string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"),
Environment.NewLine),
Context.API.GetTranslation(
@@ -512,7 +511,7 @@ internal List InstallFromLocalPath(string localPath)
if (Settings.WarnFromUnknownSource)
{
if (!InstallSourceKnown(plugin.Website)
- && MessageBoxEx.Show(string.Format(
+ && Context.API.ShowMsgBox(string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_install_unknown_source_warning"),
Environment.NewLine),
@@ -649,7 +648,7 @@ internal List RequestUninstall(string search)
Environment.NewLine);
}
- if (MessageBoxEx.Show(message,
+ if (Context.API.ShowMsgBox(message,
Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
diff --git a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
index fef16cb33ce..6385ab364bb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml.cs
@@ -1,5 +1,4 @@
using System.Windows;
-using Flow.Launcher.Core;
using Flow.Launcher.Plugin.Program.ViewModels;
namespace Flow.Launcher.Plugin.Program
@@ -33,7 +32,7 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
var (modified, msg) = ViewModel.AddOrUpdate();
if (modified == false && msg != null)
{
- MessageBoxEx.Show(msg); // Invalid
+ ViewModel.API.ShowMsgBox(msg); // Invalid
return;
}
DialogResult = modified;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
index 68363c1faf5..4d88eef2c97 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
@@ -54,7 +54,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
index af1df8e71a6..55d44bdc2f0 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Windows;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Program
{
@@ -40,14 +39,14 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
if (suffixes.Length == 0 && UseCustomSuffixes)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_program_suffixes_cannot_empty");
- MessageBoxEx.Show(warning);
+ context.API.ShowMsgBox(warning);
return;
}
if (protocols.Length == 0 && UseCustomProtocols)
{
string warning = context.API.GetTranslation("flowlauncher_plugin_protocols_cannot_empty");
- MessageBoxEx.Show(warning);
+ context.API.ShowMsgBox(warning);
return;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index c7595c49dc8..36b5acc8acb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -10,7 +10,6 @@
using System.ComponentModel;
using System.Windows.Data;
using Flow.Launcher.Plugin.Program.ViewModels;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.Program.Views
{
@@ -179,7 +178,7 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
if (selectedProgramSource == null)
{
string msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- MessageBoxEx.Show(msg);
+ context.API.ShowMsgBox(msg);
}
else
{
@@ -284,7 +283,7 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
if (selectedItems.Count == 0)
{
string msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- MessageBoxEx.Show(msg);
+ context.API.ShowMsgBox(msg);
return;
}
@@ -293,7 +292,7 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
var msg = string.Format(
context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source"));
- if (MessageBoxEx.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (context.API.ShowMsgBox(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index 4e804e82c48..b797b3cf43a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -37,7 +37,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 94e83315bea..6e55582280f 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -2,12 +2,10 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
-using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -143,7 +141,7 @@ private List Commands()
IcoPath = "Images\\shutdown.png",
Action = c =>
{
- var result = MessageBoxEx.Show(
+ var result = context.API.ShowMsgBox(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -163,7 +161,7 @@ private List Commands()
IcoPath = "Images\\restart.png",
Action = c =>
{
- var result = MessageBoxEx.Show(
+ var result = context.API.ShowMsgBox(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -183,7 +181,7 @@ private List Commands()
IcoPath = "Images\\restart_advanced.png",
Action = c =>
{
- var result = MessageBoxEx.Show(
+ var result = context.API.ShowMsgBox(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer_advanced"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -202,7 +200,7 @@ private List Commands()
IcoPath = "Images\\logoff.png",
Action = c =>
{
- var result = MessageBoxEx.Show(
+ var result = context.API.ShowMsgBox(
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_logoff_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
@@ -279,7 +277,7 @@ private List Commands()
var result = SHEmptyRecycleBin(new WindowInteropHelper(Application.Current.MainWindow).Handle, 0);
if (result != (uint) HRESULT.S_OK && result != (uint) 0x8000FFFF)
{
- MessageBoxEx.Show($"Error emptying recycle bin, error code: {result}\n" +
+ context.API.ShowMsgBox($"Error emptying recycle bin, error code: {result}\n" +
"please refer to https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137",
"Error",
MessageBoxButton.OK, MessageBoxImage.Error);
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index 8336f4b9a2b..a3e5630c22e 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -2,7 +2,6 @@
using System.Windows;
using Microsoft.Win32;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.WebSearch
{
@@ -56,17 +55,17 @@ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
if (string.IsNullOrEmpty(_searchSource.Title))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_title");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
else if (string.IsNullOrEmpty(_searchSource.Url))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_url");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
else if (string.IsNullOrEmpty(_searchSource.ActionKeyword))
{
var warning = _api.GetTranslation("flowlauncher_plugin_websearch_input_action_keyword");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
else if (_action == Action.Add)
{
@@ -93,7 +92,7 @@ private void AddSearchSource()
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
}
@@ -114,7 +113,7 @@ private void EditSearchSource()
else
{
var warning = _api.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(warning);
+ _context.API.ShowMsgBox(warning);
}
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
@@ -139,7 +138,7 @@ private async void OnSelectIconClick(object sender, RoutedEventArgs e)
if (!string.IsNullOrEmpty(selectedNewIconImageFullPath))
{
if (_viewModel.ShouldProvideHint(selectedNewIconImageFullPath))
- MessageBoxEx.Show(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));
+ _context.API.ShowMsgBox(_api.GetTranslation("flowlauncher_plugin_websearch_iconpath_hint"));
imgPreviewIcon.Source = await _viewModel.LoadPreviewIconAsync(selectedNewIconImageFullPath);
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
index 75f43601331..739bc9d6be6 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
@@ -3,7 +3,6 @@
using Flow.Launcher.Core.Plugin;
using System.ComponentModel;
using System.Windows.Data;
-using Flow.Launcher.Core;
namespace Flow.Launcher.Plugin.WebSearch
{
@@ -37,7 +36,7 @@ private void OnDeleteSearchSearchClick(object sender, RoutedEventArgs e)
var warning = _context.API.GetTranslation("flowlauncher_plugin_websearch_delete_warning");
var formated = string.Format(warning, selected.Title);
- var result = MessageBoxEx.Show(formated, string.Empty, MessageBoxButton.YesNo);
+ var result = _context.API.ShowMsgBox(formated, string.Empty, MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
var id = _context.CurrentPluginMetadata.ID;
From 129169e0a9372053529067d760c55ddad9b642d8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 19:33:33 +0800
Subject: [PATCH 0039/1335] Fix possible null reference when query is cancelled
---
Flow.Launcher/Storage/TopMostRecord.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 052c296cdde..50ce96dedd8 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,7 +12,7 @@ public class TopMostRecord
internal bool IsTopMost(Result result)
{
- if (records.Count == 0 || !records.ContainsKey(result.OriginQuery.RawQuery))
+ if (records.Count == 0 || (result.OriginQuery != null && !records.ContainsKey(result.OriginQuery.RawQuery)))
{
return false;
}
From a8d69c7dd98aae982a44dcc06dcd82d65753a739 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 19:34:34 +0800
Subject: [PATCH 0040/1335] Add support when image format is not support
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 612f495be64..c5bba9fedb3 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -215,8 +215,15 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
type = ImageType.ImageFile;
if (loadFullImage)
{
- image = LoadFullImage(path);
- type = ImageType.FullImageFile;
+ try
+ {
+ image = LoadFullImage(path);
+ type = ImageType.FullImageFile;
+ }
+ catch (NotSupportedException)
+ {
+ image = null;
+ }
}
else
{
@@ -242,7 +249,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
if (type != ImageType.Error)
{
- image.Freeze();
+ image?.Freeze();
}
return new ImageResult(image, type);
From 756e718775c479658bd8a233430167c7460c810a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 19:46:30 +0800
Subject: [PATCH 0041/1335] Regard format not support files as error type
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index c5bba9fedb3..4592269a254 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -223,6 +223,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
catch (NotSupportedException)
{
image = null;
+ type = ImageType.Error;
}
}
else
@@ -249,7 +250,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
if (type != ImageType.Error)
{
- image?.Freeze();
+ image.Freeze();
}
return new ImageResult(image, type);
From 0720779c6b0632eb7f8ac26e78b1f28b5f1e5569 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 20:19:31 +0800
Subject: [PATCH 0042/1335] Fix possible null reference when query is cancelled
---
Flow.Launcher/Storage/TopMostRecord.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 50ce96dedd8..a088353f594 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -18,7 +18,7 @@ internal bool IsTopMost(Result result)
}
// since this dictionary should be very small (or empty) going over it should be pretty fast.
- return records[result.OriginQuery.RawQuery].Equals(result);
+ return result.OriginQuery != null && records[result.OriginQuery.RawQuery].Equals(result);
}
internal void Remove(Result result)
From b95bbb3e6a2ce2e384f874e381b9ff0190f00c57 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 20:56:14 +0800
Subject: [PATCH 0043/1335] Introduce concurrent directionary for topmost
record
---
Flow.Launcher/Storage/TopMostRecord.cs | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index a088353f594..069b670cbc3 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -1,18 +1,18 @@
-using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Text.Json.Serialization;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Storage
{
- // todo this class is not thread safe.... but used from multiple threads.
public class TopMostRecord
{
[JsonInclude]
- public Dictionary records { get; private set; } = new Dictionary();
+ public ConcurrentDictionary records { get; private set; } = new ConcurrentDictionary();
internal bool IsTopMost(Result result)
{
- if (records.Count == 0 || (result.OriginQuery != null && !records.ContainsKey(result.OriginQuery.RawQuery)))
+ if (records.IsEmpty || (result.OriginQuery != null && !records.ContainsKey(result.OriginQuery.RawQuery)))
{
return false;
}
@@ -23,7 +23,7 @@ internal bool IsTopMost(Result result)
internal void Remove(Result result)
{
- records.Remove(result.OriginQuery.RawQuery);
+ records.Remove(result.OriginQuery.RawQuery, out _);
}
internal void AddOrUpdate(Result result)
@@ -34,17 +34,15 @@ internal void AddOrUpdate(Result result)
Title = result.Title,
SubTitle = result.SubTitle
};
- records[result.OriginQuery.RawQuery] = record;
-
+ records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
public void Load(Dictionary dictionary)
{
- records = dictionary;
+ records = new ConcurrentDictionary(dictionary);
}
}
-
public class Record
{
public string Title { get; set; }
From c474b304f539e657b1d289575aa2b6244db47180 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 21:21:42 +0800
Subject: [PATCH 0044/1335] Fix possible null reference
---
Flow.Launcher/Storage/UserSelectedRecord.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Storage/UserSelectedRecord.cs b/Flow.Launcher/Storage/UserSelectedRecord.cs
index 6afe1e91f8d..d6405005dba 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -51,6 +51,11 @@ private static int GenerateResultHashCode(Result result)
private static int GenerateQueryAndResultHashCode(Query query, Result result)
{
+ if (query == null)
+ {
+ return GenerateResultHashCode(result);
+ }
+
int hashcode = GenerateStaticHashCode(query.ActionKeyword);
hashcode = GenerateStaticHashCode(query.Search, hashcode);
hashcode = GenerateStaticHashCode(result.Title, hashcode);
@@ -101,4 +106,4 @@ public int GetSelectedCount(Result result)
return selectedCount;
}
}
-}
\ No newline at end of file
+}
From d8c07a5741a6bde36e12e6aeb237af537274a80b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 21:44:44 +0800
Subject: [PATCH 0045/1335] Fix result update issue during modified collection
enumeration
---
Flow.Launcher/ViewModel/MainViewModel.cs | 35 ++++++++++++++----------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6c17e21f0d2..f07d5c6dd96 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -1440,26 +1440,33 @@ public void UpdateResultView(ICollection resultsForUpdates)
}
#endif
- foreach (var metaResults in resultsForUpdates)
+ try
{
- foreach (var result in metaResults.Results)
+ foreach (var metaResults in resultsForUpdates)
{
- if (_topMostRecord.IsTopMost(result))
- {
- result.Score = int.MaxValue;
- }
- else
+ foreach (var result in metaResults.Results)
{
- var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ if (_topMostRecord.IsTopMost(result))
+ {
+ result.Score = int.MaxValue;
+ }
+ else
+ {
+ var priorityScore = metaResults.Metadata.Priority * 150;
+ result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ }
}
}
- }
- // it should be the same for all results
- bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
+ // it should be the same for all results
+ bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
- Results.AddResults(resultsForUpdates, token, reSelect);
+ Results.AddResults(resultsForUpdates, token, reSelect);
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("MainViewModel", $"Error in UpdateResultView: {ex.Message}");
+ }
}
#endregion
From c3c6126bab91b1e61fa951f8cf8a2dd902f81a19 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 21:57:17 +0800
Subject: [PATCH 0046/1335] Fix xaml convert issue and use icon loader for
PluginActivationIcon
---
Flow.Launcher/MainWindow.xaml | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index b9ad975345c..f5fd729d45b 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -308,7 +308,7 @@
VerticalAlignment="Center"
Panel.ZIndex="2"
RenderOptions.BitmapScalingMode="HighQuality"
- Source="{Binding PluginIconPath}"
+ Source="{Binding PluginIconSource}"
Stretch="Uniform"
Style="{DynamicResource PluginActivationIcon}" />
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f07d5c6dd96..7b96e0cf3c1 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -23,6 +23,8 @@
using System.Globalization;
using System.Windows.Input;
using System.ComponentModel;
+using Flow.Launcher.Infrastructure.Image;
+using System.Windows.Media;
namespace Flow.Launcher.ViewModel
{
@@ -722,6 +724,8 @@ public double ResultSubItemFontSize
set => Settings.ResultSubItemFontSize = value;
}
+ public ImageSource PluginIconSource { get; private set; } = null;
+
public string PluginIconPath { get; set; } = null;
public string OpenResultCommandModifiers => Settings.OpenResultModifiers;
@@ -1066,6 +1070,7 @@ private async void QueryResults(bool isReQuery = false, bool reSelect = true)
Results.Clear();
Results.Visibility = Visibility.Collapsed;
PluginIconPath = null;
+ PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
return;
}
@@ -1099,11 +1104,13 @@ private async void QueryResults(bool isReQuery = false, bool reSelect = true)
if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
+ PluginIconSource = await ImageLoader.LoadAsync(PluginIconPath);
SearchIconVisibility = Visibility.Hidden;
}
else
{
PluginIconPath = null;
+ PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
}
@@ -1467,6 +1474,8 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
Log.Debug("MainViewModel", $"Error in UpdateResultView: {ex.Message}");
}
+
+
}
#endregion
From 5d8f277aa0e0339e15f2cd59e283e2b701863f26 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 22:16:52 +0800
Subject: [PATCH 0047/1335] Use image loader to load image
---
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index bca20c06730..dd1e9a606aa 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -1,8 +1,9 @@
using System;
+using System.IO;
using System.Windows;
using System.Windows.Input;
-using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure;
+using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Core
@@ -142,7 +143,7 @@ private static void SetButtonVisibilityFocusAndResult(MessageBoxButton button, M
}
}
- private static void SetImageOfMessageBox(MessageBoxImage icon)
+ private static async void SetImageOfMessageBox(MessageBoxImage icon)
{
switch (icon)
{
@@ -168,11 +169,11 @@ private static void SetImageOfMessageBox(MessageBoxImage icon)
}
}
- private void SetImage(string imageName)
+ private async void SetImage(string imageName)
{
- string uri = Constant.ProgramDirectory + "/Images/" + imageName;
- var uriSource = new Uri(uri, UriKind.RelativeOrAbsolute);
- Img.Source = new BitmapImage(uriSource);
+ var imagePath = Path.Combine(Constant.ProgramDirectory, "Images", imageName);
+ var imageSource = await ImageLoader.LoadAsync(imagePath);
+ Img.Source = imageSource;
}
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
From 5312505d2aa73825334657005fcf669f9d13f7f8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 27 Nov 2024 22:27:30 +0800
Subject: [PATCH 0048/1335] Improve code quality
---
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index dd1e9a606aa..cdccb2c00c2 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure;
@@ -67,7 +68,7 @@ public static MessageBoxResult Show(string messageBoxText, string caption, Messa
msgBox.Title = caption;
msgBox.TitleTextBlock.Text = caption;
msgBox.DescTextBlock.Text = messageBoxText;
- SetImageOfMessageBox(icon);
+ _ = SetImageOfMessageBoxAsync(icon);
}
SetButtonVisibilityFocusAndResult(button, defaultResult);
msgBox.ShowDialog();
@@ -143,24 +144,24 @@ private static void SetButtonVisibilityFocusAndResult(MessageBoxButton button, M
}
}
- private static async void SetImageOfMessageBox(MessageBoxImage icon)
+ private static async Task SetImageOfMessageBoxAsync(MessageBoxImage icon)
{
switch (icon)
{
case MessageBoxImage.Exclamation:
- msgBox.SetImage("Exclamation.png");
+ await msgBox.SetImageAsync("Exclamation.png");
msgBox.Img.Visibility = Visibility.Visible;
break;
case MessageBoxImage.Question:
- msgBox.SetImage("Question.png");
+ await msgBox.SetImageAsync("Question.png");
msgBox.Img.Visibility = Visibility.Visible;
break;
case MessageBoxImage.Information:
- msgBox.SetImage("Information.png");
+ await msgBox.SetImageAsync("Information.png");
msgBox.Img.Visibility = Visibility.Visible;
break;
case MessageBoxImage.Error:
- msgBox.SetImage("Error.png");
+ await msgBox.SetImageAsync("Error.png");
msgBox.Img.Visibility = Visibility.Visible;
break;
default:
@@ -169,7 +170,7 @@ private static async void SetImageOfMessageBox(MessageBoxImage icon)
}
}
- private async void SetImage(string imageName)
+ private async Task SetImageAsync(string imageName)
{
var imagePath = Path.Combine(Constant.ProgramDirectory, "Images", imageName);
var imageSource = await ImageLoader.LoadAsync(imagePath);
From 0d362b30dd5c78f9c13a5127aa677085f6beef62 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 1 Dec 2024 18:38:48 +0800
Subject: [PATCH 0049/1335] Add default messageboxShow parameter for functions
in FilesFolders
---
.../SharedCommands/FilesFolders.cs | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
index 6e00b8a27b8..5f003e351dc 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -22,7 +22,7 @@ public static class FilesFolders
///
///
///
- public static void CopyAll(this string sourcePath, string targetPath, Func messageBoxExShow)
+ public static void CopyAll(this string sourcePath, string targetPath, Func messageBoxExShow = null)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourcePath);
@@ -63,6 +63,7 @@ public static void CopyAll(this string sourcePath, string targetPath, Func
///
///
- public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath, Func messageBoxExShow)
+ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath, Func messageBoxExShow = null)
{
try
{
@@ -98,6 +99,7 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat
#if DEBUG
throw;
#else
+ messageBoxExShow ??= MessageBox.Show;
messageBoxExShow(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
return false;
#endif
@@ -110,7 +112,7 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat
///
///
///
- public static void RemoveFolderIfExists(this string path, Func messageBoxExShow)
+ public static void RemoveFolderIfExists(this string path, Func messageBoxExShow = null)
{
try
{
@@ -122,6 +124,7 @@ public static void RemoveFolderIfExists(this string path, Func
///
///
- public static void OpenPath(string fileOrFolderPath, Func messageBoxExShow)
+ public static void OpenPath(string fileOrFolderPath, Func messageBoxExShow = null)
{
var psi = new ProcessStartInfo
{
@@ -170,6 +173,7 @@ public static void OpenPath(string fileOrFolderPath, Func
/// File path
- ///
/// Working directory
/// Open as Administrator
- public static void OpenFile(string filePath, Func messageBoxExShow, string workingDir = "", bool asAdmin = false)
+ ///
+ public static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false, Func messageBoxExShow = null)
{
var psi = new ProcessStartInfo
{
@@ -201,6 +205,7 @@ public static void OpenFile(string filePath, Func mess
#if DEBUG
throw;
#else
+ messageBoxExShow ??= MessageBox.Show;
messageBoxExShow(string.Format("Unable to open the path {0}, please check if it exists", filePath));
#endif
}
From b568d2dd950cf85ae3ff652ec526c5d9ea305d6d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 1 Dec 2024 19:55:07 +0800
Subject: [PATCH 0050/1335] Combine ShowMsgBox into one function.
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 81 ++-----------------
Flow.Launcher/PublicAPIInstance.cs | 12 +--
2 files changed, 9 insertions(+), 84 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index a747ba34023..282bb6e436e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -299,81 +299,16 @@ public interface IPublicAPI
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
-
- ///
- /// Displays a message box that has a message and that returns a result.
- ///
- /// A System.String that specifies the text to display.
- ///
- /// A System.Windows.MessageBoxResult value that specifies which message box button
- /// is clicked by the user.
- ///
- public MessageBoxResult ShowMsgBox(string messageBoxText);
///
- /// Displays a message box that has a message and title bar caption; and that returns
- /// a result.
+ /// Displays a message box like
///
- /// A System.String that specifies the text to display.
- /// A System.String that specifies the title bar caption to display.
- ///
- /// A System.Windows.MessageBoxResult value that specifies which message box button
- /// is clicked by the user.
- ///
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption);
-
- ///
- /// Displays a message box that has a message, title bar caption, and button; and
- /// that returns a result.
- ///
- /// A System.String that specifies the text to display.
- /// A System.String that specifies the title bar caption to display.
- ///
- /// A System.Windows.MessageBoxButton value that specifies which button or buttons
- /// to display.
- ///
- ///
- /// A System.Windows.MessageBoxResult value that specifies which message box button
- /// is clicked by the user.
- ///
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button);
-
- ///
- /// Displays a message box that has a message, title bar caption, button, and icon;
- /// and that returns a result.
- ///
- /// A System.String that specifies the text to display.
- /// A System.String that specifies the title bar caption to display.
- ///
- /// A System.Windows.MessageBoxButton value that specifies which button or buttons
- /// to display.
- ///
- /// A System.Windows.MessageBoxImage value that specifies the icon to display.
- ///
- /// A System.Windows.MessageBoxResult value that specifies which message box button
- /// is clicked by the user.
- ///
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
-
- ///
- /// Displays a message box that has a message, title bar caption, button, and icon;
- /// and that accepts a default message box result and returns a result.
- ///
- /// A System.String that specifies the text to display.
- /// A System.String that specifies the title bar caption to display.
- ///
- /// A System.Windows.MessageBoxButton value that specifies which button or buttons
- /// to display.
- ///
- /// A System.Windows.MessageBoxImage value that specifies the icon to display.
- ///
- /// A System.Windows.MessageBoxResult value that specifies the default result of
- /// the message box.
- ///
- ///
- /// A System.Windows.MessageBoxResult value that specifies which message box button
- /// is clicked by the user.
- ///
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
+ /// The message of the message box.
+ /// The caption of the message box.
+ /// Specifies which button or buttons to display.
+ /// Specifies the icon to display.
+ /// Specifies the default result of the message box.
+ /// Specifies which message box button is clicked by the user.
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 33739bda210..0e567cdd415 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -319,17 +319,7 @@ public bool IsGameModeOn()
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
- public MessageBoxResult ShowMsgBox(string messageBoxText) => MessageBoxEx.Show(messageBoxText);
-
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption) => MessageBoxEx.Show(messageBoxText, caption);
-
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button) =>
- MessageBoxEx.Show(messageBoxText, caption, button);
-
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon) =>
- MessageBoxEx.Show(messageBoxText, caption, button, icon);
-
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) =>
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
#endregion
From 57cbe10ef03834a627998e23e58c097687a6f55c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 1 Dec 2024 20:13:13 +0800
Subject: [PATCH 0051/1335] Fix parameter bug
---
.../Search/Everything/EverythingDownloadHelper.cs | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
index d2f760f93bd..c8bd68279f2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingDownloadHelper.cs
@@ -51,7 +51,7 @@ public static async Task PromptDownloadIfNotInstallAsync(string installe
installedLocation = "C:\\Program Files\\Everything\\Everything.exe";
- FilesFolders.OpenPath(installedLocation, api.ShowMsgBox);
+ FilesFolders.OpenPath(installedLocation, (string str) => api.ShowMsgBox(str));
return installedLocation;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index d42c477e158..1add8476577 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -336,7 +336,7 @@ private static bool IsMedia(string extension)
private static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false)
{
IncrementEverythingRunCounterIfNeeded(filePath);
- FilesFolders.OpenFile(filePath, Context.API.ShowMsgBox, workingDir, asAdmin);
+ FilesFolders.OpenFile(filePath, workingDir, asAdmin, (string str) => Context.API.ShowMsgBox(str));
}
private static void OpenFolder(string folderPath, string fileNameOrFilePath = null)
From c665482cb7684cbd40fa067aeb2d010185c0324f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 2 Dec 2024 13:10:46 +0800
Subject: [PATCH 0052/1335] Improve code quality
---
Flow.Launcher/Storage/TopMostRecord.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 069b670cbc3..cbd0b88fc7e 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,13 +12,14 @@ public class TopMostRecord
internal bool IsTopMost(Result result)
{
- if (records.IsEmpty || (result.OriginQuery != null && !records.ContainsKey(result.OriginQuery.RawQuery)))
+ if (records.IsEmpty || result.OriginQuery == null ||
+ !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
return false;
}
// since this dictionary should be very small (or empty) going over it should be pretty fast.
- return result.OriginQuery != null && records[result.OriginQuery.RawQuery].Equals(result);
+ return value.Equals(result);
}
internal void Remove(Result result)
From 4830988c555815e7ccbc40ef2f4bfb4a292a942f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 2 Dec 2024 13:54:07 +0800
Subject: [PATCH 0053/1335] Add image for format not supported images
---
Flow.Launcher.Infrastructure/Constant.cs | 1 +
.../Image/ImageLoader.cs | 3 ++-
Flow.Launcher/Images/no_image.png | Bin 0 -> 2051 bytes
3 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 Flow.Launcher/Images/no_image.png
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index 8a95ee79f77..c22355495de 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -31,6 +31,7 @@ public static class Constant
public static readonly string ErrorIcon = Path.Combine(ImagesDirectory, "app_error.png");
public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png");
public static readonly string LoadingImgIcon = Path.Combine(ImagesDirectory, "loading.png");
+ public static readonly string NoImageIcon = Path.Combine(ImagesDirectory, "no_image.png");
public static string PythonPath;
public static string NodePath;
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 4592269a254..10c769ca611 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -22,6 +22,7 @@ public static class ImageLoader
private static readonly ConcurrentDictionary GuidToKey = new();
private static IImageHashGenerator _hashGenerator;
private static readonly bool EnableImageHash = true;
+ public static ImageSource NoImage { get; } = new BitmapImage(new Uri(Constant.NoImageIcon));
public static ImageSource MissingImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon));
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
public const int SmallIconSize = 64;
@@ -222,7 +223,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
}
catch (NotSupportedException)
{
- image = null;
+ image = NoImage;
type = ImageType.Error;
}
}
diff --git a/Flow.Launcher/Images/no_image.png b/Flow.Launcher/Images/no_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8608727beb99f3445488002873532a82030762b
GIT binary patch
literal 2051
zcmV+e2>kbnP)P&2OC2OQN@VWaM;BVLi7-7
zczD=23Q-+L3B}ihkyqYab3I^d0+69}y*jY~h5&j1;r@uNwfh5e|o!g!xX+^U3Kc3Hh3QFCAk?mjG%b98@W~0;u7D10ypS
zc&^qk2)Y5N=9W=%F%DaA6wb~d2A(}^2n1aK)J!d-=zJV`J<(s|a2o?b^8hbTF2gw#
zLvBy>cPVrS(XVp^O#}Qb@P8Ec&mz|wSu=$l0bL_#7T_iS66|MZVD&^qQ_!wo1Wf|G
z`=ZvRsq=eCze`W@IPEX&>scGSe-2c_0aRHwH
z?!T~lBd~OaHywM6e1sZq8D*Cfuzx%wG!%7C@e7^9WP`DzDG0(so+pCJYxDX6D8HJ-ldU|J1{mO!cj|hJCBlH9)m9&5l83_$^sy%*Z_hm05v>NbUub%
z%^bCuJ9rch%)&7+hte}43`jsI=?cgKuy#dIadlo>05$wF3J2%#L=#6X=JpUA1G8`r
z&Ite{dr$MC2tx;cMvwtu?IZ|E?EsLE^-nZSQA@Tv1jpbUoag3#13*>~8Z{0U#+kB@LmNAjkm7afeZHC8+^`hAGg9#T|xgXb!HS
z^#Ka{W`%`W5`sG*3m~T>jB*hK#Q`4sXcB72(isvO?;4It0wCKE0>bm+2t^%!SpXJ-
zFq)(Xu=C_3)J#rSL^$Ir8kPq@QryEyMvwzwX%DT5pgh2dNvIWTR~W??;u{7adqKrs
zX$Y=%zbt_4w$%|72YB>E5NgEgi3rW#ECAUHDw2xO=9dLPQg%71EI2w)W*Q}z;)(%~Z3qG3IcW%T0L(2s%0?0@0DKTYx|3BOz@9VH!sedR
z00KgnGz3SBPZofwnO7d*kq-h$XLi&Fg{u}w^VI?%dqGYK2B=MZ
ze%SkGPs3bpWy#@c{N-ilh8$Lh}H5o(Kxtq$8*f@X$XdASXMH2ZaWcf9dH3
zAh%mOLjFhNDg*p|0#dW{!yrmWZ=>Q`Qg;Bk^U)}0>C@t
zSTBz^P6|yY*NYkjAcx!}(ku-@@#m~hpQS0pz%)At?S}
zqs+Qnr!(uuurj7L4*Ncz7n*NWfSisn@@XSv9{bLA|FK)K?Z?LOOUT_T`)w;l8)Vc5OTQy=U9e?-S%+uzfdETMED;+^ItufmKEZzq4c;Z+2Z`2o#Gv
zQ
Date: Mon, 2 Dec 2024 12:20:21 +0500
Subject: [PATCH 0054/1335] [Result] return data uri image support
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 2 +-
Flow.Launcher.Plugin/Result.cs | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 612f495be64..231fcfff81b 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -139,7 +139,7 @@ private static async ValueTask LoadInternalAsync(string path, bool
return new ImageResult(image, ImageType.ImageFile);
}
- if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
+ if (path.StartsWith("data:image", StringComparison.OrdinalIgnoreCase))
{
var imageSource = new BitmapImage(new Uri(path));
imageSource.Freeze();
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 9b42b102176..027631533a1 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -70,7 +70,8 @@ public string IcoPath
&& !string.IsNullOrEmpty(PluginDirectory)
&& !Path.IsPathRooted(value)
&& !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
- && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
+ && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
+ && !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase))
{
_icoPath = Path.Combine(PluginDirectory, value);
}
From de82819a4ab479c9e7b035f9f415abca3f143b07 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 2 Dec 2024 23:35:05 +0000
Subject: [PATCH 0055/1335] Bump StreamJsonRpc from 2.19.27 to 2.20.20
Bumps [StreamJsonRpc](https://github.com/microsoft/vs-streamjsonrpc) from 2.19.27 to 2.20.20.
- [Release notes](https://github.com/microsoft/vs-streamjsonrpc/releases)
- [Commits](https://github.com/microsoft/vs-streamjsonrpc/commits)
---
updated-dependencies:
- dependency-name: StreamJsonRpc
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 02cd5057032..8aeca4699ec 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -58,7 +58,7 @@
-
+
From 3f413d17ec4eac2101f3fe043ed21a61c21a19c2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 3 Dec 2024 14:07:56 +0800
Subject: [PATCH 0056/1335] Update image for format not supported images
---
Flow.Launcher.Infrastructure/Constant.cs | 2 +-
.../Image/ImageLoader.cs | 4 ++--
Flow.Launcher/Images/image.png | Bin 687 -> 1122 bytes
Flow.Launcher/Images/no_image.png | Bin 2051 -> 0 bytes
4 files changed, 3 insertions(+), 3 deletions(-)
delete mode 100644 Flow.Launcher/Images/no_image.png
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index c22355495de..2889e5ec7ed 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -31,7 +31,7 @@ public static class Constant
public static readonly string ErrorIcon = Path.Combine(ImagesDirectory, "app_error.png");
public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png");
public static readonly string LoadingImgIcon = Path.Combine(ImagesDirectory, "loading.png");
- public static readonly string NoImageIcon = Path.Combine(ImagesDirectory, "no_image.png");
+ public static readonly string ImageIcon = Path.Combine(ImagesDirectory, "image.png");
public static string PythonPath;
public static string NodePath;
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 10c769ca611..018c4f7c9e6 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -22,7 +22,7 @@ public static class ImageLoader
private static readonly ConcurrentDictionary GuidToKey = new();
private static IImageHashGenerator _hashGenerator;
private static readonly bool EnableImageHash = true;
- public static ImageSource NoImage { get; } = new BitmapImage(new Uri(Constant.NoImageIcon));
+ public static ImageSource Image { get; } = new BitmapImage(new Uri(Constant.ImageIcon));
public static ImageSource MissingImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon));
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
public const int SmallIconSize = 64;
@@ -223,7 +223,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
}
catch (NotSupportedException)
{
- image = NoImage;
+ image = Image;
type = ImageType.Error;
}
}
diff --git a/Flow.Launcher/Images/image.png b/Flow.Launcher/Images/image.png
index 9f26517e84ee607ab1cff7a3fdbee0b59a8d66e4..ea610046b222a9178405e41eb528e6b97f5f725a 100644
GIT binary patch
literal 1122
zcmV-o1fBbdP)y5P#8DhL-&5o`nr+0EABqD#`&`NF9)8{$-_W+nQSmqfa4UmZ2?JkPwp
z=aYPH+N62s`+48rOnXyf6h%=KMNt$*Q4~cPAklUVqd1OI9Iq$=NO1h_drj7iA5GvH
z_u$mSk+m&$MEG>)3mBYwII6bAjtG*D9qJySrqzxJ+(VO#VJATM2#xnI8$TjBK-h)|
z(gTG39)WvkaxuSK0AELt8=%dO2(kmT`9A{p(Bxu4b(Eb11(*Ac`9sJd=P1n!~9#WD4_QW9ap-UqV(l+8Uf
zxj3=m5sIpA_&);o(B$H*8~pG}7Q6gfsyED5OsS|1hLSkX#o%1}=31
z@47yFr4#u1$-sV=kwzwr|M~-Z;e5^co(4#G8^F2q-MHAP0pN82=g4v6ZI=ds2JrcN
zz?H8YK}~uD!Sevlr=7mugkOCC7V4WY(()8IpLU!#T<6Spbng6tjPGcqk?OH#-F$5@ku!TUvdY%=YdCg_HG+}G_r9Phr|%#zb0e}Mza?#75$0Tb
zi|JeMB2v|Y@=do<`PWMg(BJsQ$667Xu?|_0*f$%Fo%|A^^89l|e!Ys)#sB=znTHbk
z1h|d=!+~Z5A~9r_t{t%9wI@(=1}2d37h#o*iqPa~L&4e(=4+6+1oe(@%Pkw&r?o-?I7t%hiq
zClO5M2B=EAA=;Vp2qt3#OkTxeD2WIahm-$}*+?VV3m;Nehnz_(Sqw&Z^c%tV0Y)y}
zhuldk*bMa(!S?}XG(SOJc^z_#m$Mm)ZtpWfq^8yX0URq@UtrX-{m3h;MQ-sj7JEi;
z#;JN6G0Tmzhm13iM3RvidqmX_y>quh#vId#fy6PRx153
zJX9!n@={bpZ3Xq{$&)`?jHrl}uDxYrw#2liZA`MsW_Na*9S^Y)B{k#jbcf=6;K34R
z-+LeS&1Monp-^mV2+yL+%j^PUxXpk=VGHJ;Ex!3Ma^!T_JR9ubS>!X^645*WScaKA
zao0$R$OUi;05~kFAYlZSVJ1)BGv12G$15Nd!U$?#%wZ7{kqeNY+fI~3^a4z*grpG?
zCn0f!#7IaG5GxV6KzAb6QR38tMegs3$OZPDJJ3<0s#lV{5?n`#i%X0J>^Bro50Z}k
zNqGy2L+WTLF;
zm>-`)J-;R*{a*fZ>`q|l*crsEp4Mlv;r)o8?ffszmLBHlN(rCG@55eN1$=+g@XA%B
zKfZuNtF3$8cLmT_`Jko62x!;tfEJ1%%kbnP)P&2OC2OQN@VWaM;BVLi7-7
zczD=23Q-+L3B}ihkyqYab3I^d0+69}y*jY~h5&j1;r@uNwfh5e|o!g!xX+^U3Kc3Hh3QFCAk?mjG%b98@W~0;u7D10ypS
zc&^qk2)Y5N=9W=%F%DaA6wb~d2A(}^2n1aK)J!d-=zJV`J<(s|a2o?b^8hbTF2gw#
zLvBy>cPVrS(XVp^O#}Qb@P8Ec&mz|wSu=$l0bL_#7T_iS66|MZVD&^qQ_!wo1Wf|G
z`=ZvRsq=eCze`W@IPEX&>scGSe-2c_0aRHwH
z?!T~lBd~OaHywM6e1sZq8D*Cfuzx%wG!%7C@e7^9WP`DzDG0(so+pCJYxDX6D8HJ-ldU|J1{mO!cj|hJCBlH9)m9&5l83_$^sy%*Z_hm05v>NbUub%
z%^bCuJ9rch%)&7+hte}43`jsI=?cgKuy#dIadlo>05$wF3J2%#L=#6X=JpUA1G8`r
z&Ite{dr$MC2tx;cMvwtu?IZ|E?EsLE^-nZSQA@Tv1jpbUoag3#13*>~8Z{0U#+kB@LmNAjkm7afeZHC8+^`hAGg9#T|xgXb!HS
z^#Ka{W`%`W5`sG*3m~T>jB*hK#Q`4sXcB72(isvO?;4It0wCKE0>bm+2t^%!SpXJ-
zFq)(Xu=C_3)J#rSL^$Ir8kPq@QryEyMvwzwX%DT5pgh2dNvIWTR~W??;u{7adqKrs
zX$Y=%zbt_4w$%|72YB>E5NgEgi3rW#ECAUHDw2xO=9dLPQg%71EI2w)W*Q}z;)(%~Z3qG3IcW%T0L(2s%0?0@0DKTYx|3BOz@9VH!sedR
z00KgnGz3SBPZofwnO7d*kq-h$XLi&Fg{u}w^VI?%dqGYK2B=MZ
ze%SkGPs3bpWy#@c{N-ilh8$Lh}H5o(Kxtq$8*f@X$XdASXMH2ZaWcf9dH3
zAh%mOLjFhNDg*p|0#dW{!yrmWZ=>Q`Qg;Bk^U)}0>C@t
zSTBz^P6|yY*NYkjAcx!}(ku-@@#m~hpQS0pz%)At?S}
zqs+Qnr!(uuurj7L4*Ncz7n*NWfSisn@@XSv9{bLA|FK)K?Z?LOOUT_T`)w;l8)Vc5OTQy=U9e?-S%+uzfdETMED;+^ItufmKEZzq4c;Z+2Z`2o#Gv
zQ
Date: Wed, 4 Dec 2024 10:20:21 +0800
Subject: [PATCH 0057/1335] Revert "Fix result update issue during modified
collection enumeration"
---
Flow.Launcher/ViewModel/MainViewModel.cs | 35 +++++++++---------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 7b96e0cf3c1..f964be7954d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1447,35 +1447,26 @@ public void UpdateResultView(ICollection resultsForUpdates)
}
#endif
- try
+ foreach (var metaResults in resultsForUpdates)
{
- foreach (var metaResults in resultsForUpdates)
+ foreach (var result in metaResults.Results)
{
- foreach (var result in metaResults.Results)
+ if (_topMostRecord.IsTopMost(result))
{
- if (_topMostRecord.IsTopMost(result))
- {
- result.Score = int.MaxValue;
- }
- else
- {
- var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
- }
+ result.Score = int.MaxValue;
+ }
+ else
+ {
+ var priorityScore = metaResults.Metadata.Priority * 150;
+ result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
}
}
-
- // it should be the same for all results
- bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
-
- Results.AddResults(resultsForUpdates, token, reSelect);
- }
- catch (Exception ex)
- {
- Log.Debug("MainViewModel", $"Error in UpdateResultView: {ex.Message}");
}
-
+ // it should be the same for all results
+ bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
+
+ Results.AddResults(resultsForUpdates, token, reSelect);
}
#endregion
From fa8cd548f6c11d71cf9dbd91a5c6c1495837222b Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Thu, 5 Dec 2024 14:18:13 +0600
Subject: [PATCH 0058/1335] Add `.`, `./lib`, `./plugin` directories to path
for Python plugins
---
Flow.Launcher.Core/Plugin/PythonPlugin.cs | 52 ++++++++++++++++++---
Flow.Launcher.Core/Plugin/PythonPluginV2.cs | 31 +++++++++++-
2 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
index 536e69b3dbb..36160b92088 100644
--- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
@@ -1,4 +1,5 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
@@ -29,10 +30,6 @@ public PythonPlugin(string filename)
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
_startInfo.EnvironmentVariables["FLOW_APPLICATION_DIRECTORY"] = Constant.ApplicationDirectory;
-
-
- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
- _startInfo.ArgumentList.Add("-B");
}
protected override Task RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
@@ -50,10 +47,51 @@ protected override string Request(JsonRPCRequestModel rpcRequest, CancellationTo
// TODO: Async Action
return Execute(_startInfo);
}
+
public override async Task InitAsync(PluginInitContext context)
{
- _startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
- _startInfo.ArgumentList.Add("");
+ // Run .py files via `-c `
+ if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
+ {
+ var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
+ var libDirectory = Path.Combine(rootDirectory, "lib");
+ var pluginDirectory = Path.Combine(rootDirectory, "plugin");
+
+ // This makes it easier for plugin authors to import their own modules.
+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
+ _startInfo.ArgumentList.Add("-c");
+ _startInfo.ArgumentList.Add(
+ $"""
+ import sys
+ sys.path.append(r'{rootDirectory}')
+ sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{pluginDirectory}')
+
+ import runpy
+ runpy.run_path(r'{context.CurrentPluginMetadata.ExecuteFilePath}', None, '__main__')
+ """
+ );
+ // Plugins always expect the JSON data to be in the third argument
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
+ _startInfo.ArgumentList.Add("");
+ // Because plugins always expect the JSON data to be in the third argument, and specifying -c
+ // takes up two arguments, we have to move `-B` to the end.
+ _startInfo.ArgumentList.Add("-B");
+ }
+ // Run .pyz files as is
+ else
+ {
+ // -B flag is needed to tell python not to write .py[co] files.
+ // Because .pyc contains location infos which will prevent python portable
+ _startInfo.ArgumentList.Add("-B");
+ _startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ // Plugins always expect the JSON data to be in the third argument
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
+ _startInfo.ArgumentList.Add("");
+ }
+
await base.InitAsync(context);
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
}
diff --git a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
index 5c36e0eea7b..224653ba107 100644
--- a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
@@ -33,7 +33,36 @@ public PythonPluginV2(string filename)
public override async Task InitAsync(PluginInitContext context)
{
- StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ // Run .py files via `-c `
+ if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
+ {
+ var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
+ var libDirectory = Path.Combine(rootDirectory, "lib");
+ var pluginDirectory = Path.Combine(rootDirectory, "plugin");
+ var filePath = context.CurrentPluginMetadata.ExecuteFilePath;
+
+ // This makes it easier for plugin authors to import their own modules.
+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
+ StartInfo.ArgumentList.Add("-c");
+ StartInfo.ArgumentList.Add(
+ $"""
+ import sys
+ sys.path.append(r'{rootDirectory}')
+ sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{pluginDirectory}')
+
+ import runpy
+ runpy.run_path(r'{filePath}', None, '__main__')
+ """
+ );
+ }
+ // Run .pyz files as is
+ else
+ {
+ StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
+ }
await base.InitAsync(context);
}
From d5dd7b44a41322ebdd9e4e97a25e62e653775688 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Thu, 5 Dec 2024 17:37:54 +0600
Subject: [PATCH 0059/1335] Use PYTHONDONTWRITEBYTECODE instead of -B flag when
running Python plugins
---
Flow.Launcher.Core/Plugin/PythonPlugin.cs | 11 ++++++-----
Flow.Launcher.Core/Plugin/PythonPluginV2.cs | 4 +---
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
index 36160b92088..7b670742ab4 100644
--- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
@@ -26,6 +26,9 @@ public PythonPlugin(string filename)
var path = Path.Combine(Constant.ProgramDirectory, JsonRPC);
_startInfo.EnvironmentVariables["PYTHONPATH"] = path;
+ // Prevent Python from writing .py[co] files.
+ // Because .pyc contains location infos which will prevent python portable.
+ _startInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
@@ -76,15 +79,13 @@ import runpy
// Plugins always expect the JSON data to be in the third argument
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
_startInfo.ArgumentList.Add("");
- // Because plugins always expect the JSON data to be in the third argument, and specifying -c
- // takes up two arguments, we have to move `-B` to the end.
- _startInfo.ArgumentList.Add("-B");
}
// Run .pyz files as is
else
{
- // -B flag is needed to tell python not to write .py[co] files.
- // Because .pyc contains location infos which will prevent python portable
+ // No need for -B flag because we're using PYTHONDONTWRITEBYTECODE env variable now,
+ // but the plugins still expect data to be sent as the third argument, so we're keeping
+ // the flag here, even though it's not necessary anymore.
_startInfo.ArgumentList.Add("-B");
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
// Plugins always expect the JSON data to be in the third argument
diff --git a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
index 224653ba107..03ac0e66154 100644
--- a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
@@ -26,9 +26,7 @@ public PythonPluginV2(string filename)
var path = Path.Combine(Constant.ProgramDirectory, JsonRpc);
StartInfo.EnvironmentVariables["PYTHONPATH"] = path;
-
- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
- StartInfo.ArgumentList.Add("-B");
+ StartInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
}
public override async Task InitAsync(PluginInitContext context)
From 41a345a70006e881709b1c6543e683926289b583 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 6 Dec 2024 23:55:20 -0600
Subject: [PATCH 0060/1335] Remove Result comparison and Change signature from
IEnumerable to ICollection (due to the potential of multiple enumeration)
---
Flow.Launcher.Plugin/Result.cs | 21 ---------------------
Flow.Launcher/ViewModel/ResultsViewModel.cs | 6 +++---
2 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 9b42b102176..ac0b827c02f 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -156,27 +156,6 @@ public string PluginDirectory
}
}
- ///
- public override bool Equals(object obj)
- {
- var r = obj as Result;
-
- var equality = string.Equals(r?.Title, Title) &&
- string.Equals(r?.SubTitle, SubTitle) &&
- string.Equals(r?.AutoCompleteText, AutoCompleteText) &&
- string.Equals(r?.CopyText, CopyText) &&
- string.Equals(r?.IcoPath, IcoPath) &&
- TitleHighlightData == r.TitleHighlightData;
-
- return equality;
- }
-
- ///
- public override int GetHashCode()
- {
- return HashCode.Combine(Title, SubTitle, AutoCompleteText, CopyText, IcoPath);
- }
-
///
public override string ToString()
{
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 107372e0115..c0e0b146d03 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -182,7 +182,7 @@ public void AddResults(List newRawResults, string resultId)
///
/// To avoid deadlock, this method should not called from main thread
///
- public void AddResults(IEnumerable resultsForUpdates, CancellationToken token, bool reselect = true)
+ public void AddResults(ICollection resultsForUpdates, CancellationToken token, bool reselect = true)
{
var newResults = NewResults(resultsForUpdates);
@@ -228,12 +228,12 @@ private List NewResults(List newRawResults, string resu
.ToList();
}
- private List NewResults(IEnumerable resultsForUpdates)
+ private List NewResults(ICollection resultsForUpdates)
{
if (!resultsForUpdates.Any())
return Results;
- return Results.Where(r => r != null && !resultsForUpdates.Any(u => u.ID == r.Result.PluginID))
+ return Results.Where(r => r != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
.Concat(resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)))
.OrderByDescending(rv => rv.Result.Score)
.ToList();
From 676a5b1590a93969a5cfde5aa2eec6d46103a73f Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sat, 7 Dec 2024 22:21:08 +1100
Subject: [PATCH 0061/1335] add defaults to MessageBoxEx Show & update
WebSearch to use api call
---
Flow.Launcher.Core/MessageBoxEx.xaml.cs | 31 +++++--------------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
.../Flow.Launcher.Plugin.WebSearch/Main.cs | 2 +-
.../SearchSourceViewModel.cs | 2 +-
4 files changed, 10 insertions(+), 27 deletions(-)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml.cs b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
index cdccb2c00c2..a01b5f68d2c 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml.cs
@@ -22,32 +22,15 @@ private MessageBoxEx(MessageBoxButton button)
InitializeComponent();
}
- /// 1 parameter
public static MessageBoxResult Show(string messageBoxText)
- {
- return Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
- }
-
- // 2 parameter
- public static MessageBoxResult Show(string messageBoxText, string caption)
- {
- return Show(messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
- }
-
- /// 3 parameter
- public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
- {
- return Show(messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.OK);
- }
-
- // 4 parameter
- public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
- {
- return Show(messageBoxText, caption, button, icon, MessageBoxResult.OK);
- }
+ => Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
- // 5 parameter, Final Display Message.
- public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
+ public static MessageBoxResult Show(
+ string messageBoxText,
+ string caption = "",
+ MessageBoxButton button = MessageBoxButton.OK,
+ MessageBoxImage icon = MessageBoxImage.None,
+ MessageBoxResult defaultResult = MessageBoxResult.OK)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 282bb6e436e..1e36f3adc10 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -301,7 +301,7 @@ public interface IPublicAPI
public void ReQuery(bool reselect = true);
///
- /// Displays a message box like
+ /// Displays a standardised Flow message box.
///
/// The message of the message box.
/// The caption of the message box.
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index 39aa1738fca..9b52db5a8dd 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -13,7 +13,7 @@ namespace Flow.Launcher.Plugin.WebSearch
{
public class Main : IAsyncPlugin, ISettingProvider, IPluginI18n, IResultUpdated
{
- private PluginInitContext _context;
+ internal static PluginInitContext _context;
private Settings _settings;
private SettingsViewModel _viewModel;
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
index 0495772d540..9c5e81cb537 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
@@ -41,7 +41,7 @@ public void CopyNewImageToUserDataDirectoryIfRequired(
#if DEBUG
throw;
#else
- Flow.Launcher.Core.MessageBoxEx.Show(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
+ Main._context.API.ShowMsgBox(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
#endif
}
From 6410853e34d5b9cd9167226629056d91b5b83153 Mon Sep 17 00:00:00 2001
From: cibere <71997063+cibere@users.noreply.github.com>
Date: Sat, 7 Dec 2024 14:38:28 -0800
Subject: [PATCH 0062/1335] add `CopyText` to recyclebin, log folder, flow
tips, and userdata folder results in sys plugin
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 1ec07915d2b..a11a169deba 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -133,6 +133,8 @@ public void Init(PluginInitContext context)
private List Commands()
{
var results = new List();
+ var logPath = Path.Combine(DataLocation.DataDirectory(), "Logs", Constant.Version);
+ var userDataPath = DataLocation.DataDirectory()
results.AddRange(new[]
{
new Result
@@ -294,6 +296,7 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
+ CopyText = "shell:RecycleBinFolder",
Action = c =>
{
{
@@ -386,9 +389,9 @@ private List Commands()
Title = "Open Log Location",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
+ CopyText = logPath,
Action = c =>
{
- var logPath = Path.Combine(DataLocation.DataDirectory(), "Logs", Constant.Version);
context.API.OpenDirectory(logPath);
return true;
}
@@ -398,6 +401,7 @@ private List Commands()
Title = "Flow Launcher Tips",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
+ CopyText = Constant.Documentation,
Action = c =>
{
context.API.OpenUrl(Constant.Documentation);
@@ -409,9 +413,10 @@ private List Commands()
Title = "Flow Launcher UserData Folder",
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
+ CopyText = userDataPath,
Action = c =>
{
- context.API.OpenDirectory(DataLocation.DataDirectory());
+ context.API.OpenDirectory(userDataPath);
return true;
}
},
From 29c9fd69ad857d4bc79ccd0765fdf9ea3df502dc Mon Sep 17 00:00:00 2001
From: cibere <71997063+cibere@users.noreply.github.com>
Date: Sat, 7 Dec 2024 14:45:32 -0800
Subject: [PATCH 0063/1335] add `AutoCompleteText` key to some results in the
sys plugin
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index a11a169deba..7d240e89a34 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -134,7 +134,8 @@ private List Commands()
{
var results = new List();
var logPath = Path.Combine(DataLocation.DataDirectory(), "Logs", Constant.Version);
- var userDataPath = DataLocation.DataDirectory()
+ var userDataPath = DataLocation.DataDirectory();
+ var recycleBinFolder = "shell:RecycleBinFolder";
results.AddRange(new[]
{
new Result
@@ -296,11 +297,12 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
- CopyText = "shell:RecycleBinFolder",
+ CopyText = recycleBinFolder,
+ AutoCompleteText = recycleBinFolder,
Action = c =>
{
{
- System.Diagnostics.Process.Start("explorer", "shell:RecycleBinFolder");
+ System.Diagnostics.Process.Start("explorer", recycleBinFolder);
}
return true;
@@ -390,6 +392,7 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
CopyText = logPath,
+ AutoCompleteText = logPath,
Action = c =>
{
context.API.OpenDirectory(logPath);
@@ -402,6 +405,7 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
CopyText = Constant.Documentation,
+ AutoCompleteText = Constant.Documentation,
Action = c =>
{
context.API.OpenUrl(Constant.Documentation);
@@ -414,6 +418,7 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
CopyText = userDataPath,
+ AutoCompleteText = userDataPath,
Action = c =>
{
context.API.OpenDirectory(userDataPath);
From 0c43ea9379d8a487ac626434623996607889530d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 8 Dec 2024 09:24:17 +0800
Subject: [PATCH 0064/1335] Fix possible result update issue for plugins with
IResultUpdate interface
---
Flow.Launcher/ViewModel/MainViewModel.cs | 35 +++++++++++++++---------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f964be7954d..8a7d5c0d2b1 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1447,26 +1447,35 @@ public void UpdateResultView(ICollection resultsForUpdates)
}
#endif
- foreach (var metaResults in resultsForUpdates)
+ try
{
- foreach (var result in metaResults.Results)
+ foreach (var metaResults in resultsForUpdates)
{
- if (_topMostRecord.IsTopMost(result))
- {
- result.Score = int.MaxValue;
- }
- else
+ foreach (var result in metaResults.Results)
{
- var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ if (_topMostRecord.IsTopMost(result))
+ {
+ result.Score = int.MaxValue;
+ }
+ else
+ {
+ var priorityScore = metaResults.Metadata.Priority * 150;
+ result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ }
}
}
- }
- // it should be the same for all results
- bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
+ // it should be the same for all results
+ bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
- Results.AddResults(resultsForUpdates, token, reSelect);
+ Results.AddResults(resultsForUpdates, token, reSelect);
+ }
+ catch (InvalidOperationException e)
+ {
+ // Plugin with IResultUpdate interface can somtimes throw this exception
+ // Collection was modified; enumeration operation may not execute
+ Log.Exception($"{nameof(MainViewModel)}.{nameof(UpdateResultView)}|UpdateResultView failed", e);
+ }
}
#endregion
From 9a7c08b1cd3477f63200de4b5628217dbbfb8db0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 8 Dec 2024 10:00:51 +0800
Subject: [PATCH 0065/1335] Revert fix in MainViewModel & Fix possible issue in
WebSearch plugin
---
Flow.Launcher/ViewModel/MainViewModel.cs | 35 +++++++------------
.../Flow.Launcher.Plugin.WebSearch/Main.cs | 2 +-
2 files changed, 14 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8a7d5c0d2b1..f964be7954d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1447,35 +1447,26 @@ public void UpdateResultView(ICollection resultsForUpdates)
}
#endif
- try
+ foreach (var metaResults in resultsForUpdates)
{
- foreach (var metaResults in resultsForUpdates)
+ foreach (var result in metaResults.Results)
{
- foreach (var result in metaResults.Results)
+ if (_topMostRecord.IsTopMost(result))
{
- if (_topMostRecord.IsTopMost(result))
- {
- result.Score = int.MaxValue;
- }
- else
- {
- var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
- }
+ result.Score = int.MaxValue;
+ }
+ else
+ {
+ var priorityScore = metaResults.Metadata.Priority * 150;
+ result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
}
}
+ }
- // it should be the same for all results
- bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
+ // it should be the same for all results
+ bool reSelect = resultsForUpdates.First().ReSelectFirstResult;
- Results.AddResults(resultsForUpdates, token, reSelect);
- }
- catch (InvalidOperationException e)
- {
- // Plugin with IResultUpdate interface can somtimes throw this exception
- // Collection was modified; enumeration operation may not execute
- Log.Exception($"{nameof(MainViewModel)}.{nameof(UpdateResultView)}|UpdateResultView failed", e);
- }
+ Results.AddResults(resultsForUpdates, token, reSelect);
}
#endregion
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index ce53c7da5c4..1bb96384c1d 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -85,7 +85,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
{
- Results = results,
+ Results = results.ToList(),
Query = query
});
From 30938f1ce5c639bf2a5aa66a04cf0f5d2d996583 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 8 Dec 2024 12:01:46 +0800
Subject: [PATCH 0066/1335] Revert "Fix possible issue in WebSearch plugin"
---
Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index 1bb96384c1d..ce53c7da5c4 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -85,7 +85,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
{
- Results = results.ToList(),
+ Results = results,
Query = query
});
From 26d97a2f686afb750cfed7ffe451dac465bb0270 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 8 Dec 2024 12:02:04 +0800
Subject: [PATCH 0067/1335] Fix plugin change the result when updating view
model
---
Flow.Launcher/ViewModel/MainViewModel.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f964be7954d..e5364dbb367 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -233,8 +233,11 @@ private void RegisterResultsUpdatedEvent()
var token = e.Token == default ? _updateToken : e.Token;
- PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query);
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query,
+ // make a copy of results to avoid plugin change the result when updating view model
+ var resultsCopy = e.Results.ToList();
+
+ PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query);
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
token)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
From 824befdef62d1e10710d75c7481f74e54d0ee6d4 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Mon, 9 Dec 2024 02:33:19 +0600
Subject: [PATCH 0068/1335] Add preserve last action keyword options
---
.../UserSettings/Settings.cs | 8 +++++---
Flow.Launcher/Languages/en.xaml | 2 ++
Flow.Launcher/ViewModel/MainViewModel.cs | 16 +++++++++++++---
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0c7de10fd78..0bcc9368d22 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -62,7 +62,7 @@ public string Theme
public double ItemHeightSize { get; set; } = 58;
public double QueryBoxFontSize { get; set; } = 20;
public double ResultItemFontSize { get; set; } = 16;
- public double ResultSubItemFontSize { get; set; } = 13;
+ public double ResultSubItemFontSize { get; set; } = 13;
public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name;
public string QueryBoxFontStyle { get; set; }
public string QueryBoxFontWeight { get; set; }
@@ -187,7 +187,7 @@ public CustomBrowserViewModel CustomBrowser
public bool ShouldUsePinyin { get; set; } = false;
public bool AlwaysPreview { get; set; } = false;
-
+
public bool AlwaysStartEn { get; set; } = false;
private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular;
@@ -370,7 +370,9 @@ public enum LastQueryMode
{
Selected,
Empty,
- Preserved
+ Preserved,
+ ActionKeywordPreserved,
+ ActionKeywordSelected
}
public enum ColorSchemes
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index ffb03b63592..4c465d61f52 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -67,6 +67,8 @@
Preserve Last Query
Select last Query
Empty last Query
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Maximum results shown
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 626495cb68a..7260593dc28 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -771,7 +771,7 @@ public string VerifyOrSetDefaultHotkey(string hotkey, string defaultHotkey)
public string Image => Constant.QueryTextBoxIconImagePath;
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
-
+
#endregion
#region Preview
@@ -833,7 +833,7 @@ when CanExternalPreviewSelectedResult(out var path):
}
private void HidePreview()
- {
+ {
if (PluginManager.UseExternalPreview())
CloseExternalPreview();
@@ -912,7 +912,7 @@ when PluginManager.AllowAlwaysPreview() && CanExternalPreviewSelectedResult(out
break;
}
}
-
+
private void UpdatePreview()
{
switch (PluginManager.UseExternalPreview())
@@ -1401,6 +1401,16 @@ public async void Hide()
await Task.Delay(100);
LastQuerySelected = false;
break;
+ case LastQueryMode.ActionKeywordPreserved or LastQueryMode.ActionKeywordSelected:
+ var newQuery = _lastQuery.ActionKeyword;
+ if (!string.IsNullOrEmpty(newQuery))
+ newQuery += " ";
+ ChangeQueryText(newQuery);
+ if (Settings.UseAnimation)
+ await Task.Delay(100);
+ if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected)
+ LastQuerySelected = false;
+ break;
default:
throw new ArgumentException($"wrong LastQueryMode: <{Settings.LastQueryMode}>");
}
From 5b344fb53cad6fee62612680aebff55907fb3aed Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 9 Dec 2024 13:23:28 +0800
Subject: [PATCH 0069/1335] Improve windows index search with special character
---
.../Search/WindowsIndex/QueryConstructor.cs | 37 ++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
index a35bad274d3..9e3707fbeab 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs
@@ -1,10 +1,14 @@
using System;
+using System.Text.RegularExpressions;
using Microsoft.Search.Interop;
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
public class QueryConstructor
{
+ private static Regex _specialCharacterMatcher = new(@"[\@\@\#\#\&\&*_;,\%\|\!\(\)\{\}\[\]\^\~\?\\""\/\:\=\-]+", RegexOptions.Compiled);
+ private static Regex _multiWhiteSpacesMatcher = new(@"\s+", RegexOptions.Compiled);
+
private Settings settings { get; }
private const string SystemIndex = "SystemIndex";
@@ -76,8 +80,39 @@ public string FilesAndFolders(ReadOnlySpan userSearchString)
if (userSearchString.IsWhiteSpace())
userSearchString = "*";
+ // Remove any special characters that might cause issues with the query
+ var replacedSearchString = ReplaceSpecialCharacterWithTwoSideWhiteSpace(userSearchString);
+
// Generate SQL from constructed parameters, converting the userSearchString from AQS->WHERE clause
- return $"{CreateBaseQuery().GenerateSQLFromUserQuery(userSearchString.ToString())} AND {RestrictionsForAllFilesAndFoldersSearch} ORDER BY {FileName}";
+ return $"{CreateBaseQuery().GenerateSQLFromUserQuery(replacedSearchString)} AND {RestrictionsForAllFilesAndFoldersSearch} ORDER BY {FileName}";
+ }
+
+ ///
+ /// If one special character have white space on one side, replace it with one white space.
+ /// So command will not have "[special character]+*" which will cause OLEDB exception.
+ ///
+ private static string ReplaceSpecialCharacterWithTwoSideWhiteSpace(ReadOnlySpan input)
+ {
+ const string whiteSpace = " ";
+
+ var inputString = input.ToString();
+
+ // Use regex to match special characters with whitespace on one side
+ // and replace them with a single space
+ var result = _specialCharacterMatcher.Replace(inputString, match =>
+ {
+ // Check if the match has whitespace on one side
+ bool hasLeadingWhitespace = match.Index > 0 && char.IsWhiteSpace(inputString[match.Index - 1]);
+ bool hasTrailingWhitespace = match.Index + match.Length < inputString.Length && char.IsWhiteSpace(inputString[match.Index + match.Length]);
+ if (hasLeadingWhitespace || hasTrailingWhitespace)
+ {
+ return whiteSpace;
+ }
+ return match.Value;
+ });
+
+ // Remove any extra spaces that might have been introduced
+ return _multiWhiteSpacesMatcher.Replace(result, whiteSpace).Trim();
}
///
From a395936a6c6b8fa0f3d7c34ccbb0b876d88d035b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 11:56:32 +0800
Subject: [PATCH 0070/1335] Replace FormApplication & DllImport with CSWin32
---
.../Flow.Launcher.Plugin.Sys.csproj | 7 +++
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 44 ++++---------------
.../NativeMethods.txt | 6 +++
3 files changed, 21 insertions(+), 36 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index b797b3cf43a..dbc36ad424b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -57,4 +57,11 @@
PreserveNewest
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 6e55582280f..f80f3c9ddf4 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -2,17 +2,16 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Runtime.InteropServices;
using System.Windows;
-using System.Windows.Forms;
-using System.Windows.Interop;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.Shutdown;
using Application = System.Windows.Application;
using Control = System.Windows.Controls.Control;
-using FormsApplication = System.Windows.Forms.Application;
namespace Flow.Launcher.Plugin.Sys
{
@@ -21,33 +20,6 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
private PluginInitContext context;
private Dictionary KeywordTitleMappings = new Dictionary();
- #region DllImport
-
- internal const int EWX_LOGOFF = 0x00000000;
- internal const int EWX_SHUTDOWN = 0x00000001;
- internal const int EWX_REBOOT = 0x00000002;
- internal const int EWX_FORCE = 0x00000004;
- internal const int EWX_POWEROFF = 0x00000008;
- internal const int EWX_FORCEIFHUNG = 0x00000010;
-
- [DllImport("user32")]
- private static extern bool ExitWindowsEx(uint uFlags, uint dwReason);
-
- [DllImport("user32")]
- private static extern void LockWorkStation();
-
- [DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
- private static extern uint SHEmptyRecycleBin(IntPtr hWnd, uint dwFlags);
-
- // http://www.pinvoke.net/default.aspx/Enums/HRESULT.html
- private enum HRESULT : uint
- {
- S_FALSE = 0x0001,
- S_OK = 0x0000
- }
-
- #endregion
-
public Control CreateSettingPanel()
{
var results = Commands();
@@ -206,7 +178,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- ExitWindowsEx(EWX_LOGOFF, 0);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, 0);
return true;
}
@@ -219,7 +191,7 @@ private List Commands()
IcoPath = "Images\\lock.png",
Action = c =>
{
- LockWorkStation();
+ PInvoke.LockWorkStation();
return true;
}
},
@@ -229,7 +201,7 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
- Action = c => FormsApplication.SetSuspendState(PowerState.Suspend, false, false)
+ Action = c => PInvoke.SetSuspendState(false, false, false)
},
new Result
{
@@ -274,8 +246,8 @@ private List Commands()
// http://www.pinvoke.net/default.aspx/shell32/SHEmptyRecycleBin.html
// FYI, couldn't find documentation for this but if the recycle bin is already empty, it will return -2147418113 (0x8000FFFF (E_UNEXPECTED))
// 0 for nothing
- var result = SHEmptyRecycleBin(new WindowInteropHelper(Application.Current.MainWindow).Handle, 0);
- if (result != (uint) HRESULT.S_OK && result != (uint) 0x8000FFFF)
+ var result = PInvoke.SHEmptyRecycleBin(new(), string.Empty, 0);
+ if (result != HRESULT.S_OK && result != HRESULT.E_UNEXPECTED)
{
context.API.ShowMsgBox($"Error emptying recycle bin, error code: {result}\n" +
"please refer to https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137",
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
new file mode 100644
index 00000000000..8fcb6cae91e
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
@@ -0,0 +1,6 @@
+ExitWindowsEx
+LockWorkStation
+SHEmptyRecycleBin
+S_OK
+E_UNEXPECTED
+SetSuspendState
\ No newline at end of file
From ca01b25a39b6c35d58b021fd153d796def9d7e05 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 13:29:21 +0800
Subject: [PATCH 0071/1335] Replace DllImport & flags with CSWin32
---
.../Flow.Launcher.Plugin.ProcessKiller.csproj | 7 +++
.../NativeMethods.txt | 2 +
.../ProcessHelper.cs | 52 ++++++++-----------
3 files changed, 31 insertions(+), 30 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj
index 876bac1e754..4e216b7b26a 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj
@@ -50,6 +50,13 @@
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
new file mode 100644
index 00000000000..7fa794755e1
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
@@ -0,0 +1,2 @@
+QueryFullProcessImageName
+OpenProcess
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index 0acc39fbb1c..d8e5f4fb7a9 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -1,11 +1,13 @@
-using Flow.Launcher.Infrastructure;
+using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
+using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.Threading;
namespace Flow.Launcher.Plugin.ProcessKiller
{
@@ -84,43 +86,33 @@ public void TryKill(Process p)
}
}
- public string TryGetProcessFilename(Process p)
+ public unsafe string TryGetProcessFilename(Process p)
{
try
{
- int capacity = 2000;
- StringBuilder builder = new StringBuilder(capacity);
- IntPtr ptr = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, p.Id);
- if (!QueryFullProcessImageName(ptr, 0, builder, ref capacity))
+ var handle = PInvoke.OpenProcess(PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_LIMITED_INFORMATION, false, (uint)p.Id);
+ if (handle.Value == IntPtr.Zero)
{
- return String.Empty;
+ return string.Empty;
}
- return builder.ToString();
+ using var safeHandle = new SafeProcessHandle(handle.Value, true);
+ uint capacity = 2000;
+ char[] buffer = new char[capacity];
+ fixed (char* pBuffer = buffer)
+ {
+ if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, (PWSTR)pBuffer, ref capacity))
+ {
+ return string.Empty;
+ }
+ }
+
+ return new string(buffer, 0, (int)capacity);
}
catch
{
- return "";
+ return string.Empty;
}
}
-
- [Flags]
- private enum ProcessAccessFlags : uint
- {
- QueryLimitedInformation = 0x00001000
- }
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern bool QueryFullProcessImageName(
- [In] IntPtr hProcess,
- [In] int dwFlags,
- [Out] StringBuilder lpExeName,
- ref int lpdwSize);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr OpenProcess(
- ProcessAccessFlags processAccess,
- bool bInheritHandle,
- int processId);
}
}
From 313f86b6485e6f32f1d23e58fcd09692ae322e8c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 15:09:06 +0800
Subject: [PATCH 0072/1335] Replace DllImport & flags with CSWin32
---
.../Flow.Launcher.Plugin.Program.csproj | 8 ++
.../NativeMethods.txt | 10 ++
.../Programs/ShellLinkHelper.cs | 130 +++++-------------
.../Programs/ShellLocalization.cs | 67 +++++----
4 files changed, 82 insertions(+), 133 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
index c0ad63cfeb4..99c1a12e9b3 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj
@@ -52,6 +52,10 @@
PreserveNewest
+
+
+
+
@@ -61,6 +65,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt
new file mode 100644
index 00000000000..ecd547dffcd
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt
@@ -0,0 +1,10 @@
+SHGetLocalizedName
+LoadString
+LoadLibraryEx
+FreeLibrary
+ExpandEnvironmentStrings
+S_OK
+SLGP_FLAGS
+WIN32_FIND_DATAW
+SLR_FLAGS
+IShellLinkW
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index 78c66d60485..fae9c84c985 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -1,97 +1,17 @@
using System;
-using System.Text;
using System.Runtime.InteropServices;
-using Accessibility;
using System.Runtime.InteropServices.ComTypes;
using Flow.Launcher.Plugin.Program.Logger;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.Storage.FileSystem;
namespace Flow.Launcher.Plugin.Program.Programs
{
class ShellLinkHelper
{
- [Flags()]
- public enum SLGP_FLAGS
- {
- SLGP_SHORTPATH = 0x1,
- SLGP_UNCPRIORITY = 0x2,
- SLGP_RAWPATH = 0x4
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- public struct WIN32_FIND_DATAW
- {
- public uint dwFileAttributes;
- public long ftCreationTime;
- public long ftLastAccessTime;
- public long ftLastWriteTime;
- public uint nFileSizeHigh;
- public uint nFileSizeLow;
- public uint dwReserved0;
- public uint dwReserved1;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
- public string cFileName;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
- public string cAlternateFileName;
- }
-
- [Flags()]
- public enum SLR_FLAGS
- {
- SLR_NO_UI = 0x1,
- SLR_ANY_MATCH = 0x2,
- SLR_UPDATE = 0x4,
- SLR_NOUPDATE = 0x8,
- SLR_NOSEARCH = 0x10,
- SLR_NOTRACK = 0x20,
- SLR_NOLINKINFO = 0x40,
- SLR_INVOKE_MSI = 0x80
- }
-
-
+
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
- /// The IShellLink interface allows Shell links to be created, modified, and resolved
- [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
- interface IShellLinkW
- {
- /// Retrieves the path and file name of a Shell link object
- void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
- /// Retrieves the list of item identifiers for a Shell link object
- void GetIDList(out IntPtr ppidl);
- /// Sets the pointer to an item identifier list (PIDL) for a Shell link object.
- void SetIDList(IntPtr pidl);
- /// Retrieves the description string for a Shell link object
- void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
- /// Sets the description for a Shell link object. The description can be any application-defined string
- void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
- /// Retrieves the name of the working directory for a Shell link object
- void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
- /// Sets the name of the working directory for a Shell link object
- void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
- /// Retrieves the command-line arguments associated with a Shell link object
- void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
- /// Sets the command-line arguments for a Shell link object
- void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
- /// Retrieves the hot key for a Shell link object
- void GetHotkey(out short pwHotkey);
- /// Sets a hot key for a Shell link object
- void SetHotkey(short wHotkey);
- /// Retrieves the show command for a Shell link object
- void GetShowCmd(out int piShowCmd);
- /// Sets the show command for a Shell link object. The show command sets the initial show state of the window.
- void SetShowCmd(int iShowCmd);
- /// Retrieves the location (path and index) of the icon for a Shell link object
- void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
- int cchIconPath, out int piIcon);
- /// Sets the location (path and index) of the icon for a Shell link object
- void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
- /// Sets the relative path to the Shell link object
- void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
- /// Attempts to find the target of a Shell link, even if it has been moved or renamed
- void Resolve(ref Accessibility._RemotableHandle hwnd, SLR_FLAGS fFlags);
- /// Sets the path and file name of a Shell link object
- void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
- }
-
[ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
public class ShellLink
{
@@ -102,29 +22,40 @@ public class ShellLink
public string arguments = string.Empty;
// Retrieve the target path using Shell Link
- public string retrieveTargetPath(string path)
+ public unsafe string retrieveTargetPath(string path)
{
var link = new ShellLink();
const int STGM_READ = 0;
((IPersistFile)link).Load(path, STGM_READ);
- var hwnd = new _RemotableHandle();
- ((IShellLinkW)link).Resolve(ref hwnd, 0);
+ var hwnd = new HWND(IntPtr.Zero);
+ ((IShellLinkW)link).Resolve(hwnd, 0);
const int MAX_PATH = 260;
- StringBuilder buffer = new StringBuilder(MAX_PATH);
+ char[] buffer = new char[MAX_PATH];
var data = new WIN32_FIND_DATAW();
- ((IShellLinkW)link).GetPath(buffer, buffer.Capacity, ref data, SLGP_FLAGS.SLGP_SHORTPATH);
- var target = buffer.ToString();
+ var target = string.Empty;
+ fixed (char* bufferChar = buffer)
+ {
+ ((IShellLinkW)link).GetPath((PWSTR)bufferChar, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = MAX_PATH;
+ target = new string(buffer, 0, validLength);
+ }
// To set the app description
- if (!String.IsNullOrEmpty(target))
+ if (!string.IsNullOrEmpty(target))
{
try
{
- buffer = new StringBuilder(MAX_PATH);
- ((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
- description = buffer.ToString();
+ char[] buffer1 = new char[MAX_PATH];
+ fixed (char* buffer1Char = buffer1)
+ {
+ ((IShellLinkW)link).GetDescription((PWSTR)buffer1Char, MAX_PATH);
+ int validLength = Array.IndexOf(buffer1, '\0');
+ if (validLength < 0) validLength = MAX_PATH;
+ description = new string(buffer1, 0, validLength);
+ }
}
catch (COMException e)
{
@@ -134,9 +65,14 @@ public string retrieveTargetPath(string path)
e);
}
- buffer.Clear();
- ((IShellLinkW)link).GetArguments(buffer, MAX_PATH);
- arguments = buffer.ToString();
+ char[] buffer2 = new char[MAX_PATH];
+ fixed (char* buffer2Char = buffer2)
+ {
+ ((IShellLinkW)link).GetArguments((PWSTR)buffer2Char, MAX_PATH);
+ int validLength = Array.IndexOf(buffer2, '\0');
+ if (validLength < 0) validLength = MAX_PATH;
+ arguments = new string(buffer2, 0, validLength);
+ }
}
// To release unmanaged memory
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
index 4f344d89ecc..e36618b0de5 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
@@ -1,8 +1,8 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.LibraryLoader;
namespace Flow.Launcher.Plugin.Program.Programs
{
@@ -13,51 +13,46 @@ namespace Flow.Launcher.Plugin.Program.Programs
///
public static class ShellLocalization
{
- internal const uint DONTRESOLVEDLLREFERENCES = 0x00000001;
- internal const uint LOADLIBRARYASDATAFILE = 0x00000002;
-
- [DllImport("shell32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
- internal static extern int SHGetLocalizedName(string pszPath, StringBuilder pszResModule, ref int cch, out int pidsRes);
-
- [DllImport("user32.dll", EntryPoint = "LoadStringW", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
- internal static extern int LoadString(IntPtr hModule, int resourceID, StringBuilder resourceValue, int len);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "LoadLibraryExW")]
- internal static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
-
- [DllImport("kernel32.dll", ExactSpelling = true)]
- internal static extern int FreeLibrary(IntPtr hModule);
-
- [DllImport("kernel32.dll", EntryPoint = "ExpandEnvironmentStringsW", CharSet = CharSet.Unicode, ExactSpelling = true)]
- internal static extern uint ExpandEnvironmentStrings(string lpSrc, StringBuilder lpDst, int nSize);
-
///
/// Returns the localized name of a shell item.
///
/// Path to the shell item (e. g. shortcut 'File Explorer.lnk').
/// The localized name as string or .
- public static string GetLocalizedName(string path)
+ public static unsafe string GetLocalizedName(string path)
{
- StringBuilder resourcePath = new StringBuilder(1024);
- StringBuilder localizedName = new StringBuilder(1024);
- int len, id;
- len = resourcePath.Capacity;
+ int capacity = 1024;
+ char[] resourcePathBuffer = new char[capacity];
// If there is no resource to localize a file name the method returns a non zero value.
- if (SHGetLocalizedName(path, resourcePath, ref len, out id) == 0)
+ fixed (char* resourcePath = resourcePathBuffer)
{
- _ = ExpandEnvironmentStrings(resourcePath.ToString(), resourcePath, resourcePath.Capacity);
- IntPtr hMod = LoadLibraryEx(resourcePath.ToString(), IntPtr.Zero, DONTRESOLVEDLLREFERENCES | LOADLIBRARYASDATAFILE);
- if (hMod != IntPtr.Zero)
+ var result = PInvoke.SHGetLocalizedName(path, (PWSTR)resourcePath, (uint)capacity, out var id);
+ if (result == HRESULT.S_OK)
{
- if (LoadString(hMod, id, localizedName, localizedName.Capacity) != 0)
+ int validLength = Array.IndexOf(resourcePathBuffer, '\0');
+ if (validLength < 0) validLength = capacity;
+ var resourcePathStr = new string(resourcePathBuffer, 0, validLength);
+ _ = PInvoke.ExpandEnvironmentStrings(resourcePathStr, resourcePath, (uint)capacity);
+ var handle = PInvoke.LoadLibraryEx(resourcePathStr,
+ LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
+ IntPtr safeHandle = handle.DangerousGetHandle();
+ if (safeHandle != IntPtr.Zero)
{
- string lString = localizedName.ToString();
- _ = FreeLibrary(hMod);
- return lString;
- }
+ char[] localizedNameBuffer = new char[capacity];
+ fixed (char* localizedName = localizedNameBuffer)
+ {
+ if (PInvoke.LoadString(handle, (uint)id, (PWSTR)localizedName, capacity) != 0)
+ {
+ validLength = Array.IndexOf(localizedNameBuffer, '\0');
+ if (validLength < 0) validLength = capacity;
+ var lString = new string(localizedNameBuffer, 0, validLength);
+ PInvoke.FreeLibrary(new(safeHandle));
+ return lString;
+ }
+ }
- _ = FreeLibrary(hMod);
+ PInvoke.FreeLibrary(new(safeHandle));
+ }
}
}
From ccfc39e54a35fb552cc563f1fa8660e99ffe1037 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 15:12:35 +0800
Subject: [PATCH 0073/1335] Fix string length issue
---
Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index d8e5f4fb7a9..6df12fae98b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -105,9 +105,11 @@ public unsafe string TryGetProcessFilename(Process p)
{
return string.Empty;
}
- }
- return new string(buffer, 0, (int)capacity);
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = (int)capacity;
+ return new string(buffer, 0, validLength);
+ }
}
catch
{
From 79f8f053d9288282c56579f41f284e96c19f2de5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 15:24:19 +0800
Subject: [PATCH 0074/1335] Replace DllImport with CSWin32
---
.../Flow.Launcher.Plugin.csproj | 10 +++++-
Flow.Launcher.Plugin/NativeMethods.txt | 3 ++
.../SharedCommands/ShellCommand.cs | 31 ++++++++++++-------
3 files changed, 32 insertions(+), 12 deletions(-)
create mode 100644 Flow.Launcher.Plugin/NativeMethods.txt
diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
index 35b9af1c9db..2feb21b12aa 100644
--- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
+++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
@@ -57,7 +57,11 @@
-
+
+
+
+
+
@@ -68,6 +72,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flow.Launcher.Plugin/NativeMethods.txt b/Flow.Launcher.Plugin/NativeMethods.txt
new file mode 100644
index 00000000000..e3e2b705eb0
--- /dev/null
+++ b/Flow.Launcher.Plugin/NativeMethods.txt
@@ -0,0 +1,3 @@
+EnumThreadWindows
+GetWindowText
+GetWindowTextLength
\ No newline at end of file
diff --git a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
index 49f78b458d7..191a7630958 100644
--- a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
@@ -2,18 +2,15 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Threading;
+using Windows.Win32;
+using Windows.Win32.Foundation;
namespace Flow.Launcher.Plugin.SharedCommands
{
public static class ShellCommand
{
public delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
- [DllImport("user32.dll")] static extern bool EnumThreadWindows(uint threadId, EnumThreadDelegate lpfn, IntPtr lParam);
- [DllImport("user32.dll")] static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
- [DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hwnd);
private static bool containsSecurityWindow;
@@ -42,21 +39,33 @@ private static void CheckSecurityWindow()
{
ProcessThreadCollection ptc = Process.GetCurrentProcess().Threads;
for (int i = 0; i < ptc.Count; i++)
- EnumThreadWindows((uint)ptc[i].Id, CheckSecurityThread, IntPtr.Zero);
+ PInvoke.EnumThreadWindows((uint)ptc[i].Id, CheckSecurityThread, IntPtr.Zero);
}
- private static bool CheckSecurityThread(IntPtr hwnd, IntPtr lParam)
+ private static BOOL CheckSecurityThread(HWND hwnd, LPARAM lParam)
{
if (GetWindowTitle(hwnd) == "Windows Security")
containsSecurityWindow = true;
return true;
}
- private static string GetWindowTitle(IntPtr hwnd)
+ private static unsafe string GetWindowTitle(HWND hwnd)
{
- StringBuilder sb = new StringBuilder(GetWindowTextLength(hwnd) + 1);
- GetWindowText(hwnd, sb, sb.Capacity);
- return sb.ToString();
+ var capacity = PInvoke.GetWindowTextLength(hwnd) + 1;
+ char[] buffer = new char[capacity];
+ fixed (char* pBuffer = buffer)
+ {
+ // If the window has no title bar or text, if the title bar is empty,
+ // or if the window or control handle is invalid, the return value is zero.
+ if (PInvoke.GetWindowText(hwnd, (PWSTR)pBuffer, capacity) == 0)
+ {
+ return string.Empty;
+ }
+
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = capacity;
+ return new string(buffer, 0, validLength);
+ }
}
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "", bool createNoWindow = false)
From 22170ee43a9fc9b01838cef65f0f45594473d952 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 20:44:28 +0800
Subject: [PATCH 0075/1335] Replace DllImport & flags with CSWin32
---
.../FileExplorerHelper.cs | 10 +-
.../Flow.Launcher.Infrastructure.csproj | 8 +
.../Hotkey/GlobalHotkey.cs | 58 +++----
.../Hotkey/InterceptKeys.cs | 38 -----
.../Hotkey/KeyEvent.cs | 12 +-
.../Image/ThumbnailReader.cs | 150 ++++++------------
.../NativeMethods.txt | 20 +++
7 files changed, 114 insertions(+), 182 deletions(-)
delete mode 100644 Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
create mode 100644 Flow.Launcher.Infrastructure/NativeMethods.txt
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index 76695a4e31e..b738b9c88f6 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
+using Windows.Win32;
namespace Flow.Launcher.Infrastructure
{
@@ -54,10 +54,6 @@ private static dynamic GetActiveExplorer()
return explorerWindows.Zip(zOrders).MinBy(x => x.Second).First;
}
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
-
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
///
@@ -70,9 +66,9 @@ private static IEnumerable GetZOrder(List hWnds)
var index = 0;
var numRemaining = hWnds.Count;
- EnumWindows((wnd, _) =>
+ PInvoke.EnumWindows((wnd, _) =>
{
- var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.ToInt32());
+ var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.Value);
if (searchIndex != -1)
{
z[searchIndex] = index;
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index ec35ef9d679..1475252caee 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -35,6 +35,10 @@
false
+
+
+
+
@@ -56,6 +60,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
index f847ab18906..75af843b973 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
@@ -1,6 +1,11 @@
-using System;
+using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using Flow.Launcher.Plugin;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Input.KeyboardAndMouse;
+using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Infrastructure.Hotkey
{
@@ -10,44 +15,41 @@ namespace Flow.Launcher.Infrastructure.Hotkey
///
public unsafe class GlobalHotkey : IDisposable
{
- private static readonly IntPtr hookId;
-
-
-
- public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
- internal static Func hookedKeyboardCallback;
+ private static readonly UnhookWindowsHookExSafeHandle hookId;
- //Modifier key constants
- private const int VK_SHIFT = 0x10;
- private const int VK_CONTROL = 0x11;
- private const int VK_ALT = 0x12;
- private const int VK_WIN = 91;
+ public delegate bool KeyboardCallback(int keyEvent, int vkCode, SpecialKeyState state);
+ internal static Func hookedKeyboardCallback;
static GlobalHotkey()
{
// Set the hook
- hookId = InterceptKeys.SetHook(& LowLevelKeyboardProc);
+ using Process curProcess = Process.GetCurrentProcess();
+ using ProcessModule curModule = curProcess.MainModule;
+ hookId = PInvoke.SetWindowsHookEx(
+ WINDOWS_HOOK_ID.WH_KEYBOARD_LL,
+ LowLevelKeyboardProc,
+ PInvoke.GetModuleHandle(curModule.ModuleName), 0);
}
public static SpecialKeyState CheckModifiers()
{
SpecialKeyState state = new SpecialKeyState();
- if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0)
+ if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_SHIFT) & 0x8000) != 0)
{
//SHIFT is pressed
state.ShiftPressed = true;
}
- if ((InterceptKeys.GetKeyState(VK_CONTROL) & 0x8000) != 0)
+ if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_CONTROL) & 0x8000) != 0)
{
//CONTROL is pressed
state.CtrlPressed = true;
}
- if ((InterceptKeys.GetKeyState(VK_ALT) & 0x8000) != 0)
+ if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_MENU) & 0x8000) != 0)
{
//ALT is pressed
state.AltPressed = true;
}
- if ((InterceptKeys.GetKeyState(VK_WIN) & 0x8000) != 0)
+ if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_LWIN) & 0x8000) != 0)
{
//WIN is pressed
state.WinPressed = true;
@@ -56,33 +58,33 @@ public static SpecialKeyState CheckModifiers()
return state;
}
- [UnmanagedCallersOnly]
- private static IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
+ private static LRESULT LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
bool continues = true;
if (nCode >= 0)
{
- if (wParam.ToUInt32() == (int)KeyEvent.WM_KEYDOWN ||
- wParam.ToUInt32() == (int)KeyEvent.WM_KEYUP ||
- wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYDOWN ||
- wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYUP)
+ var wParamValue = (int)wParam.Value;
+ if (wParamValue == (int)KeyEvent.WM_KEYDOWN ||
+ wParamValue == (int)KeyEvent.WM_KEYUP ||
+ wParamValue == (int)KeyEvent.WM_SYSKEYDOWN ||
+ wParamValue == (int)KeyEvent.WM_SYSKEYUP)
{
if (hookedKeyboardCallback != null)
- continues = hookedKeyboardCallback((KeyEvent)wParam.ToUInt32(), Marshal.ReadInt32(lParam), CheckModifiers());
+ continues = hookedKeyboardCallback((KeyEvent)wParamValue, Marshal.ReadInt32(lParam), CheckModifiers());
}
}
if (continues)
{
- return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
+ return PInvoke.CallNextHookEx(hookId, nCode, wParam, lParam);
}
- return (IntPtr)(-1);
+ return new LRESULT(-1);
}
public void Dispose()
{
- InterceptKeys.UnhookWindowsHookEx(hookId);
+ PInvoke.UnhookWindowsHookEx(new HHOOK(hookId.DangerousGetHandle()));
}
~GlobalHotkey()
@@ -90,4 +92,4 @@ public void Dispose()
Dispose();
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs b/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
deleted file mode 100644
index d33bac34cea..00000000000
--- a/Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Flow.Launcher.Infrastructure.Hotkey
-{
- internal static unsafe class InterceptKeys
- {
- public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
-
- private const int WH_KEYBOARD_LL = 13;
-
- public static IntPtr SetHook(delegate* unmanaged proc)
- {
- using (Process curProcess = Process.GetCurrentProcess())
- using (ProcessModule curModule = curProcess.MainModule)
- {
- return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
- }
- }
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr SetWindowsHookEx(int idHook, delegate* unmanaged lpfn, IntPtr hMod, uint dwThreadId);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool UnhookWindowsHookEx(IntPtr hhk);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, UIntPtr wParam, IntPtr lParam);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr GetModuleHandle(string lpModuleName);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
- public static extern short GetKeyState(int keyCode);
- }
-}
\ No newline at end of file
diff --git a/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs b/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs
index 15e3068830f..95bb258377b 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs
@@ -1,3 +1,5 @@
+using Windows.Win32;
+
namespace Flow.Launcher.Infrastructure.Hotkey
{
public enum KeyEvent
@@ -5,21 +7,21 @@ public enum KeyEvent
///
/// Key down
///
- WM_KEYDOWN = 256,
+ WM_KEYDOWN = (int)PInvoke.WM_KEYDOWN,
///
/// Key up
///
- WM_KEYUP = 257,
+ WM_KEYUP = (int)PInvoke.WM_KEYUP,
///
/// System key up
///
- WM_SYSKEYUP = 261,
+ WM_SYSKEYUP = (int)PInvoke.WM_SYSKEYUP,
///
/// System key down
///
- WM_SYSKEYDOWN = 260
+ WM_SYSKEYDOWN = (int)PInvoke.WM_SYSKEYDOWN
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index 247238bb68f..49d6da8c249 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -1,12 +1,19 @@
using System;
using System.Runtime.InteropServices;
using System.IO;
+using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
-using System.Windows;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.Graphics.Gdi;
namespace Flow.Launcher.Infrastructure.Image
{
+ ///
+ /// Subclass of
+ ///
[Flags]
public enum ThumbnailOptions
{
@@ -22,91 +29,13 @@ public class WindowsThumbnailProvider
{
// Based on https://stackoverflow.com/questions/21751747/extract-thumbnail-for-any-file-in-windows
- private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern int SHCreateItemFromParsingName(
- [MarshalAs(UnmanagedType.LPWStr)] string path,
- IntPtr pbc,
- ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
-
- [DllImport("gdi32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool DeleteObject(IntPtr hObject);
-
- [ComImport]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
- internal interface IShellItem
- {
- void BindToHandler(IntPtr pbc,
- [MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
- [MarshalAs(UnmanagedType.LPStruct)]Guid riid,
- out IntPtr ppv);
-
- void GetParent(out IShellItem ppsi);
- void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
- void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
- void Compare(IShellItem psi, uint hint, out int piOrder);
- };
-
- internal enum SIGDN : uint
- {
- NORMALDISPLAY = 0,
- PARENTRELATIVEPARSING = 0x80018001,
- PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
- DESKTOPABSOLUTEPARSING = 0x80028000,
- PARENTRELATIVEEDITING = 0x80031001,
- DESKTOPABSOLUTEEDITING = 0x8004c000,
- FILESYSPATH = 0x80058000,
- URL = 0x80068000
- }
-
- internal enum HResult
- {
- Ok = 0x0000,
- False = 0x0001,
- InvalidArguments = unchecked((int)0x80070057),
- OutOfMemory = unchecked((int)0x8007000E),
- NoInterface = unchecked((int)0x80004002),
- Fail = unchecked((int)0x80004005),
- ExtractionFailed = unchecked((int)0x8004B200),
- ElementNotFound = unchecked((int)0x80070490),
- TypeElementNotFound = unchecked((int)0x8002802B),
- NoObject = unchecked((int)0x800401E5),
- Win32ErrorCanceled = 1223,
- Canceled = unchecked((int)0x800704C7),
- ResourceInUse = unchecked((int)0x800700AA),
- AccessDenied = unchecked((int)0x80030005)
- }
-
- [ComImportAttribute()]
- [GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
- [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- internal interface IShellItemImageFactory
- {
- [PreserveSig]
- HResult GetImage(
- [In, MarshalAs(UnmanagedType.Struct)] NativeSize size,
- [In] ThumbnailOptions flags,
- [Out] out IntPtr phbm);
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct NativeSize
- {
- private int width;
- private int height;
-
- public int Width { set { width = value; } }
- public int Height { set { height = value; } }
- };
+ private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
+ private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
- IntPtr hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
+ HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
try
{
@@ -115,39 +44,52 @@ public static BitmapSource GetThumbnail(string fileName, int width, int height,
finally
{
// delete HBitmap to avoid memory leaks
- DeleteObject(hBitmap);
+ PInvoke.DeleteObject(hBitmap);
}
}
-
- private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
+
+ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
{
- IShellItem nativeShellItem;
- Guid shellItem2Guid = new Guid(IShellItem2Guid);
- int retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem);
+ var retCode = PInvoke.SHCreateItemFromParsingName(
+ fileName,
+ null,
+ GUID_IShellItem,
+ out var nativeShellItem);
- if (retCode != 0)
+ if (retCode != HRESULT.S_OK)
throw Marshal.GetExceptionForHR(retCode);
- NativeSize nativeSize = new NativeSize
+ if (nativeShellItem is not IShellItemImageFactory imageFactory)
{
- Width = width,
- Height = height
- };
+ Marshal.ReleaseComObject(nativeShellItem);
+ throw new InvalidOperationException("Failed to get IShellItemImageFactory");
+ }
- IntPtr hBitmap;
- HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out hBitmap);
+ SIZE size = new SIZE
+ {
+ cx = width,
+ cy = height
+ };
- // if extracting image thumbnail and failed, extract shell icon
- if (options == ThumbnailOptions.ThumbnailOnly && hr == HResult.ExtractionFailed)
+ HBITMAP hBitmap = default;
+ try
{
- hr = ((IShellItemImageFactory) nativeShellItem).GetImage(nativeSize, ThumbnailOptions.IconOnly, out hBitmap);
+ try
+ {
+ imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
+ }
+ catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
+ {
+ // Fallback to IconOnly if ThumbnailOnly fails
+ imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
+ }
+ }
+ finally
+ {
+ Marshal.ReleaseComObject(nativeShellItem);
}
- Marshal.ReleaseComObject(nativeShellItem);
-
- if (hr == HResult.Ok) return hBitmap;
-
- throw new COMException($"Error while extracting thumbnail for {fileName}", Marshal.GetExceptionForHR((int)hr));
+ return hBitmap;
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
new file mode 100644
index 00000000000..a083f79aad8
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -0,0 +1,20 @@
+SHCreateItemFromParsingName
+DeleteObject
+IShellItem
+IShellItemImageFactory
+ExtractionFailed
+S_OK
+
+SetWindowsHookEx
+UnhookWindowsHookEx
+CallNextHookEx
+GetModuleHandle
+GetKeyState
+VIRTUAL_KEY
+
+WM_KEYDOWN
+WM_KEYUP
+WM_SYSKEYDOWN
+WM_SYSKEYUP
+
+EnumWindows
\ No newline at end of file
From ce8b42bc6edb3e5759c7700dd11c71dfb4bff1d4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 22:01:55 +0800
Subject: [PATCH 0076/1335] Replace DllImport & flags with CSWin32
---
Flow.Launcher/Flow.Launcher.csproj | 4 +
Flow.Launcher/Helper/DWMDropShadow.cs | 19 ++--
.../Helper/WallpaperPathRetrieval.cs | 17 ++--
Flow.Launcher/Helper/WindowsInteropHelper.cs | 89 +++++++------------
Flow.Launcher/MainWindow.xaml.cs | 9 +-
Flow.Launcher/NativeMethods.txt | 14 +++
6 files changed, 65 insertions(+), 87 deletions(-)
create mode 100644 Flow.Launcher/NativeMethods.txt
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index afc3fbbaa0f..7bd59e8c138 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -90,6 +90,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flow.Launcher/Helper/DWMDropShadow.cs b/Flow.Launcher/Helper/DWMDropShadow.cs
index e448acd4c9e..7cb719d074d 100644
--- a/Flow.Launcher/Helper/DWMDropShadow.cs
+++ b/Flow.Launcher/Helper/DWMDropShadow.cs
@@ -1,20 +1,15 @@
using System;
-using System.Drawing.Printing;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
+using Windows.Win32;
+using Windows.Win32.Graphics.Dwm;
+using Windows.Win32.UI.Controls;
namespace Flow.Launcher.Helper;
public class DwmDropShadow
{
- [DllImport("dwmapi.dll", PreserveSig = true)]
- private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
-
- [DllImport("dwmapi.dll")]
- private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
-
///
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven).
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect,
@@ -43,18 +38,18 @@ private static void window_SourceInitialized(object sender, EventArgs e) //fixed
///
/// Window to which the shadow will be applied
/// True if the method succeeded, false if not
- private static bool DropShadow(Window window)
+ private unsafe static bool DropShadow(Window window)
{
try
{
WindowInteropHelper helper = new WindowInteropHelper(window);
int val = 2;
- int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);
+ int ret1 = PInvoke.DwmSetWindowAttribute(new(helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
if (ret1 == 0)
{
- Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 };
- int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m);
+ var m = new MARGINS { cyBottomHeight = 0, cxLeftWidth = 0, cxRightWidth = 0, cyTopHeight = 0 };
+ int ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
return ret2 == 0;
}
else
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index e08e227cc33..8ab06e78d08 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -1,24 +1,21 @@
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
+using System.Linq;
using System.Text;
using System.Windows.Media;
using Microsoft.Win32;
+using Windows.Win32;
+using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
- [DllImport("user32.dll", CharSet = CharSet.Unicode)]
- private static extern Int32 SystemParametersInfo(UInt32 action,
- Int32 uParam, StringBuilder vParam, UInt32 winIni);
- private static readonly UInt32 SPI_GETDESKWALLPAPER = 0x73;
- private static int MAX_PATH = 260;
+
+ private static readonly int MAX_PATH = 260;
- public static string GetWallpaperPath()
+ public static unsafe string GetWallpaperPath()
{
var wallpaper = new StringBuilder(MAX_PATH);
- SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallpaper, 0);
+ PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH, &wallpaper, 0);
var str = wallpaper.ToString();
if (string.IsNullOrEmpty(str))
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index 89fbec967a8..ae48034e81e 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -1,75 +1,50 @@
using System;
using System.Drawing;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
namespace Flow.Launcher.Helper;
public class WindowsInteropHelper
{
- private const int GWL_STYLE = -16; //WPF's Message code for Title Bar's Style
- private const int WS_SYSMENU = 0x80000; //WPF's Message code for System Menu
- private static IntPtr _hwnd_shell;
- private static IntPtr _hwnd_desktop;
+ private static HWND _hwnd_shell;
+ private static HWND _hwnd_desktop;
//Accessors for shell and desktop handlers
//Will set the variables once and then will return them
- private static IntPtr HWND_SHELL
+ private static HWND HWND_SHELL
{
get
{
- return _hwnd_shell != IntPtr.Zero ? _hwnd_shell : _hwnd_shell = GetShellWindow();
+ return _hwnd_shell != HWND.Null ? _hwnd_shell : _hwnd_shell = PInvoke.GetShellWindow();
}
}
- private static IntPtr HWND_DESKTOP
+
+ private static HWND HWND_DESKTOP
{
get
{
- return _hwnd_desktop != IntPtr.Zero ? _hwnd_desktop : _hwnd_desktop = GetDesktopWindow();
+ return _hwnd_desktop != HWND.Null ? _hwnd_desktop : _hwnd_desktop = PInvoke.GetDesktopWindow();
}
}
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll")]
- internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetForegroundWindow();
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetDesktopWindow();
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetShellWindow();
-
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
-
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
-
- [DllImport("user32.DLL")]
- public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
-
-
const string WINDOW_CLASS_CONSOLE = "ConsoleWindowClass";
const string WINDOW_CLASS_WINTAB = "Flip3D";
const string WINDOW_CLASS_PROGMAN = "Progman";
const string WINDOW_CLASS_WORKERW = "WorkerW";
- public static bool IsWindowFullscreen()
+ public unsafe static bool IsWindowFullscreen()
{
//get current active window
- IntPtr hWnd = GetForegroundWindow();
+ var hWnd = PInvoke.GetForegroundWindow();
- if (hWnd.Equals(IntPtr.Zero))
+ if (hWnd.Equals(HWND.Null))
{
return false;
}
@@ -80,9 +55,16 @@ public static bool IsWindowFullscreen()
return false;
}
- StringBuilder sb = new StringBuilder(256);
- GetClassName(hWnd, sb, sb.Capacity);
- string windowClass = sb.ToString();
+ string windowClass;
+ int capacity = 256;
+ char[] buffer = new char[capacity];
+ fixed (char* pBuffer = buffer)
+ {
+ PInvoke.GetClassName(hWnd, pBuffer, capacity);
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = capacity;
+ windowClass = new string(buffer, 0, validLength);
+ }
//for Win+Tab (Flip3D)
if (windowClass == WINDOW_CLASS_WINTAB)
@@ -90,20 +72,19 @@ public static bool IsWindowFullscreen()
return false;
}
- RECT appBounds;
- GetWindowRect(hWnd, out appBounds);
+ PInvoke.GetWindowRect(hWnd, out var appBounds);
//for console (ConsoleWindowClass), we have to check for negative dimensions
if (windowClass == WINDOW_CLASS_CONSOLE)
{
- return appBounds.Top < 0 && appBounds.Bottom < 0;
+ return appBounds.top < 0 && appBounds.bottom < 0;
}
//for desktop (Progman or WorkerW, depends on the system), we have to check
if (windowClass is WINDOW_CLASS_PROGMAN or WINDOW_CLASS_WORKERW)
{
- IntPtr hWndDesktop = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
- hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", "FolderView");
+ var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
+ hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
if (!hWndDesktop.Equals(IntPtr.Zero))
{
return false;
@@ -111,7 +92,7 @@ public static bool IsWindowFullscreen()
}
Rectangle screenBounds = Screen.FromHandle(hWnd).Bounds;
- return (appBounds.Bottom - appBounds.Top) == screenBounds.Height && (appBounds.Right - appBounds.Left) == screenBounds.Width;
+ return (appBounds.bottom - appBounds.top) == screenBounds.Height && (appBounds.right - appBounds.left) == screenBounds.Width;
}
///
@@ -120,8 +101,8 @@ public static bool IsWindowFullscreen()
///
public static void DisableControlBox(Window win)
{
- var hwnd = new WindowInteropHelper(win).Handle;
- SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
+ var hwnd = new HWND(new WindowInteropHelper(win).Handle);
+ PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE) & ~(int)WINDOW_STYLE.WS_SYSMENU);
}
///
@@ -146,14 +127,4 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
}
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
-
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 0f8b8f6d70c..b4f1fb0317f 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -26,7 +26,7 @@
using DataObject = System.Windows.DataObject;
using System.Windows.Media;
using System.Windows.Interop;
-using System.Runtime.InteropServices;
+using Windows.Win32;
namespace Flow.Launcher
{
@@ -34,9 +34,6 @@ public partial class MainWindow
{
#region Private Fields
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern IntPtr SetForegroundWindow(IntPtr hwnd);
-
private readonly Storyboard _progressBarStoryboard = new Storyboard();
private bool isProgressBarStoryboardPaused;
private Settings _settings;
@@ -424,7 +421,7 @@ private void InitializeNotifyIcon()
// Get context menu handle and bring it to the foreground
if (PresentationSource.FromVisual(contextMenu) is HwndSource hwndSource)
{
- _ = SetForegroundWindow(hwndSource.Handle);
+ PInvoke.SetForegroundWindow(new(hwndSource.Handle));
}
contextMenu.Focus();
@@ -692,7 +689,7 @@ public Screen SelectedScreen()
screen = Screen.PrimaryScreen;
break;
case SearchWindowScreens.Focus:
- IntPtr foregroundWindowHandle = WindowsInteropHelper.GetForegroundWindow();
+ var foregroundWindowHandle = PInvoke.GetForegroundWindow().Value;
screen = Screen.FromHandle(foregroundWindowHandle);
break;
case SearchWindowScreens.Custom:
diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt
new file mode 100644
index 00000000000..bbf55502e5a
--- /dev/null
+++ b/Flow.Launcher/NativeMethods.txt
@@ -0,0 +1,14 @@
+DwmSetWindowAttribute
+DwmExtendFrameIntoClientArea
+SystemParametersInfo
+SetForegroundWindow
+
+GetWindowLong
+SetWindowLong
+GetForegroundWindow
+GetDesktopWindow
+GetShellWindow
+GetWindowRect
+GetClassName
+FindWindowEx
+WINDOW_STYLE
\ No newline at end of file
From dbe626d2384865b0a90af2939d8a2e75c4e223e1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Dec 2024 09:57:13 +0800
Subject: [PATCH 0077/1335] Fix key event return result issue
---
.../Hotkey/GlobalHotkey.cs | 33 ++++++++++---------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
index 75af843b973..04694ed167f 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
@@ -15,20 +15,23 @@ namespace Flow.Launcher.Infrastructure.Hotkey
///
public unsafe class GlobalHotkey : IDisposable
{
+ private static readonly HOOKPROC _procKeyboard = HookKeyboardCallback;
private static readonly UnhookWindowsHookExSafeHandle hookId;
- public delegate bool KeyboardCallback(int keyEvent, int vkCode, SpecialKeyState state);
+ public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
internal static Func hookedKeyboardCallback;
static GlobalHotkey()
{
// Set the hook
- using Process curProcess = Process.GetCurrentProcess();
- using ProcessModule curModule = curProcess.MainModule;
- hookId = PInvoke.SetWindowsHookEx(
- WINDOWS_HOOK_ID.WH_KEYBOARD_LL,
- LowLevelKeyboardProc,
- PInvoke.GetModuleHandle(curModule.ModuleName), 0);
+ hookId = SetHook(_procKeyboard, WINDOWS_HOOK_ID.WH_KEYBOARD_LL);
+ }
+
+ private static UnhookWindowsHookExSafeHandle SetHook(HOOKPROC proc, WINDOWS_HOOK_ID hookId)
+ {
+ using var curProcess = Process.GetCurrentProcess();
+ using var curModule = curProcess.MainModule;
+ return PInvoke.SetWindowsHookEx(hookId, proc, PInvoke.GetModuleHandle(curModule.ModuleName), 0);
}
public static SpecialKeyState CheckModifiers()
@@ -58,20 +61,19 @@ public static SpecialKeyState CheckModifiers()
return state;
}
- private static LRESULT LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
+ private static LRESULT HookKeyboardCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
bool continues = true;
if (nCode >= 0)
{
- var wParamValue = (int)wParam.Value;
- if (wParamValue == (int)KeyEvent.WM_KEYDOWN ||
- wParamValue == (int)KeyEvent.WM_KEYUP ||
- wParamValue == (int)KeyEvent.WM_SYSKEYDOWN ||
- wParamValue == (int)KeyEvent.WM_SYSKEYUP)
+ if (wParam.Value == (int)KeyEvent.WM_KEYDOWN ||
+ wParam.Value == (int)KeyEvent.WM_KEYUP ||
+ wParam.Value == (int)KeyEvent.WM_SYSKEYDOWN ||
+ wParam.Value == (int)KeyEvent.WM_SYSKEYUP)
{
if (hookedKeyboardCallback != null)
- continues = hookedKeyboardCallback((KeyEvent)wParamValue, Marshal.ReadInt32(lParam), CheckModifiers());
+ continues = hookedKeyboardCallback((KeyEvent)wParam.Value, Marshal.ReadInt32(lParam), CheckModifiers());
}
}
@@ -79,7 +81,8 @@ private static LRESULT LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
{
return PInvoke.CallNextHookEx(hookId, nCode, wParam, lParam);
}
- return new LRESULT(-1);
+
+ return new LRESULT(1);
}
public void Dispose()
From be72bb73aa8b1783c6ec9877f8067096e5a7ac84 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Dec 2024 09:57:49 +0800
Subject: [PATCH 0078/1335] Fix VIRTUAL_KEY.VK_RWIN check issue
---
Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
index 04694ed167f..2bc7db9bf65 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
@@ -52,7 +52,8 @@ public static SpecialKeyState CheckModifiers()
//ALT is pressed
state.AltPressed = true;
}
- if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_LWIN) & 0x8000) != 0)
+ if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_LWIN) & 0x8000) != 0 ||
+ (PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_RWIN) & 0x8000) != 0)
{
//WIN is pressed
state.WinPressed = true;
From 49fc0b8fd07d5856eb265981e6dbccaad834d2a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Dec 2024 10:04:03 +0800
Subject: [PATCH 0079/1335] Remove useless DllImport & flags
---
Flow.Launcher/Helper/SingleInstance.cs | 226 -------------------------
1 file changed, 226 deletions(-)
diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs
index 739fed378e0..e0e3075f636 100644
--- a/Flow.Launcher/Helper/SingleInstance.cs
+++ b/Flow.Launcher/Helper/SingleInstance.cs
@@ -1,11 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using System.Runtime.InteropServices;
using System.IO.Pipes;
-using System.Security;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@@ -14,172 +8,6 @@
// modified to allow single instace restart
namespace Flow.Launcher.Helper
{
- internal enum WM
- {
- NULL = 0x0000,
- CREATE = 0x0001,
- DESTROY = 0x0002,
- MOVE = 0x0003,
- SIZE = 0x0005,
- ACTIVATE = 0x0006,
- SETFOCUS = 0x0007,
- KILLFOCUS = 0x0008,
- ENABLE = 0x000A,
- SETREDRAW = 0x000B,
- SETTEXT = 0x000C,
- GETTEXT = 0x000D,
- GETTEXTLENGTH = 0x000E,
- PAINT = 0x000F,
- CLOSE = 0x0010,
- QUERYENDSESSION = 0x0011,
- QUIT = 0x0012,
- QUERYOPEN = 0x0013,
- ERASEBKGND = 0x0014,
- SYSCOLORCHANGE = 0x0015,
- SHOWWINDOW = 0x0018,
- ACTIVATEAPP = 0x001C,
- SETCURSOR = 0x0020,
- MOUSEACTIVATE = 0x0021,
- CHILDACTIVATE = 0x0022,
- QUEUESYNC = 0x0023,
- GETMINMAXINFO = 0x0024,
-
- WINDOWPOSCHANGING = 0x0046,
- WINDOWPOSCHANGED = 0x0047,
-
- CONTEXTMENU = 0x007B,
- STYLECHANGING = 0x007C,
- STYLECHANGED = 0x007D,
- DISPLAYCHANGE = 0x007E,
- GETICON = 0x007F,
- SETICON = 0x0080,
- NCCREATE = 0x0081,
- NCDESTROY = 0x0082,
- NCCALCSIZE = 0x0083,
- NCHITTEST = 0x0084,
- NCPAINT = 0x0085,
- NCACTIVATE = 0x0086,
- GETDLGCODE = 0x0087,
- SYNCPAINT = 0x0088,
- NCMOUSEMOVE = 0x00A0,
- NCLBUTTONDOWN = 0x00A1,
- NCLBUTTONUP = 0x00A2,
- NCLBUTTONDBLCLK = 0x00A3,
- NCRBUTTONDOWN = 0x00A4,
- NCRBUTTONUP = 0x00A5,
- NCRBUTTONDBLCLK = 0x00A6,
- NCMBUTTONDOWN = 0x00A7,
- NCMBUTTONUP = 0x00A8,
- NCMBUTTONDBLCLK = 0x00A9,
-
- SYSKEYDOWN = 0x0104,
- SYSKEYUP = 0x0105,
- SYSCHAR = 0x0106,
- SYSDEADCHAR = 0x0107,
- COMMAND = 0x0111,
- SYSCOMMAND = 0x0112,
-
- MOUSEMOVE = 0x0200,
- LBUTTONDOWN = 0x0201,
- LBUTTONUP = 0x0202,
- LBUTTONDBLCLK = 0x0203,
- RBUTTONDOWN = 0x0204,
- RBUTTONUP = 0x0205,
- RBUTTONDBLCLK = 0x0206,
- MBUTTONDOWN = 0x0207,
- MBUTTONUP = 0x0208,
- MBUTTONDBLCLK = 0x0209,
- MOUSEWHEEL = 0x020A,
- XBUTTONDOWN = 0x020B,
- XBUTTONUP = 0x020C,
- XBUTTONDBLCLK = 0x020D,
- MOUSEHWHEEL = 0x020E,
-
-
- CAPTURECHANGED = 0x0215,
-
- ENTERSIZEMOVE = 0x0231,
- EXITSIZEMOVE = 0x0232,
-
- IME_SETCONTEXT = 0x0281,
- IME_NOTIFY = 0x0282,
- IME_CONTROL = 0x0283,
- IME_COMPOSITIONFULL = 0x0284,
- IME_SELECT = 0x0285,
- IME_CHAR = 0x0286,
- IME_REQUEST = 0x0288,
- IME_KEYDOWN = 0x0290,
- IME_KEYUP = 0x0291,
-
- NCMOUSELEAVE = 0x02A2,
-
- DWMCOMPOSITIONCHANGED = 0x031E,
- DWMNCRENDERINGCHANGED = 0x031F,
- DWMCOLORIZATIONCOLORCHANGED = 0x0320,
- DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
-
- #region Windows 7
- DWMSENDICONICTHUMBNAIL = 0x0323,
- DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326,
- #endregion
-
- USER = 0x0400,
-
- // This is the hard-coded message value used by WinForms for Shell_NotifyIcon.
- // It's relatively safe to reuse.
- TRAYMOUSEMESSAGE = 0x800, //WM_USER + 1024
- APP = 0x8000
- }
-
- [SuppressUnmanagedCodeSecurity]
- internal static class NativeMethods
- {
- ///
- /// Delegate declaration that matches WndProc signatures.
- ///
- public delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled);
-
- [DllImport("shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode)]
- private static extern IntPtr _CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, out int numArgs);
-
-
- [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)]
- private static extern IntPtr _LocalFree(IntPtr hMem);
-
-
- public static string[] CommandLineToArgvW(string cmdLine)
- {
- IntPtr argv = IntPtr.Zero;
- try
- {
- int numArgs = 0;
-
- argv = _CommandLineToArgvW(cmdLine, out numArgs);
- if (argv == IntPtr.Zero)
- {
- throw new Win32Exception();
- }
- var result = new string[numArgs];
-
- for (int i = 0; i < numArgs; i++)
- {
- IntPtr currArg = Marshal.ReadIntPtr(argv, i * Marshal.SizeOf(typeof(IntPtr)));
- result[i] = Marshal.PtrToStringUni(currArg);
- }
-
- return result;
- }
- finally
- {
-
- IntPtr p = _LocalFree(argv);
- // Otherwise LocalFree failed.
- // Assert.AreEqual(IntPtr.Zero, p);
- }
- }
-
- }
-
public interface ISingleInstanceApp
{
void OnSecondAppStarted();
@@ -219,10 +47,6 @@ public static class SingleInstance
#endregion
- #region Public Properties
-
- #endregion
-
#region Public Methods
///
@@ -264,56 +88,6 @@ public static void Cleanup()
#region Private Methods
- ///
- /// Gets command line args - for ClickOnce deployed applications, command line args may not be passed directly, they have to be retrieved.
- ///
- /// List of command line arg strings.
- private static IList GetCommandLineArgs( string uniqueApplicationName )
- {
- string[] args = null;
-
- try
- {
- // The application was not clickonce deployed, get args from standard API's
- args = Environment.GetCommandLineArgs();
- }
- catch (NotSupportedException)
- {
-
- // The application was clickonce deployed
- // Clickonce deployed apps cannot recieve traditional commandline arguments
- // As a workaround commandline arguments can be written to a shared location before
- // the app is launched and the app can obtain its commandline arguments from the
- // shared location
- string appFolderPath = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), uniqueApplicationName);
-
- string cmdLinePath = Path.Combine(appFolderPath, "cmdline.txt");
- if (File.Exists(cmdLinePath))
- {
- try
- {
- using (TextReader reader = new StreamReader(cmdLinePath, Encoding.Unicode))
- {
- args = NativeMethods.CommandLineToArgvW(reader.ReadToEnd());
- }
-
- File.Delete(cmdLinePath);
- }
- catch (IOException)
- {
- }
- }
- }
-
- if (args == null)
- {
- args = new string[] { };
- }
-
- return new List(args);
- }
-
///
/// Creates a remote server pipe for communication.
/// Once receives signal from client, will activate first instance.
From 8a05c606e4ce63ecdde6aacf8b3d6ae7b778f91d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Dec 2024 11:08:57 +0800
Subject: [PATCH 0080/1335] Fix possible double release
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index 49d6da8c249..2fb8cf3632d 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -62,6 +62,7 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
if (nativeShellItem is not IShellItemImageFactory imageFactory)
{
Marshal.ReleaseComObject(nativeShellItem);
+ nativeShellItem = null;
throw new InvalidOperationException("Failed to get IShellItemImageFactory");
}
@@ -86,7 +87,10 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
}
finally
{
- Marshal.ReleaseComObject(nativeShellItem);
+ if (nativeShellItem != null)
+ {
+ Marshal.ReleaseComObject(nativeShellItem);
+ }
}
return hBitmap;
From fe4fcf6cc0a75d94fe274d6c055fdf70ce336aeb Mon Sep 17 00:00:00 2001
From: cibere <71997063+cibere@users.noreply.github.com>
Date: Wed, 11 Dec 2024 10:53:25 -0800
Subject: [PATCH 0081/1335] remove `AutoCompleteText` from the Open Recycle Bin
result in sys plugin
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 7d240e89a34..2d5847cded5 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -298,7 +298,6 @@ private List Commands()
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
CopyText = recycleBinFolder,
- AutoCompleteText = recycleBinFolder,
Action = c =>
{
{
From a088f91541ea18c637c368706443793739acdc46 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 14 Dec 2024 11:17:29 +0800
Subject: [PATCH 0082/1335] Add comments for string truncation
---
Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs | 1 +
Flow.Launcher/Helper/WindowsInteropHelper.cs | 2 ++
Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs | 1 +
.../Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs | 2 ++
4 files changed, 6 insertions(+)
diff --git a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
index 191a7630958..9639f1b1ad4 100644
--- a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
@@ -62,6 +62,7 @@ private static unsafe string GetWindowTitle(HWND hwnd)
return string.Empty;
}
+ // Truncate the buffer to the actual length of the string
int validLength = Array.IndexOf(buffer, '\0');
if (validLength < 0) validLength = capacity;
return new string(buffer, 0, validLength);
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index ae48034e81e..6656b0c5b26 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -61,6 +61,8 @@ public unsafe static bool IsWindowFullscreen()
fixed (char* pBuffer = buffer)
{
PInvoke.GetClassName(hWnd, pBuffer, capacity);
+
+ // Truncate the buffer to the actual length of the string
int validLength = Array.IndexOf(buffer, '\0');
if (validLength < 0) validLength = capacity;
windowClass = new string(buffer, 0, validLength);
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index 6df12fae98b..abc254d8694 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -106,6 +106,7 @@ public unsafe string TryGetProcessFilename(Process p)
return string.Empty;
}
+ // Truncate the buffer to the actual length of the string
int validLength = Array.IndexOf(buffer, '\0');
if (validLength < 0) validLength = (int)capacity;
return new string(buffer, 0, validLength);
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index fae9c84c985..05cbfd2b12e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -38,6 +38,8 @@ public unsafe string retrieveTargetPath(string path)
fixed (char* bufferChar = buffer)
{
((IShellLinkW)link).GetPath((PWSTR)bufferChar, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
+
+ // Truncate the buffer to the actual length of the string
int validLength = Array.IndexOf(buffer, '\0');
if (validLength < 0) validLength = MAX_PATH;
target = new string(buffer, 0, validLength);
From a899ff83e5a336505cdf0b64d2ef48f2d1fd417a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 14 Dec 2024 11:46:09 +0800
Subject: [PATCH 0083/1335] Improve code quality
---
.../Programs/ShellLinkHelper.cs | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index 05cbfd2b12e..ad1f3ab564d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -38,11 +38,7 @@ public unsafe string retrieveTargetPath(string path)
fixed (char* bufferChar = buffer)
{
((IShellLinkW)link).GetPath((PWSTR)bufferChar, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
-
- // Truncate the buffer to the actual length of the string
- int validLength = Array.IndexOf(buffer, '\0');
- if (validLength < 0) validLength = MAX_PATH;
- target = new string(buffer, 0, validLength);
+ target = GetStringFromBuffer(buffer, MAX_PATH);
}
// To set the app description
@@ -54,9 +50,7 @@ public unsafe string retrieveTargetPath(string path)
fixed (char* buffer1Char = buffer1)
{
((IShellLinkW)link).GetDescription((PWSTR)buffer1Char, MAX_PATH);
- int validLength = Array.IndexOf(buffer1, '\0');
- if (validLength < 0) validLength = MAX_PATH;
- description = new string(buffer1, 0, validLength);
+ description = GetStringFromBuffer(buffer1, MAX_PATH);
}
}
catch (COMException e)
@@ -71,9 +65,7 @@ public unsafe string retrieveTargetPath(string path)
fixed (char* buffer2Char = buffer2)
{
((IShellLinkW)link).GetArguments((PWSTR)buffer2Char, MAX_PATH);
- int validLength = Array.IndexOf(buffer2, '\0');
- if (validLength < 0) validLength = MAX_PATH;
- arguments = new string(buffer2, 0, validLength);
+ arguments = GetStringFromBuffer(buffer2, MAX_PATH);
}
}
@@ -82,5 +74,13 @@ public unsafe string retrieveTargetPath(string path)
return target;
}
+
+ private static unsafe string GetStringFromBuffer(char[] buffer, int maxLength)
+ {
+ // Truncate the buffer to the actual length of the string
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = maxLength;
+ return new string(buffer, 0, validLength);
+ }
}
}
From b96c7b12d51ec89b3355c8bc7a241f8173935d10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 14 Dec 2024 11:51:13 +0800
Subject: [PATCH 0084/1335] Remove useless PInvoke method import
---
Flow.Launcher.Infrastructure/NativeMethods.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index a083f79aad8..f117534a1ff 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -2,7 +2,6 @@
DeleteObject
IShellItem
IShellItemImageFactory
-ExtractionFailed
S_OK
SetWindowsHookEx
From 26b33b9e13ef714c82f43e2faf0fbe1ca4333ed8 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Sat, 14 Dec 2024 10:22:09 -0600
Subject: [PATCH 0085/1335] add Hebrew in available languages
---
Flow.Launcher.Core/Resource/AvailableLanguages.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Resource/AvailableLanguages.cs b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
index 46c1ecb54f1..c385cd8e871 100644
--- a/Flow.Launcher.Core/Resource/AvailableLanguages.cs
+++ b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
@@ -28,6 +28,7 @@ internal static class AvailableLanguages
public static Language Czech = new Language("cs", "čeština");
public static Language Arabic = new Language("ar", "اللغة العربية");
public static Language Vietnamese = new Language("vi-vn", "Tiếng Việt");
+ public static Language Hebrew = new Language("he", "עברית");
public static List GetAvailableLanguages()
@@ -57,7 +58,8 @@ public static List GetAvailableLanguages()
Turkish,
Czech,
Arabic,
- Vietnamese
+ Vietnamese,
+ Hebrew
};
return languages;
}
From e8bbbda75b243cc3025d55a031ad8e2071f3b6e6 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Sun, 15 Dec 2024 00:27:25 +0600
Subject: [PATCH 0086/1335] Add European date formats in settings
---
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 8a835ba7cbb..8d8ccb78041 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -132,7 +132,9 @@ public class ColorSchemeData : DropdownDataGeneric { }
"ddd dd'/'MM",
"dddd dd'/'MM",
"dddd dd', 'MMMM",
- "dd', 'MMMM"
+ "dd', 'MMMM",
+ "dd.MM.yy",
+ "dd.MM.yyyy"
};
public string TimeFormat
From 5f52c81446d8146cde0ccda79a7cd0077640e342 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 16 Dec 2024 22:11:39 +0000
Subject: [PATCH 0087/1335] Bump CommunityToolkit.Mvvm from 8.3.2 to 8.4.0
Bumps [CommunityToolkit.Mvvm](https://github.com/CommunityToolkit/dotnet) from 8.3.2 to 8.4.0.
- [Release notes](https://github.com/CommunityToolkit/dotnet/releases)
- [Commits](https://github.com/CommunityToolkit/dotnet/compare/v8.3.2...v8.4.0)
---
updated-dependencies:
- dependency-name: CommunityToolkit.Mvvm
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index afc3fbbaa0f..d37416f9b26 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -83,7 +83,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
From 532b5dc4c90b03399136299cc514aecd65d59eb5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 19 Dec 2024 14:08:46 +0800
Subject: [PATCH 0088/1335] Replace flags with CSWin32
---
Flow.Launcher/MainWindow.xaml.cs | 6 ++----
Flow.Launcher/NativeMethods.txt | 5 ++++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index b4f1fb0317f..8ca153afc34 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -78,21 +78,19 @@ public MainWindow()
InitializeComponent();
}
- private const int WM_ENTERSIZEMOVE = 0x0231;
- private const int WM_EXITSIZEMOVE = 0x0232;
private int _initialWidth;
private int _initialHeight;
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
- if (msg == WM_ENTERSIZEMOVE)
+ if (msg == PInvoke.WM_ENTERSIZEMOVE)
{
_initialWidth = (int)Width;
_initialHeight = (int)Height;
handled = true;
}
- if (msg == WM_EXITSIZEMOVE)
+ if (msg == PInvoke.WM_EXITSIZEMOVE)
{
if (_initialHeight != (int)Height)
{
diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt
index bbf55502e5a..2b147c05f52 100644
--- a/Flow.Launcher/NativeMethods.txt
+++ b/Flow.Launcher/NativeMethods.txt
@@ -11,4 +11,7 @@ GetShellWindow
GetWindowRect
GetClassName
FindWindowEx
-WINDOW_STYLE
\ No newline at end of file
+WINDOW_STYLE
+
+WM_ENTERSIZEMOVE
+WM_EXITSIZEMOVE
\ No newline at end of file
From 3ab1fb15b639f13fa46ab5fcfceb581e20b3682a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 19 Dec 2024 16:34:32 +0800
Subject: [PATCH 0089/1335] Fix clipboard action under sta thread issue
---
.../NativeMethods.txt | 5 +-
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Infrastructure/Win32Helper.cs | 141 ++++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 45 +++---
4 files changed, 170 insertions(+), 23 deletions(-)
create mode 100644 Flow.Launcher.Infrastructure/Win32Helper.cs
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index f117534a1ff..d8777ff277c 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -16,4 +16,7 @@ WM_KEYUP
WM_SYSKEYDOWN
WM_SYSKEYUP
-EnumWindows
\ No newline at end of file
+EnumWindows
+
+OleInitialize
+OleUninitialize
\ No newline at end of file
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0c7de10fd78..5493ad72410 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -230,7 +230,7 @@ public SearchPrecisionScore QuerySearchPrecision
[JsonIgnore]
public ObservableCollection BuiltinShortcuts { get; set; } = new()
{
- new BuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", Clipboard.GetText),
+ new BuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", () => Win32Helper.StartSTATaskAsync(Clipboard.GetText).Result),
new BuiltinShortcutModel("{active_explorer_path}", "shortcut_active_explorer_path", FileExplorerHelper.GetActiveExplorerPath)
};
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
new file mode 100644
index 00000000000..76e9cfe5bcc
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Windows.Win32;
+
+namespace Flow.Launcher.Infrastructure
+{
+ ///
+ /// Provides static helper for Win32.
+ /// Codes are edited from: https://github.com/files-community/Files.
+ ///
+ public static class Win32Helper
+ {
+ public static Task StartSTATaskAsync(Action action)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+ Thread thread = new(() =>
+ {
+ PInvoke.OleInitialize();
+
+ try
+ {
+ action();
+ taskCompletionSource.SetResult();
+ }
+ catch (System.Exception)
+ {
+ taskCompletionSource.SetResult();
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+
+ public static Task StartSTATaskAsync(Func func)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+ Thread thread = new(async () =>
+ {
+ PInvoke.OleInitialize();
+
+ try
+ {
+ await func();
+ taskCompletionSource.SetResult();
+ }
+ catch (System.Exception)
+ {
+ taskCompletionSource.SetResult();
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+
+ public static Task StartSTATaskAsync(Func func)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ Thread thread = new(() =>
+ {
+ PInvoke.OleInitialize();
+
+ try
+ {
+ taskCompletionSource.SetResult(func());
+ }
+ catch (System.Exception)
+ {
+ taskCompletionSource.SetResult(default);
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+
+ public static Task StartSTATaskAsync(Func> func)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ Thread thread = new(async () =>
+ {
+ PInvoke.OleInitialize();
+ try
+ {
+ taskCompletionSource.SetResult(await func());
+ }
+ catch (System.Exception)
+ {
+ taskCompletionSource.SetResult(default);
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+ }
+}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f4712770d7d..dcdb798fff2 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
@@ -117,35 +117,38 @@ public void ShellRun(string cmd, string filename = "cmd.exe")
ShellCommand.Execute(startInfo);
}
- public void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
+ public async void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
{
if (string.IsNullOrEmpty(stringToCopy))
return;
- var isFile = File.Exists(stringToCopy);
- if (directCopy && (isFile || Directory.Exists(stringToCopy)))
+ await Win32Helper.StartSTATaskAsync(() =>
{
- var paths = new StringCollection
+ var isFile = File.Exists(stringToCopy);
+ if (directCopy && (isFile || Directory.Exists(stringToCopy)))
{
- stringToCopy
- };
+ var paths = new StringCollection
+ {
+ stringToCopy
+ };
- Clipboard.SetFileDropList(paths);
+ Clipboard.SetFileDropList(paths);
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
- GetTranslation("completedSuccessfully"));
- }
- else
- {
- Clipboard.SetDataObject(stringToCopy);
+ if (showDefaultNotification)
+ ShowMsg(
+ $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
+ GetTranslation("completedSuccessfully"));
+ }
+ else
+ {
+ Clipboard.SetDataObject(stringToCopy);
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
- GetTranslation("completedSuccessfully"));
- }
+ if (showDefaultNotification)
+ ShowMsg(
+ $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
+ GetTranslation("completedSuccessfully"));
+ }
+ });
}
public void StartLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Visible;
From 243ebb8df23dfc2119683a8c1d7b9bfff48c6017 Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Thu, 19 Dec 2024 14:35:29 +0500
Subject: [PATCH 0090/1335] ci: fix permissions + migrate to fresher action (Pr
Assign) (#3117)
* ci: fix permissions + migrate to fresher action
* ci: remove unnecessary comment
---
.github/workflows/pr_assignee.yml | 10 +++++-----
.github/workflows/pr_milestone.yml | 3 +++
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/pr_assignee.yml b/.github/workflows/pr_assignee.yml
index af6daff02b7..44b808885d2 100644
--- a/.github/workflows/pr_assignee.yml
+++ b/.github/workflows/pr_assignee.yml
@@ -1,19 +1,19 @@
name: Assign PR to creator
-# Due to GitHub token limitation, only able to assign org members not authors from forks.
-# https://github.com/thomaseizinger/assign-pr-creator-action/issues/3
-
on:
- pull_request:
+ pull_request_target:
types: [opened]
branches-ignore:
- l10n_dev
+permissions:
+ pull-requests: write
+
jobs:
automation:
runs-on: ubuntu-latest
steps:
- name: Assign PR to creator
- uses: thomaseizinger/assign-pr-creator-action@v1.0.0
+ uses: toshimaru/auto-author-assign@v2.1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/pr_milestone.yml b/.github/workflows/pr_milestone.yml
index b343a39cc8f..b17912be0b1 100644
--- a/.github/workflows/pr_milestone.yml
+++ b/.github/workflows/pr_milestone.yml
@@ -6,6 +6,9 @@ on:
pull_request:
types: [opened]
+permissions:
+ pull-requests: write
+
jobs:
automation:
runs-on: ubuntu-latest
From 141634ca8855f6dffb41d429d5587ac57e9496fd Mon Sep 17 00:00:00 2001
From: NoPlagiarism <37241775+NoPlagiarism@users.noreply.github.com>
Date: Thu, 19 Dec 2024 21:07:46 +0500
Subject: [PATCH 0091/1335] ci: pull_request_target & remove useless secret
---
.github/workflows/pr_assignee.yml | 2 --
.github/workflows/pr_milestone.yml | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/.github/workflows/pr_assignee.yml b/.github/workflows/pr_assignee.yml
index 44b808885d2..5be603df632 100644
--- a/.github/workflows/pr_assignee.yml
+++ b/.github/workflows/pr_assignee.yml
@@ -15,5 +15,3 @@ jobs:
steps:
- name: Assign PR to creator
uses: toshimaru/auto-author-assign@v2.1.1
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/pr_milestone.yml b/.github/workflows/pr_milestone.yml
index b17912be0b1..e2365f55493 100644
--- a/.github/workflows/pr_milestone.yml
+++ b/.github/workflows/pr_milestone.yml
@@ -3,7 +3,7 @@ name: Set Milestone
# Assigns the earliest created milestone that matches the below glob pattern.
on:
- pull_request:
+ pull_request_target:
types: [opened]
permissions:
From 1073821b655e3dd29062fd19cc4a6f2b976aa292 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 20 Dec 2024 18:55:57 +0800
Subject: [PATCH 0092/1335] Improve recyble bin clear issue noticification
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 8bcd5cd6b75..5bfc68ea613 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -252,8 +252,10 @@ private List Commands()
var result = PInvoke.SHEmptyRecycleBin(new(), string.Empty, 0);
if (result != HRESULT.S_OK && result != HRESULT.E_UNEXPECTED)
{
- context.API.ShowMsgBox($"Error emptying recycle bin, error code: {result}\n" +
- "please refer to https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137",
+ context.API.ShowMsgBox("Failed to empty the recycle bin. This might happen if:\n" +
+ "- A file in the recycle bin is in use\n" +
+ "- You don't have permission to delete some items\n" +
+ "Please close any applications that might be using these files and try again.",
"Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
From b5e401f759d01a9aa4d52a2500e5be15772b6480 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 23 Dec 2024 15:50:52 +0800
Subject: [PATCH 0093/1335] Fix user result set max value issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 7260593dc28..8bfd2f4e569 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1473,7 +1473,7 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
result.Score = int.MaxValue;
}
- else
+ else if (result.Score != int.MaxValue)
{
var priorityScore = metaResults.Metadata.Priority * 150;
result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
From 4ad967b5f31c5e500d8ff08b5a897806c9890daa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 23 Dec 2024 15:57:59 +0800
Subject: [PATCH 0094/1335] Add support for removing selected count from score
---
Flow.Launcher.Plugin/Result.cs | 5 +++++
Flow.Launcher/ViewModel/MainViewModel.cs | 4 +++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 027631533a1..57ee1e92182 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -263,6 +263,11 @@ public ValueTask ExecuteAsync(ActionContext context)
///
public PreviewInfo Preview { get; set; } = PreviewInfo.Default;
+ ///
+ /// Determines if the selected count should be added to the score
+ ///
+ public bool AddSelectedCount { get; set; } = true;
+
///
/// Info of the preview section of a
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8bfd2f4e569..6458316bbb5 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1476,7 +1476,9 @@ public void UpdateResultView(ICollection resultsForUpdates)
else if (result.Score != int.MaxValue)
{
var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ result.Score += result.AddSelectedCount ?
+ _userSelectedRecord.GetSelectedCount(result) + priorityScore :
+ priorityScore;
}
}
}
From 1c01fa4e46a53367a3d0c66cc3fe3214e22bdcce Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 24 Dec 2024 14:32:05 +1100
Subject: [PATCH 0095/1335] update comment
---
Flow.Launcher.Plugin/Result.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 57ee1e92182..669927072d8 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -264,7 +264,7 @@ public ValueTask ExecuteAsync(ActionContext context)
public PreviewInfo Preview { get; set; } = PreviewInfo.Default;
///
- /// Determines if the selected count should be added to the score
+ /// Determines if the user selection count should be added to the score. This can be useful when set to false to allow the result sequence order to be the same everytime instead of changing based on selection.
///
public bool AddSelectedCount { get; set; } = true;
From 269e583ea7629c3b1bfd6bc945c39ac026bbe11d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 24 Dec 2024 11:54:15 +0800
Subject: [PATCH 0096/1335] Add maximum score to the results for developers.
---
Flow.Launcher.Plugin/Result.cs | 5 +++++
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 669927072d8..f2050cc9f78 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -268,6 +268,11 @@ public ValueTask ExecuteAsync(ActionContext context)
///
public bool AddSelectedCount { get; set; } = true;
+ ///
+ /// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users.
+ ///
+ public const int MaxScore = int.MaxValue;
+
///
/// Info of the preview section of a
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6458316bbb5..e369a1fea15 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1471,9 +1471,9 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
if (_topMostRecord.IsTopMost(result))
{
- result.Score = int.MaxValue;
+ result.Score = Result.MaxScore;
}
- else if (result.Score != int.MaxValue)
+ else if (result.Score != Result.MaxScore)
{
var priorityScore = metaResults.Metadata.Priority * 150;
result.Score += result.AddSelectedCount ?
From 6f899092b59a344b3ceb3d2edd28700e585c7335 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 24 Dec 2024 11:59:04 +0800
Subject: [PATCH 0097/1335] Move dll import codes to win32 helper
---
Flow.Launcher.Core/Resource/Theme.cs | 98 +-----------------
Flow.Launcher.Infrastructure/Win32Helper.cs | 106 +++++++++++++++++++-
2 files changed, 104 insertions(+), 100 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 0d8c0d90163..1d840930663 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -3,10 +3,8 @@
using System.IO;
using System.Linq;
using System.Xml;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Effects;
@@ -98,12 +96,12 @@ public bool ChangeTheme(string theme)
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
- BlurEnabled = IsBlurTheme();
+ BlurEnabled = Win32Helper.IsBlurTheme();
if (Settings.UseDropShadowEffect && !BlurEnabled)
AddDropShadowEffectToCurrentTheme();
- SetBlurForWindow();
+ Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
}
catch (DirectoryNotFoundException)
{
@@ -357,98 +355,6 @@ public void RemoveDropShadowEffectFromCurrentTheme()
UpdateResourceDictionary(dict);
}
- #region Blur Handling
- /*
- Found on https://github.com/riverar/sample-win10-aeroglass
- */
- private enum AccentState
- {
- ACCENT_DISABLED = 0,
- ACCENT_ENABLE_GRADIENT = 1,
- ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
- ACCENT_ENABLE_BLURBEHIND = 3,
- ACCENT_INVALID_STATE = 4
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct AccentPolicy
- {
- public AccentState AccentState;
- public int AccentFlags;
- public int GradientColor;
- public int AnimationId;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WindowCompositionAttributeData
- {
- public WindowCompositionAttribute Attribute;
- public IntPtr Data;
- public int SizeOfData;
- }
-
- private enum WindowCompositionAttribute
- {
- WCA_ACCENT_POLICY = 19
- }
- [DllImport("user32.dll")]
- private static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
-
- ///
- /// Sets the blur for a window via SetWindowCompositionAttribute
- ///
- public void SetBlurForWindow()
- {
- if (BlurEnabled)
- {
- SetWindowAccent(Application.Current.MainWindow, AccentState.ACCENT_ENABLE_BLURBEHIND);
- }
- else
- {
- SetWindowAccent(Application.Current.MainWindow, AccentState.ACCENT_DISABLED);
- }
- }
-
- private bool IsBlurTheme()
- {
- if (Environment.OSVersion.Version >= new Version(6, 2))
- {
- var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
-
- if (resource is bool)
- return (bool)resource;
-
- return false;
- }
-
- return false;
- }
-
- private void SetWindowAccent(Window w, AccentState state)
- {
- var windowHelper = new WindowInteropHelper(w);
-
- windowHelper.EnsureHandle();
-
- var accent = new AccentPolicy { AccentState = state };
- var accentStructSize = Marshal.SizeOf(accent);
-
- var accentPtr = Marshal.AllocHGlobal(accentStructSize);
- Marshal.StructureToPtr(accent, accentPtr, false);
-
- var data = new WindowCompositionAttributeData
- {
- Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
- SizeOfData = accentStructSize,
- Data = accentPtr
- };
-
- SetWindowCompositionAttribute(windowHelper.Handle, ref data);
-
- Marshal.FreeHGlobal(accentPtr);
- }
- #endregion
-
public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null);
}
}
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 76e9cfe5bcc..6d6c7286412 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -1,16 +1,21 @@
using System;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
+using System.Windows.Interop;
+using System.Windows;
using Windows.Win32;
namespace Flow.Launcher.Infrastructure
{
- ///
- /// Provides static helper for Win32.
- /// Codes are edited from: https://github.com/files-community/Files.
- ///
public static class Win32Helper
{
+ #region STA Thread
+
+ /*
+ Found on https://github.com/files-community/Files
+ */
+
public static Task StartSTATaskAsync(Action action)
{
var taskCompletionSource = new TaskCompletionSource();
@@ -137,5 +142,98 @@ public static Task StartSTATaskAsync(Func func)
return taskCompletionSource.Task;
}
+
+ #endregion
+
+ #region Blur Handling
+
+ /*
+ Found on https://github.com/riverar/sample-win10-aeroglass
+ */
+
+ private enum AccentState
+ {
+ ACCENT_DISABLED = 0,
+ ACCENT_ENABLE_GRADIENT = 1,
+ ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
+ ACCENT_ENABLE_BLURBEHIND = 3,
+ ACCENT_INVALID_STATE = 4
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct AccentPolicy
+ {
+ public AccentState AccentState;
+ public int AccentFlags;
+ public int GradientColor;
+ public int AnimationId;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct WindowCompositionAttributeData
+ {
+ public WindowCompositionAttribute Attribute;
+ public IntPtr Data;
+ public int SizeOfData;
+ }
+
+ private enum WindowCompositionAttribute
+ {
+ WCA_ACCENT_POLICY = 19
+ }
+
+ [DllImport("user32.dll")]
+ private static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
+
+ ///
+ /// Checks if the blur theme is enabled
+ ///
+ public static bool IsBlurTheme()
+ {
+ if (Environment.OSVersion.Version >= new Version(6, 2))
+ {
+ var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
+
+ if (resource is bool b)
+ return b;
+
+ return false;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Sets the blur for a window via SetWindowCompositionAttribute
+ ///
+ public static void SetBlurForWindow(Window w, bool blur)
+ {
+ SetWindowAccent(w, blur ? AccentState.ACCENT_ENABLE_BLURBEHIND : AccentState.ACCENT_DISABLED);
+ }
+
+ private static void SetWindowAccent(Window w, AccentState state)
+ {
+ var windowHelper = new WindowInteropHelper(w);
+
+ windowHelper.EnsureHandle();
+
+ var accent = new AccentPolicy { AccentState = state };
+ var accentStructSize = Marshal.SizeOf(accent);
+
+ var accentPtr = Marshal.AllocHGlobal(accentStructSize);
+ Marshal.StructureToPtr(accent, accentPtr, false);
+
+ var data = new WindowCompositionAttributeData
+ {
+ Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
+ SizeOfData = accentStructSize,
+ Data = accentPtr
+ };
+
+ SetWindowCompositionAttribute(windowHelper.Handle, ref data);
+
+ Marshal.FreeHGlobal(accentPtr);
+ }
+ #endregion
}
}
From 51a16cc40f8159f6e54d772df16e5ae0466be989 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 6 Dec 2024 23:55:20 -0600
Subject: [PATCH 0098/1335] Remove Result comparison and Change signature from
IEnumerable to ICollection (due to the potential of multiple enumeration)
---
Flow.Launcher.Plugin/Result.cs | 21 ---------------------
Flow.Launcher/ViewModel/ResultsViewModel.cs | 6 +++---
2 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index f2050cc9f78..c6ca81cf31c 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -157,27 +157,6 @@ public string PluginDirectory
}
}
- ///
- public override bool Equals(object obj)
- {
- var r = obj as Result;
-
- var equality = string.Equals(r?.Title, Title) &&
- string.Equals(r?.SubTitle, SubTitle) &&
- string.Equals(r?.AutoCompleteText, AutoCompleteText) &&
- string.Equals(r?.CopyText, CopyText) &&
- string.Equals(r?.IcoPath, IcoPath) &&
- TitleHighlightData == r.TitleHighlightData;
-
- return equality;
- }
-
- ///
- public override int GetHashCode()
- {
- return HashCode.Combine(Title, SubTitle, AutoCompleteText, CopyText, IcoPath);
- }
-
///
public override string ToString()
{
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 107372e0115..c0e0b146d03 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -182,7 +182,7 @@ public void AddResults(List newRawResults, string resultId)
///
/// To avoid deadlock, this method should not called from main thread
///
- public void AddResults(IEnumerable resultsForUpdates, CancellationToken token, bool reselect = true)
+ public void AddResults(ICollection resultsForUpdates, CancellationToken token, bool reselect = true)
{
var newResults = NewResults(resultsForUpdates);
@@ -228,12 +228,12 @@ private List NewResults(List newRawResults, string resu
.ToList();
}
- private List NewResults(IEnumerable resultsForUpdates)
+ private List NewResults(ICollection resultsForUpdates)
{
if (!resultsForUpdates.Any())
return Results;
- return Results.Where(r => r != null && !resultsForUpdates.Any(u => u.ID == r.Result.PluginID))
+ return Results.Where(r => r != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
.Concat(resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)))
.OrderByDescending(rv => rv.Result.Score)
.ToList();
From 5f6ac6a35e38c301ffb2b8b2fdc5af95869b3703 Mon Sep 17 00:00:00 2001
From: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
Date: Sat, 7 Dec 2024 12:48:15 -0600
Subject: [PATCH 0099/1335] Update Flow.Launcher/ViewModel/ResultsViewModel.cs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher/ViewModel/ResultsViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index c0e0b146d03..7d2b5bc9348 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -233,7 +233,7 @@ private List NewResults(ICollection resultsFo
if (!resultsForUpdates.Any())
return Results;
- return Results.Where(r => r != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
+ return Results.Where(r => r?.Result != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
.Concat(resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)))
.OrderByDescending(rv => rv.Result.Score)
.ToList();
From e7e825e930c61a50ac4deb9eb481cfc860514049 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Thu, 26 Dec 2024 03:41:40 +1100
Subject: [PATCH 0100/1335] New Crowdin updates (#3062)
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations resources.resx (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations resources.resx (Portuguese)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Arabic)
[ci skip]
* New translations en.xaml (Czech)
[ci skip]
* New translations en.xaml (Danish)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Italian)
[ci skip]
* New translations en.xaml (Japanese)
[ci skip]
* New translations en.xaml (Korean)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (Turkish)
[ci skip]
* New translations en.xaml (Ukrainian)
[ci skip]
* New translations en.xaml (Chinese Simplified)
[ci skip]
* New translations en.xaml (Chinese Traditional)
[ci skip]
* New translations en.xaml (Vietnamese)
[ci skip]
* New translations en.xaml (Portuguese, Brazilian)
[ci skip]
* New translations en.xaml (Norwegian Bokmal)
[ci skip]
* New translations en.xaml (Serbian (Latin))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish, Latin America)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations resources.resx (Hebrew)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Hebrew)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Arabic)
[ci skip]
* New translations en.xaml (Czech)
[ci skip]
* New translations en.xaml (Danish)
[ci skip]
* New translations en.xaml (German)
[ci skip]
* New translations en.xaml (Italian)
[ci skip]
* New translations en.xaml (Japanese)
[ci skip]
* New translations en.xaml (Korean)
[ci skip]
* New translations en.xaml (Dutch)
[ci skip]
* New translations en.xaml (Polish)
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
* New translations en.xaml (Russian)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (Turkish)
[ci skip]
* New translations en.xaml (Ukrainian)
[ci skip]
* New translations en.xaml (Chinese Simplified)
[ci skip]
* New translations en.xaml (Chinese Traditional)
[ci skip]
* New translations en.xaml (Vietnamese)
[ci skip]
* New translations en.xaml (Portuguese, Brazilian)
[ci skip]
* New translations en.xaml (Norwegian Bokmal)
[ci skip]
* New translations en.xaml (Serbian (Latin))
[ci skip]
* New translations en.xaml (Spanish, Latin America)
[ci skip]
* New translations en.xaml (Slovak)
[ci skip]
* New translations en.xaml (French)
[ci skip]
* New translations en.xaml (Spanish (Modern))
[ci skip]
* New translations en.xaml (Portuguese)
[ci skip]
---------
Co-authored-by: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
---
Flow.Launcher/Languages/ar.xaml | 2 +
Flow.Launcher/Languages/cs.xaml | 2 +
Flow.Launcher/Languages/da.xaml | 2 +
Flow.Launcher/Languages/de.xaml | 18 +-
Flow.Launcher/Languages/es-419.xaml | 2 +
Flow.Launcher/Languages/es.xaml | 6 +-
Flow.Launcher/Languages/fr.xaml | 2 +
Flow.Launcher/Languages/he.xaml | 458 +++
Flow.Launcher/Languages/it.xaml | 2 +
Flow.Launcher/Languages/ja.xaml | 2 +
Flow.Launcher/Languages/ko.xaml | 2 +
Flow.Launcher/Languages/nb.xaml | 2 +
Flow.Launcher/Languages/nl.xaml | 2 +
Flow.Launcher/Languages/pl.xaml | 4 +-
Flow.Launcher/Languages/pt-br.xaml | 2 +
Flow.Launcher/Languages/pt-pt.xaml | 2 +
Flow.Launcher/Languages/ru.xaml | 11 +-
Flow.Launcher/Languages/sk.xaml | 3 +-
Flow.Launcher/Languages/sr.xaml | 2 +
Flow.Launcher/Languages/tr.xaml | 2 +
Flow.Launcher/Languages/uk-UA.xaml | 2 +
Flow.Launcher/Languages/vi.xaml | 2 +
Flow.Launcher/Languages/zh-cn.xaml | 2 +
Flow.Launcher/Languages/zh-tw.xaml | 2 +
Flow.Launcher/Properties/Resources.he-IL.resx | 130 +
.../Languages/de.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/he.xaml | 28 +
.../Languages/de.xaml | 4 +-
.../Languages/he.xaml | 15 +
.../Languages/de.xaml | 22 +-
.../Languages/he.xaml | 165 ++
.../Languages/ru.xaml | 10 +-
.../Languages/de.xaml | 4 +-
.../Languages/he.xaml | 9 +
.../Languages/he.xaml | 63 +
.../Languages/de.xaml | 10 +-
.../Languages/he.xaml | 11 +
.../Languages/de.xaml | 2 +-
.../Languages/fr.xaml | 2 +-
.../Languages/he.xaml | 95 +
.../Languages/he.xaml | 17 +
.../Languages/ru.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/he.xaml | 63 +
.../Languages/de.xaml | 10 +-
.../Languages/he.xaml | 17 +
.../Languages/ar.xaml | 3 +-
.../Languages/cs.xaml | 3 +-
.../Languages/da.xaml | 3 +-
.../Languages/de.xaml | 23 +-
.../Languages/es-419.xaml | 3 +-
.../Languages/es.xaml | 3 +-
.../Languages/fr.xaml | 5 +-
.../Languages/he.xaml | 52 +
.../Languages/it.xaml | 3 +-
.../Languages/ja.xaml | 3 +-
.../Languages/ko.xaml | 3 +-
.../Languages/nb.xaml | 3 +-
.../Languages/nl.xaml | 3 +-
.../Languages/pl.xaml | 3 +-
.../Languages/pt-br.xaml | 3 +-
.../Languages/pt-pt.xaml | 3 +-
.../Languages/ru.xaml | 1 -
.../Languages/sk.xaml | 3 +-
.../Languages/sr.xaml | 3 +-
.../Languages/tr.xaml | 3 +-
.../Languages/uk-UA.xaml | 3 +-
.../Languages/vi.xaml | 3 +-
.../Languages/zh-cn.xaml | 3 +-
.../Languages/zh-tw.xaml | 3 +-
.../Properties/Resources.de-DE.resx | 40 +-
.../Properties/Resources.he-IL.resx | 2514 +++++++++++++++++
.../Properties/Resources.pt-PT.resx | 44 +-
74 files changed, 3832 insertions(+), 128 deletions(-)
create mode 100644 Flow.Launcher/Languages/he.xaml
create mode 100644 Flow.Launcher/Properties/Resources.he-IL.resx
create mode 100644 Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index b096e748942..fa5c968d479 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -65,6 +65,8 @@
حفظ الاستعلام الأخير
اختيار الاستعلام الأخير
تفريغ الاستعلام الأخير
+ Preserve Last Action Keyword
+ Select Last Action Keyword
ارتفاع ثابت للنافذة
ارتفاع النافذة غير قابل للتعديل عن طريق السحب.
الحد الأقصى للنتائج المعروضة
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 8bc572c112f..05adf095b68 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -65,6 +65,8 @@
Zachovat poslední dotaz
Vybrat poslední dotaz
Smazat poslední dotaz
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Počet zobrazených výsledků
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index f8e3ea4a5af..36970ad5364 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -65,6 +65,8 @@
Preserve Last Query
Select last Query
Empty last Query
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Maksimum antal resultater vist
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 600d96e2593..7f2e2bd8d03 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -65,6 +65,8 @@
Letzte Abfrage beibehalten
Letzte Abfrage auswählen
Letzte Abfrage leeren
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Feste Fensterhöhe
Die Fensterhöhe ist durch Ziehen nicht anpassbar.
Maximal gezeigte Ergebnisse
@@ -77,7 +79,7 @@
Einstellung für Neuer Tab, Neues Fenster, Privater Modus.
Python-Pfad
Node.js-Pfad
- Bitte wählen Sie das Programm Node.js aus
+ Bitte wählen Sie die ausführbare Datei Node.js aus
Bitte wählen Sie pythonw.exe aus
Tippen immer im englischen Modus starten
Ändern Sie Ihre Eingabemethode temporär in den englischen Modus, wenn Sie Flow aktivieren.
@@ -166,8 +168,8 @@
Individuell anpassen
Fenstermodus
Opazität
- Theme {0} ist nicht vorhanden, Fallback auf Standard-Theme
- Theme {0} konnte nicht geladen werden, Fallback auf Standard-Theme
+ Theme {0} ist nicht vorhanden, Fallback auf Default-Theme
+ Theme {0} konnte nicht geladen werden, Fallback auf Default-Theme
Theme-Ordner
Theme-Ordner öffnen
Farbschema
@@ -175,7 +177,7 @@
Hell
Dunkel
Soundeffekt
- Einen kleinen Sound abspielen, wenn das Suchfenster geöffnet wird
+ Einen kurzen Sound abspielen, wenn das Suchfenster geöffnet wird
Lautstärke der Soundeffekte
Lautstärke des Soundeffekts anpassen
Windows Media Player ist nicht verfügbar und ist für die Lautstärkeregelung von Flow erforderlich. Bitte überprüfen Sie Ihre Installation, wenn Sie die Lautstärke anpassen müssen.
@@ -287,8 +289,8 @@
Versionshinweise
Tipps zur Nutzung
DevTools
- Ordner Einstellungen
- Ordner Logs
+ Ordner »Settings«
+ Ordner »Logs«
Logs löschen
Sind Sie sicher, dass Sie alle Logs löschen wollen?
Assistent
@@ -411,8 +413,8 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
Willkommen bei Flow Launcher
Hallo, dies ist das erste Mal, dass Sie Flow Launcher ausführen!
Bevor Sie beginnen, hilft dieser Assistent bei der Einrichtung von Flow Launcher. Sie können dies überspringen, wenn Sie möchten. Bitte wählen Sie eine Sprache
- Suchen und führen Sie alle Dateien und Anwendungen auf Ihrem PC aus
- Suchen Sie alles in Anwendungen, Dateien, Lesezeichen, YouTube, Twitter und vielem mehr. Alles bequem über Ihre Tastatur, ohne die Maus zu berühren.
+ Alle Dateien und Anwendungen auf Ihrem PC suchen und ausführen
+ Durchsuchen Sie alles von Anwendungen, Dateien, Lesezeichen, YouTube, Twitter und vielem mehr. Alles bequem über Ihre Tastatur, ohne die Maus zu berühren.
Flow Launcher startet mit dem unten stehenden Hotkey, probieren Sie ihn gleich aus. Um ihn zu ändern, klicken Sie auf die Eingabe und drücken Sie den gewünschten Hotkey auf der Tastatur.
Hotkeys
Aktions-Schlüsselwort und Befehle
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 9a682269cf8..0556c59ae4f 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -65,6 +65,8 @@
Conservar última consulta
Seleccionar última consulta
Borrar última consulta
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 328d98d4188..bf22aea48c9 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -65,6 +65,8 @@
Mantener la última consulta
Seleccionar la última consulta
Limpiar la última consulta
+ Conservar palabra clave de última acción
+ Seleccionar palabra clave de última acción
Altura de la ventana fija
La altura de la ventana no se puede ajustar arrastrando el ratón.
Número máximo de resultados mostrados
@@ -218,7 +220,7 @@
Abrir menú contextual nativo
Abrir ventana de configuración
Copiar ruta del archivo
- Cambia a Modo Juego
+ Cambiar a Modo Juego
Cambiar historial
Abrir carpeta contenedora
Ejecutar como administrador
@@ -293,7 +295,7 @@
¿Está seguro de que desea eliminar todos los registros?
Asistente
Ubicación de datos del usuario
- La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portátil o no.
+ La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portable o no.
Abrir carpeta
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index b171dcc9e5c..e978e91ecd1 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -65,6 +65,8 @@
Conserver la dernière recherche
Sélectionner la dernière recherche
Ne pas afficher la dernière recherche
+ Conserver le mot clé de la dernière action
+ Sélectionnez le mot clé de la dernière action
Hauteur de fenêtre fixe
La hauteur de la fenêtre n'est pas réglable par glissement.
Résultats maximums à afficher
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
new file mode 100644
index 00000000000..eeb33da1727
--- /dev/null
+++ b/Flow.Launcher/Languages/he.xaml
@@ -0,0 +1,458 @@
+
+
+
+
+ Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
+ {2}{2}
+ Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
+
+ אנא בחר את קובץ ההפעלה {0}
+ לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).
+ נכשל בהפעלת תוספים
+ תוספים: {0} - נכשלים בטעינה ויהיו מושבתים, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
+
+
+ רישום מקש הקיצור "{0}" נכשל. ייתכן שמקש הקיצור נמצא בשימוש על ידי תוכנה אחרת. שנה למקש קיצור אחר, או צא מהתוכנה האחרת.
+ Flow Launcher
+ לא ניתן היה להפעיל את {0}
+ פורמט קובץ תוסף Flow Launcher לא חוקי
+ הגדר כגבוה ביותר בשאילתה זו
+ בטל העלאה בשאילתה זו
+ בצע שאילתה: {0}
+ Last execution time: {0}
+ פתח
+ הגדרות
+ אודות
+ יציאה
+ סגור
+ העתק
+ גזור
+ הדבק
+ Undo
+ בחר הכל
+ קובץ
+ תיקייה
+ טקסט
+ מצב משחק
+ השהה את השימוש במקשי קיצור.
+ Position Reset
+ Reset search window position
+
+
+ הגדרות
+ כללי
+ מצב נייד
+ אחסן את כל ההגדרות ונתוני המשתמש בתיקייה אחת (שימושי בשימוש עם כוננים נשלפים או שירותי ענן).
+ הפעל את Flow Launcher בעת הפעלת Window
+ שגיאה בהגדרת ההפעלה בעת הפעלת windows
+ הסתר את Flow Launcher כאשר הוא אינו החלון הפעיל
+ אל תציג התראות על גרסה חדשה
+ מיקום חלון החיפוש
+ זכור את המיקום האחרון
+ Monitor with Mouse Cursor
+ Monitor with Focused Window
+ צג ראשי
+ צג מותאם אישית
+ Search Window Position on Monitor
+ Center
+ Center Top
+ Left Top
+ Right Top
+ Custom Position
+ שפה
+ Last Query Style
+ Show/Hide previous results when Flow Launcher is reactivated.
+ Preserve Last Query
+ Select last Query
+ Empty last Query
+ Preserve Last Action Keyword
+ Select Last Action Keyword
+ Fixed Window Height
+ The window height is not adjustable by dragging.
+ Maximum results shown
+ You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
+ Ignore hotkeys in fullscreen mode
+ Disable Flow Launcher activation when a full screen application is active (Recommended for games).
+ Default File Manager
+ Select the file manager to use when opening the folder.
+ Default Web Browser
+ Setting for New Tab, New Window, Private Mode.
+ Python Path
+ Node.js Path
+ Please select the Node.js executable
+ Please select pythonw.exe
+ Always Start Typing in English Mode
+ Temporarily change your input method to English mode when activating Flow.
+ Auto Update
+ Select
+ Hide Flow Launcher on startup
+ Flow Launcher search window is hidden in the tray after starting up.
+ Hide tray icon
+ When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.
+ Query Search Precision
+ Changes minimum match score required for results.
+ None
+ Low
+ Regular
+ Search with Pinyin
+ Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
+ Always Preview
+ Always open preview panel when Flow activates. Press {0} to toggle preview.
+ Shadow effect is not allowed while current theme has blur effect enabled
+
+
+ Search Plugin
+ Ctrl+F to search plugins
+ No results found
+ Please try a different search.
+ Plugin
+ תוספים
+ מצא תוספים נוספים
+ On
+ Off
+ Action keyword Setting
+ Action keyword
+ Current action keyword
+ New action keyword
+ Change Action Keywords
+ Current Priority
+ New Priority
+ Priority
+ Change Plugin Results Priority
+ Plugin Directory
+ by
+ Init time:
+ Query time:
+ Version
+ Website
+ Uninstall
+
+
+
+ חנות תוספים
+ New Release
+ Recently Updated
+ תוספים
+ Installed
+ רענן
+ התקן
+ Uninstall
+ עדכון
+ Plugin already installed
+ New Version
+ This plugin has been updated within the last 7 days
+ New Update is Available
+
+
+
+
+ ערכת נושא
+ Appearance
+ גלריית ערכות נושא
+ How to create a theme
+ Hi There
+ Explorer
+ Search for files, folders and file contents
+ WebSearch
+ Search the web with different search engine support
+ Program
+ Launch programs as admin or a different user
+ ProcessKiller
+ Terminate unwanted processes
+ Search Bar Height
+ Item Height
+ Query Box Font
+ Result Title Font
+ Result Subtitle Font
+ Reset
+ Customize
+ Window Mode
+ Opacity
+ Theme {0} not exists, fallback to default theme
+ Fail to load theme {0}, fallback to default theme
+ Theme Folder
+ Open Theme Folder
+ Color Scheme
+ System Default
+ בהיר
+ כהה
+ Sound Effect
+ Play a small sound when the search window opens
+ Sound Effect Volume
+ Adjust the volume of the sound effect
+ Windows Media Player is unavailable and is required for Flow's volume adjustment. Please check your installation if you need to adjust volume.
+ Animation
+ Use Animation in UI
+ Animation Speed
+ The speed of the UI animation
+ Slow
+ Medium
+ Fast
+ Custom
+ Clock
+ Date
+ This theme supports two(light/dark) modes.
+ This theme supports Blur Transparent Background.
+
+
+
+ Hotkey
+ Hotkeys
+ Open Flow Launcher
+ Enter shortcut to show/hide Flow Launcher.
+ Toggle Preview
+ Enter shortcut to show/hide preview in search window.
+ Hotkey Presets
+ List of currently registered hotkeys
+ Open Result Modifier Key
+ Select a modifier key to open selected result via keyboard.
+ Show Hotkey
+ Show result selection hotkey with results.
+ Auto Complete
+ Runs autocomplete for the selected items.
+ Select Next Item
+ Select Previous Item
+ Next Page
+ Previous Page
+ Cycle Previous Query
+ Cycle Next Query
+ Open Context Menu
+ Open Native Context Menu
+ Open Setting Window
+ Copy File Path
+ Toggle Game Mode
+ Toggle History
+ Open Containing Folder
+ Run As Admin
+ Refresh Search Results
+ Reload Plugins Data
+ Quick Adjust Window Width
+ Quick Adjust Window Height
+ Use when require plugins to reload and update their existing data.
+ You can add one more hotkey for this function.
+ Custom Query Hotkeys
+ Custom Query Shortcuts
+ Built-in Shortcuts
+ שאילתה
+ Shortcut
+ Expansion
+ Description
+ מחק
+ ערוך
+ הוסף
+ None
+ אנא בחר פריט
+ Are you sure you want to delete {0} plugin hotkey?
+ Are you sure you want to delete shortcut: {0} with expansion {1}?
+ Get text from clipboard.
+ Get path from active explorer.
+ Query window shadow effect
+ Shadow effect has a substantial usage of GPU. Not recommended if your computer performance is limited.
+ Window Width Size
+ You can also quickly adjust this by using Ctrl+[ and Ctrl+].
+ Use Segoe Fluent Icons
+ Use Segoe Fluent Icons for query results where supported
+ Press Key
+
+
+ HTTP Proxy
+ Enable HTTP Proxy
+ HTTP Server
+ Port
+ User Name
+ Password
+ Test Proxy
+ שמור
+ Server field can't be empty
+ Port field can't be empty
+ Invalid port format
+ Proxy configuration saved successfully
+ Proxy configured correctly
+ Proxy connection failed
+
+
+ אודות
+ Website
+ GitHub
+ Docs
+ Version
+ Icons
+ You have activated Flow Launcher {0} times
+ Check for Updates
+ Become A Sponsor
+ New version {0} is available, would you like to restart Flow Launcher to use the update?
+ בדיקת העדכונים נכשלה, אנא בדוק את הגדרות החיבור ואת הגדרות ה-Proxy שלך לכתובת api.github.com.
+
+ Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com,
+ or go to https://github.com/Flow-Launcher/Flow.Launcher/releases to download updates manually.
+
+ Release Notes
+ Usage Tips
+ DevTools
+ Setting Folder
+ Log Folder
+ Clear Logs
+ Are you sure you want to delete all logs?
+ אשף
+ User Data Location
+ User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
+ Open Folder
+
+
+ Select File Manager
+ Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
+ For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
+ File Manager
+ Profile Name
+ File Manager Path
+ Arg For Folder
+ Arg For File
+
+
+ Default Web Browser
+ The default setting follows the OS default browser setting. If specified separately, flow uses that browser.
+ Browser
+ Browser Name
+ Browser Path
+ New Window
+ New Tab
+ Private Mode
+
+
+ Change Priority
+ Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number
+ Please provide an valid integer for Priority!
+
+
+ Old Action Keyword
+ New Action Keyword
+ ביטול
+ בוצע
+ Can't find specified plugin
+ New Action Keyword can't be empty
+ This new Action Keyword is already assigned to another plugin, please choose a different one
+ הצליח
+ הושלם בהצלחה
+ Enter the action keyword you like to use to start the plugin. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Custom Query Hotkey
+ Press a custom hotkey to open Flow Launcher and input the specified query automatically.
+ תצוגה מקדימה
+ Hotkey is unavailable, please select a new hotkey
+ Invalid plugin hotkey
+ עדכון
+ Binding Hotkey
+ Current hotkey is unavailable.
+ This hotkey is reserved for "{0}" and can't be used. Please choose another hotkey.
+ This hotkey is already in use by "{0}". If you press "Overwrite", it will be removed from "{0}".
+ Press the keys you want to use for this function.
+
+
+ Custom Query Shortcut
+ Enter a shortcut that automatically expands to the specified query.
+ A shortcut is expanded when it exactly matches the query.
+
+If you add an '@' prefix while inputting a shortcut, it matches any position in the query. Builtin shortcuts match any position in a query.
+
+ Shortcut already exists, please enter a new Shortcut or edit the existing one.
+ Shortcut and/or its expansion is empty.
+
+
+ שמור
+ Overwrite
+ ביטול
+ Reset
+ מחק
+ OK
+ Yes
+ No
+
+
+ Version
+ זמן
+ Please tell us how application crashed so we can fix it
+ שלח דיווח
+ ביטול
+ כללי
+ חריגים
+ Exception Type
+ Source
+ Stack Trace
+ Sending
+ Report sent successfully
+ Failed to send report
+ Flow Launcher got an error
+
+
+ Please wait...
+
+
+ Checking for new update
+ You already have the latest Flow Launcher version
+ Update found
+ Updating...
+
+ Flow Launcher was not able to move your user profile data to the new update version.
+ Please manually move your profile data folder from {0} to {1}
+
+ עדכון חדש
+ New Flow Launcher release {0} is now available
+ An error occurred while trying to install software updates
+ עדכון
+ ביטול
+ העדכון נכשל
+ Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.
+ This upgrade will restart Flow Launcher
+ Following files will be updated
+ Update files
+ Update description
+
+
+ דלג
+ Welcome to Flow Launcher
+ Hello, this is the first time you are running Flow Launcher!
+ Before starting, this wizard will assist in setting up Flow Launcher. You can skip this if you wish. Please choose a language
+ Search and run all files and applications on your PC
+ Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
+ Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.
+ Hotkeys
+ Action Keyword and Commands
+ Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.
+ Let's Start Flow Launcher
+ Finished. Enjoy Flow Launcher. Don't forget the hotkey to start :)
+
+
+
+ Back / Context Menu
+ Item Navigation
+ Open Context Menu
+ Open Containing Folder
+ Run as Admin / Open Folder in Default File Manager
+ Query History
+ Back to Result in Context Menu
+ Autocomplete
+ Open / Run Selected Item
+ Open Setting Window
+ Reload Plugin Data
+
+ Select first result
+ Select last result
+ Run current query again
+ Open result
+ Open result #{0}
+
+ Weather
+ Weather in Google Result
+ > ping 8.8.8.8
+ Shell Command
+ s Bluetooth
+ Bluetooth in Windows Settings
+ sn
+ Sticky Notes
+
+
+ File Size
+ Created
+ Last Modified
+
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index ddb1d5555e0..372f4630ef5 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -65,6 +65,8 @@
Conserva ultima ricerca
Seleziona ultima ricerca
Cancella ultima ricerca
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Altezza Finestra Fissa
L'altezza della finestra non si può regolare trascinando.
Numero massimo di risultati mostrati
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index 962b68017f5..e7671367a3f 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -65,6 +65,8 @@
前回のクエリを保存
前回のクエリを選択
前回のクエリを消去
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
結果の最大表示件数
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index 81dae917915..67bf2490ab7 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -65,6 +65,8 @@
직전 쿼리에 계속 입력
직전 쿼리 내용 선택
직전 쿼리 지우기
+ Preserve Last Action Keyword
+ Select Last Action Keyword
창 높이 고정
드래그로 창 높이를 조정하지 않습니다.
표시할 결과 수
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index b608f5c0bf2..e3b8e36da2a 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -65,6 +65,8 @@
Bevar siste spørring
Velg siste spørring
Tøm siste spørring
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fast vindushøyde
Vindushøyden kan ikke justeres ved å dra.
Maksimalt antall resultater vist
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index d5bd0f284f9..db440c3a057 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -65,6 +65,8 @@
Behoud laatste zoekopdracht
Selecteer laatste zoekopdracht
Laatste zoekopdracht verwijderen
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Vaste venster hoogte
De vensterhoogte is niet aanpasbaar door te slepen.
Laat maximale resultaten zien
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 7aa0d64b275..df7c9d2d4ec 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -65,6 +65,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Zachowaj ostatnie zapytanie
Wybierz ostatnie zapytanie
Puste ostatnie zapytanie
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Stała wysokość okna
Wysokość okna nie jest regulowana poprzez przeciąganie.
Maksymalna liczba wyników
@@ -361,7 +363,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
Nadpisz
Anuluj
Zresetuj
- Usu
+ Usuń
Aktualizuj
Tak
Nie
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index 6f6bb4df870..4a30ffda4c2 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -65,6 +65,8 @@
Preservar Última Consulta
Selecionar última consulta
Limpar última consulta
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index 9f316220d84..470bf2b4e4e 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -65,6 +65,8 @@ Clique "Não" se já tiver instalado e, de seguida, ser-lhe-á solicit
Manter última consulta
Selecionar última consulta
Limpar última consulta
+ Manter palavra-chave da última ação
+ Selecionar palavra-chave da última ação
Altura fixa de janela
Não é possível ajustar o tamanho da janela por arrasto.
Número máximo de resultados
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index f501fd63819..1c420100f23 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -1,12 +1,13 @@
+
- Flow определил, что вы установили {0} плагины, которым требуется {1} для работы. Скачать {1}?
+ Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
{2}{2}
- Кликните нет, если он уже установлен, и вам будет предложено выбрать папку, где находится исполняемый файл {1}
+ Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
- Пожалуйста, выберите исполняемый файл {0}
- Не удалось установить путь к исполняемому файлу {0}, пожалуйста, попробуйте через настройки Flow (прокрутите вниз).
+ Please select the {0} executable
+ Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -64,6 +65,8 @@
Сохранение последнего запроса
Выбор последнего запроса
Очистить последний запрос
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Фиксированная высота окна
The window height is not adjustable by dragging.
Максимальное количество результатов
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index f91fd596d52..3db778cc8f2 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -65,6 +65,8 @@
Ponechať
Označiť
Vymazať
+ Ponechať posledný akčný príkaz
+ Označiť posledný akčný príkaz
Pevná výška okna
Výška okna sa nedá nastaviť ťahaním.
Maximum výsledkov
@@ -454,4 +456,3 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s
Vytvorené
Upravené
-
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index af32a5cfe45..fc5a1e2fc8a 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -65,6 +65,8 @@
Sačuvaj poslednji Upit
Selektuj poslednji Upit
Isprazni poslednji Upit
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
Maksimum prikazanih rezultata
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index ecca292d979..cfb3689c39c 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -65,6 +65,8 @@
Son Sorguyu Sakla
Son Sorguyu Sakla ve Tümünü Seç
Sorgu Kutusunu Temizle
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Sabit Pencere Yükseliği
Pencere yüksekliği sürükleme ile ayarlanamaz.
Maksimum Sonuç Sayısı
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index f74efa48bc3..09c576150b5 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -65,6 +65,8 @@
Зберегти останній запит
Вибрати останній запит
Очистити останній запит
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Фіксована висота вікна
Висота вікна не регулюється перетягуванням.
Максимальна кількість результатів
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index 802d4b06c3b..31e8ad2aaf6 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -65,6 +65,8 @@
Giữ lại truy vấn cuối cùng
Chọn truy vấn cuối cùng
Trống truy vấn cuối cùng
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Giữ nguyên chiều cao cửa sổ
Chiều cao cửa sổ không thể thay đổi bằng cách kéo.
Số kết quả tối đa
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 3a8217f5977..681c715fb03 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -65,6 +65,8 @@
保留上次搜索关键字
选择上次搜索关键字
清空上次搜索关键字
+ Preserve Last Action Keyword
+ Select Last Action Keyword
固定窗口高度
窗口高度不能通过拖动来调整。
最大结果显示个数
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 3cdf0a7b425..44be5257bb2 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -65,6 +65,8 @@
保留上一個查詢
選擇上一個查詢
清空上次搜尋關鍵字
+ Preserve Last Action Keyword
+ Select Last Action Keyword
Fixed Window Height
The window height is not adjustable by dragging.
最大結果顯示個數
diff --git a/Flow.Launcher/Properties/Resources.he-IL.resx b/Flow.Launcher/Properties/Resources.he-IL.resx
new file mode 100644
index 00000000000..ca0f66f533b
--- /dev/null
+++ b/Flow.Launcher/Properties/Resources.he-IL.resx
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\app.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Images\dev.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Images\gamemode.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
index c5d371c6c42..4d1ad4bf108 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/de.xaml
@@ -16,7 +16,7 @@
URL des Lesezeichens in Zwischenablage kopieren
Browser laden aus:
Browser-Name
- URL des Lesezeichens in Zwischenablage kopieren
+ Pfad zu Datenverzeichnis
Hinzufügen
Bearbeiten
Löschen
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
index b80e4f926b5..db87ee2810e 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/es.xaml
@@ -23,6 +23,6 @@
Navegar
Otros
Motor del navegador
- Si no está utilizando Chrome, Firefox o Edge, o si está utilizando su versión portátil, debe añadir el directorio de datos de los marcadores y seleccionar el motor del navegador correcto para que este complemento funcione.
+ Si no está utilizando Chrome, Firefox o Edge, o si está utilizando su versión portable, debe añadir el directorio de datos de los marcadores y seleccionar el motor del navegador correcto para que este complemento funcione.
Por ejemplo: El motor de Brave es Chromium; y la ubicación por defecto de los datos de los marcadores es: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Para el motor de Firefox, el directorio de los marcadores es la carpeta de datos del usuario que contiene el archivo places.sqlite.
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
new file mode 100644
index 00000000000..7c6f73ed794
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/he.xaml
@@ -0,0 +1,28 @@
+
+
+
+
+ Browser Bookmarks
+ Search your browser bookmarks
+
+
+ Bookmark Data
+ Open bookmarks in:
+ New window
+ New tab
+ Set browser from path:
+ Choose
+ Copy url
+ Copy the bookmark's url to clipboard
+ Load Browser From:
+ Browser Name
+ Data Directory Path
+ הוסף
+ ערוך
+ מחק
+ Browse
+ Others
+ Browser Engine
+ If you are not using Chrome, Firefox or Edge, or you are using their portable version, you need to add bookmarks data directory and select correct browser engine to make this plugin work.
+ For example: Brave's engine is Chromium; and its default bookmarks data location is: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". For Firefox engine, the bookmarks directory is the userdata folder contains the places.sqlite file.
+
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
index 47bcaacc9e2..d8da714dcff 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/de.xaml
@@ -2,8 +2,8 @@
Rechner
- Ermöglicht mathematische Berechnungen (z. B. 5*3-2 in Flow Launcher)
- Nicht eine Zahl (NaN)
+ Ermöglicht mathematische Berechnungen. (Versuchen Sie 5*3-2 in Flow Launcher)
+ Nicht eine Zahl (NaN)
Ausdruck falsch oder unvollständig (Haben Sie einige Klammern vergessen?)
Diese Zahl in die Zwischenablage kopieren
Dezimaltrennzeichen
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
new file mode 100644
index 00000000000..15598118cbc
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/he.xaml
@@ -0,0 +1,15 @@
+
+
+
+ Calculator
+ Allows to do mathematical calculations.(Try 5*3-2 in Flow Launcher)
+ Not a number (NaN)
+ Expression wrong or incomplete (Did you forget some parentheses?)
+ Copy this number to the clipboard
+ Decimal separator
+ The decimal separator to be used in the output.
+ Use system locale
+ Comma (,)
+ Dot (.)
+ Max. decimal places
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
index e3862df761b..f2df655c729 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/de.xaml
@@ -2,7 +2,7 @@
- Bitte treffen Sie zuerst eine Auswahl.
+ Bitte treffen Sie zuerst eine Auswahl
Bitte wählen Sie einen Ordner-Link aus
Sind Sie sicher, dass Sie {0} löschen wollen?
Sind Sie sicher, dass Sie diese Datei dauerhaft löschen möchten?
@@ -40,8 +40,8 @@
Shell-Pfad
Indexsuche ausgeschlossene Pfade
Ort des Suchergebnisses als Arbeitsverzeichnis der ausführbaren Datei verwenden
- Drücken Sie die Enter, um den Ordner im Default-Dateimanager zu öffnen
- Use Index Search For Path Search
+ Drücken Sie Enter, um Ordner im Default-Dateimanager zu öffnen
+ Indexsuche für Pfadsuche verwenden
Indexierungsoptionen
Suche:
Pfad-Suche:
@@ -60,10 +60,10 @@
Aktiviert
Deaktiviert
- Content Search Engine
- Directory Recursive Search Engine
- Index Search Engine
- Open Windows Index Option
+ Content-Suchmaschine
+ Verzeichnis Rekursive Suchmaschine
+ Suchmaschine indizieren
+ Windows-Indexierungsoptionen öffnen
Ausgeschlossene Dateitypen (durch Komma getrennt)
Zum Beispiel: exe,jpg,png
Maximale Ergebnisse
@@ -131,12 +131,12 @@
Pfad
Größe
Extension
- Type Name
+ Typname
Erstellungsdatum
Änderungsdatum
Attribute
- File List FileName
- Run Count
+ Dateilistenname
+ Ausführungszahl
Datum kürzlich geändert
Zugriffsdatum
Ausführungsdatum
@@ -145,7 +145,7 @@
Warnung: Dies ist keine Schnellsortieroption, Suchen können langsam sein
Vollständigen Pfad suchen
- Enable File/Folder Run Count
+ Datei-/Ordnerlaufzähler aktivieren
Klicken, um Everything zu starten oder zu installieren
Everything-Installation
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
new file mode 100644
index 00000000000..0e1753d6745
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -0,0 +1,165 @@
+
+
+
+
+ Please make a selection first
+ Please select a folder link
+ Are you sure you want to delete {0}?
+ Are you sure you want to permanently delete this file?
+ Are you sure you want to permanently delete this file/folder?
+ Deletion successful
+ Successfully deleted {0}
+ Assigning the global action keyword could bring up too many results during search. Please choose a specific action keyword
+ Quick Access can not be set to the global action keyword when enabled. Please choose a specific action keyword
+ The required service for Windows Index Search does not appear to be running
+ To fix this, start the Windows Search service. Select here to remove this warning
+ The warning message has been switched off. As an alternative for searching files and folders, would you like to install Everything plugin?{0}{0}Select 'Yes' to install Everything plugin, or 'No' to return
+ Explorer Alternative
+ Error occurred during search: {0}
+ Could not open folder
+ Could not open file
+
+
+ מחק
+ ערוך
+ הוסף
+ General Setting
+ Customise Action Keywords
+ Quick Access Links
+ Everything Setting
+ Preview Panel
+ Size
+ Date Created
+ Date Modified
+ Display File Info
+ Date and time format
+ Sort Option:
+ Everything Path:
+ Launch Hidden
+ Editor Path
+ Shell Path
+ Index Search Excluded Paths
+ Use search result's location as the working directory of the executable
+ Hit Enter to open folder in Default File Manager
+ Use Index Search For Path Search
+ Indexing Options
+ Search:
+ Path Search:
+ File Content Search:
+ Index Search:
+ Quick Access:
+ Current Action Keyword
+ בוצע
+ Enabled
+ When disabled Flow will not execute this search option, and will additionally revert back to '*' to free up the action keyword
+ Everything
+ Windows Index
+ Direct Enumeration
+ File Editor Path
+ Folder Editor Path
+ Enabled
+ Disabled
+
+ Content Search Engine
+ Directory Recursive Search Engine
+ Index Search Engine
+ Open Windows Index Option
+ Excluded File Types (comma seperated)
+ For example: exe,jpg,png
+ Maximum results
+ The maximum number of results requested from active search engine
+
+
+ Explorer
+ Find and manage files and folders via Windows Search or Everything
+
+
+ Ctrl + Enter to open the directory
+ Ctrl + Enter to open the containing folder
+
+
+ Copy path
+ Copy path of current item to clipboard
+ Copy
+ Copy current file to clipboard
+ Copy current folder to clipboard
+ מחק
+ Permanently delete current file
+ Permanently delete current folder
+ Path:
+ Delete the selected
+ Run as different user
+ Run the selected using a different user account
+ Open containing folder
+ Open the location that contains current item
+ Open With Editor:
+ Failed to open file at {0} with Editor {1} at {2}
+ Open With Shell:
+ Failed to open folder {0} with Shell {1} at {2}
+ Exclude current and sub-directories from Index Search
+ Excluded from Index Search
+ Open Windows Indexing Options
+ Manage indexed files and folders
+ Failed to open Windows Indexing Options
+ Add to Quick Access
+ Add current item to Quick Access
+ Successfully Added
+ Successfully added to Quick Access
+ Successfully Removed
+ Successfully removed from Quick Access
+ Add to Quick Access so it can be opened with Explorer's Search Activation action keyword
+ Remove from Quick Access
+ Remove from Quick Access
+ Remove current item from Quick Access
+ Show Windows Context Menu
+ Open With
+ Select a program to open with
+
+
+ {0} free of {1}
+ Open in Default File Manager
+
+ Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.
+
+
+
+ Failed to load Everything SDK
+ אזהרה: שירות Everything אינו פועל
+ שגיאה במהלך שאילתה לEverything
+ Sort By
+ Name
+ Path
+ Size
+ Extension
+ Type Name
+ Date Created
+ Date Modified
+ Attributes
+ File List FileName
+ Run Count
+ Date Recently Changed
+ Date Accessed
+ Date Run
+ ↑
+ ↓
+ Warning: This is not a Fast Sort option, searches may be slow
+
+ Search Full Path
+ Enable File/Folder Run Count
+
+ Click to launch or install Everything
+ Everything Installation
+ Installing Everything service. Please wait...
+ Successfully installed Everything service
+ Failed to automatically install Everything service. Please manually install it from https://www.voidtools.com
+ Click here to start it
+ Unable to find an Everything installation, would you like to manually select a location?{0}{0}Click no and Everything will be automatically installed for you
+ Do you want to enable content search for Everything?
+ It can be very slow without index (which is only supported in Everything v1.5+)
+
+
+ Native Context Menu
+ Display native context menu (experimental)
+ Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').
+ Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
index 38b9c29c65a..911364fdff5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ru.xaml
@@ -43,7 +43,7 @@
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
- Search:
+ Поиск:
Path Search:
File Content Search:
Index Search:
@@ -78,17 +78,17 @@
Ctrl + Enter to open the containing folder
- Copy path
+ Скопировать путь
Copy path of current item to clipboard
- Copy
+ Скопировать
Copy current file to clipboard
Copy current folder to clipboard
Удалить
Permanently delete current file
Permanently delete current folder
- Path:
+ Путь:
Delete the selected
- Run as different user
+ Запустить от имени другого пользователя
Run the selected using a different user account
Open containing folder
Open the location that contains current item
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
index 50d3b01ed20..f39f4d4be5b 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/de.xaml
@@ -1,9 +1,9 @@
- Plug-in-Aktions-Schlüsselwort {0} aktivieren
+ Aktions-Schlüsselwort für Plug-in {0} aktivieren
Plug-in-Indikator
- Bietet Vorschläge für Aktionswörter für Plug-ins
+ Bietet Vorschläge für Aktions-Schlüsselwörter für Plug-ins
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
new file mode 100644
index 00000000000..893948d3dcc
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/he.xaml
@@ -0,0 +1,9 @@
+
+
+
+ Activate {0} plugin action keyword
+
+ Plugin Indicator
+ Provides plugins action words suggestions
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
new file mode 100644
index 00000000000..e13a857a164
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/he.xaml
@@ -0,0 +1,63 @@
+
+
+
+
+ Downloading plugin
+ Successfully downloaded {0}
+ Error: Unable to download the plugin
+ {0} by {1} {2}{3}Would you like to uninstall this plugin? After the uninstallation Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to uninstall this plugin?
+ {0} by {1} {2}{3}Would you like to install this plugin? After the installation Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to install this plugin?
+ Plugin Install
+ Installing Plugin
+ Download and install {0}
+ Plugin Uninstall
+ Plugin {0} successfully installed. Restarting Flow, please wait...
+ Unable to find the plugin.json metadata file from the extracted zip file.
+ Error: A plugin which has the same or greater version with {0} already exists.
+ Error installing plugin
+ Error occurred while trying to install {0}
+ Error uninstalling plugin
+ No update available
+ All plugins are up to date
+ {0} by {1} {2}{3}Would you like to update this plugin? After the update Flow will automatically restart.
+ {0} by {1} {2}{2}Would you like to update this plugin?
+ Plugin Update
+ This plugin is already installed
+ Plugin Manifest Download Failed
+ Please check if you can connect to github.com. This error means you may not be able to install or update plugins.
+ Update all plugins
+ Would you like to update all plugins?
+ Would you like to update {0} plugins?{1}Flow Launcher will restart after updating all plugins.
+ Would you like to update {0} plugins?
+ {0} plugins successfully updated. Restarting Flow, please wait...
+ Plugin {0} successfully updated. Restarting Flow, please wait...
+ Installing from an unknown source
+ You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
+
+ Plugin {0} successfully installed. Please restart Flow.
+ Plugin {0} successfully uninstalled. Please restart Flow.
+ Plugin {0} successfully updated. Please restart Flow.
+ {0} plugins successfully updated. Please restart Flow.
+ Plugin {0} has already been modified. Please restart Flow before making any further changes.
+
+
+ Plugins Manager
+ Management of installing, uninstalling or updating Flow Launcher plugins
+ Unknown Author
+
+
+ Open website
+ Visit the plugin's website
+ See source code
+ See the plugin's source code
+ Suggest an enhancement or submit an issue
+ Suggest an enhancement or submit an issue to the plugin developer
+ Go to Flow's plugins repository
+ Visit the PluginsManifest repository to see community-made plugin submissions
+
+
+ Install from unknown source warning
+ Automatically restart Flow Launcher after installing/uninstalling/updating plugins
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
index b3429f7af86..8697818dc89 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
@@ -1,11 +1,11 @@
- Prozesskiller
- Beende laufende Prozesse durch Flow Launcher
+ Process Killer
+ Laufende Prozesse aus Flow Launcher beenden
- alle Instanzen von "{0} " beenden
- beende {0} Prozesse
- alle Instanzen beenden
+ Alle Instanzen von "{0}" beenden
+ {0} Prozesse beenden
+ Alle Instanzen beenden
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
new file mode 100644
index 00000000000..c4cc8546346
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
@@ -0,0 +1,11 @@
+
+
+
+ Process Killer
+ Kill running processes from Flow Launcher
+
+ kill all instances of "{0}"
+ kill {0} processes
+ kill all instances
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
index 81f2b7c7bc9..7923024ab47 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
@@ -31,7 +31,7 @@
App-Pfad ausblenden
Für ausführbare Dateien wie UWP oder lnk den Dateipfad nicht mehr sichtbar machen
Uninstaller ausblenden
- Versteckt Programme mit gängigen Uninstaller-Namen, wie unins000.exe
+ Blendet Programme mit gängigen Uninstaller-Namen aus, wie unins000.exe
In Programmbeschreibung suchen
Flow wird in Programmbeschreibung suchen
Suffixe
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
index 3adc1fd3385..b67a1a7271a 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
@@ -75,7 +75,7 @@
Masquer ce programme des résultats
Ouvrir le répertoire cible
- Programme
+ Programmes
Rechercher des programmes dans Flow Launcher
Chemin d'accès invalide
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
new file mode 100644
index 00000000000..69b9324dce8
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
@@ -0,0 +1,95 @@
+
+
+
+
+ Reset Default
+ מחק
+ ערוך
+ הוסף
+ Name
+ Enable
+ Enabled
+ Disable
+ Status
+ Enabled
+ Disabled
+ Location
+ All Programs
+ File Type
+ Reindex
+ Indexing
+ Index Sources
+ Options
+ UWP Apps
+ When enabled, Flow will load UWP Applications
+ Start Menu
+ When enabled, Flow will load programs from the start menu
+ Registry
+ When enabled, Flow will load programs from the registry
+ PATH
+ When enabled, Flow will load programs from the PATH environment variable
+ Hide app path
+ For executable files such as UWP or lnk, hide the file path from being visible
+ Hide uninstallers
+ Hides programs with common uninstaller names, such as unins000.exe
+ Search in Program Description
+ Flow will search program's description
+ Suffixes
+ Max Depth
+
+ Directory
+ Browse
+ File Suffixes:
+ Maximum Search Depth (-1 is unlimited):
+
+ Please select a program source
+ Are you sure you want to delete the selected program sources?
+ Another program source with the same location already exists.
+
+ Program Source
+ Edit directory and status of this program source.
+
+ עדכון
+ Program Plugin will only index files with selected suffixes and .url files with selected protocols.
+ Successfully updated file suffixes
+ File suffixes can't be empty
+ Protocols can't be empty
+
+ File Suffixes
+ URL Protocols
+ Steam Games
+ Epic Games
+ Http/Https
+ Custom URL Protocols
+ Custom File Suffixes
+
+ Insert file suffixes you want to index. Suffixes should be separated by ';'. (ex>bat;py)
+
+
+ Insert protocols of .url files you want to index. Protocols should be separated by ';', and should end with "://". (ex>ftp://;mailto://)
+
+
+ Run As Different User
+ Run As Administrator
+ Open containing folder
+ Disable this program from displaying
+ Open target folder
+
+ Program
+ Search programs in Flow Launcher
+
+ Invalid Path
+
+ Customized Explorer
+ Args
+ You can customize the explorer used for opening the container folder by inputing the Environmental Variable of the explorer you want to use. It will be useful to use CMD to test whether the Environmental Variable is available.
+ Enter the customized args you want to add for your customized explorer. %s for parent directory, %f for full path (which only works for win32). Check the explorer's website for details.
+
+
+ הצליח
+ Error
+ Successfully disabled this program from displaying in your query
+ This app is not intended to be run as administrator
+ Unable to run {0}
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
new file mode 100644
index 00000000000..b7d02c5586c
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/he.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Replace Win+R
+ Close Command Prompt after pressing any key
+ Press any key to close this window...
+ Do not close Command Prompt after command execution
+ Always run as administrator
+ Run as different user
+ Shell
+ Allows to execute system commands from Flow Launcher
+ this command has been executed {0} times
+ execute command through command shell
+ Run As Administrator
+ Copy the command
+ Only show number of most used commands:
+
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
index bf3864c7bbd..20fc3fb5df7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ru.xaml
@@ -6,7 +6,7 @@
Press any key to close this window...
Не закрывать командную строку после выполнения команды
Всегда запускать с правами администратора
- Run as different user
+ Запустить от имени другого пользователя
Оболочка
Allows to execute system commands from Flow Launcher
эта команда была выполнена {0} раз
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
index cb8b00f52c9..5a517083816 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
@@ -46,7 +46,7 @@
Busca actualizaciones de Flow Launcher
Accede a la documentación de Flow Launcher para más ayuda y consejos de uso
Abre la ubicación donde se almacena la configuración de Flow Launcher
- Cambia a Modo Juego
+ Cambiar a Modo Juego
Correcto
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
new file mode 100644
index 00000000000..b98fc47ee1b
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
@@ -0,0 +1,63 @@
+
+
+
+
+ Command
+ Description
+
+ Shutdown
+ Restart
+ Restart With Advanced Boot Options
+ Log Off/Sign Out
+ Lock
+ Sleep
+ Hibernate
+ Index Option
+ Empty Recycle Bin
+ Open Recycle Bin
+ יציאה
+ Save Settings
+ Restart Flow Launcher
+ הגדרות
+ Reload Plugin Data
+ Check For Update
+ Open Log Location
+ Flow Launcher Tips
+ Flow Launcher UserData Folder
+ Toggle Game Mode
+
+
+ Shutdown Computer
+ Restart Computer
+ Restart the computer with Advanced Boot Options for Safe and Debugging modes, as well as other options
+ Log off
+ Lock this computer
+ Close Flow Launcher
+ Restart Flow Launcher
+ Tweak Flow Launcher's settings
+ Put computer to sleep
+ Empty recycle bin
+ Open recycle bin
+ Indexing Options
+ Hibernate computer
+ Save all Flow Launcher settings
+ Refreshes plugin data with new content
+ Open Flow Launcher's log location
+ Check for new Flow Launcher update
+ Visit Flow Launcher's documentation for more help and how to use tips
+ Open the location where Flow Launcher's settings are stored
+ Toggle Game Mode
+
+
+ הצליח
+ All Flow Launcher settings saved
+ Reloaded all applicable plugin data
+ Are you sure you want to shut the computer down?
+ Are you sure you want to restart the computer?
+ Are you sure you want to restart the computer with Advanced Boot Options?
+ Are you sure you want to log off?
+
+ System Commands
+ Provides System related commands. e.g. shutdown, lock, settings etc.
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
index 9ae4c17dfcd..ee13754d5cd 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Url/Languages/de.xaml
@@ -5,13 +5,13 @@
Neues Fenster
Neuer Tab
- Öffne URL:{0}
- Kann URL nicht öffnen:{0}
+ URL öffnen: {0}
+ URL kann nicht geöffnet werden: {0}
URL
- Öffne eine eingegebene URL mit Flow Launcher
+ Öffnen Sie die eingetippte URL in Flow Launcher
Bitte legen Sie Ihren Browser-Pfad fest:
- Auswählen
- URL öffnen: {0}
+ Wählen
+ Anwendung (*.exe)|*.exe|Alle Dateien|*.*
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
new file mode 100644
index 00000000000..4187310217a
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Url/Languages/he.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Open search in:
+ New Window
+ New Tab
+
+ Open url:{0}
+ Can't open url:{0}
+
+ URL
+ Open the typed URL from Flow Launcher
+
+ Please set your browser path:
+ Choose
+ Application(*.exe)|*.exe|All files|*.*
+
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
index 623a5d5fb3f..6e92178db97 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
@@ -29,7 +29,8 @@
وبالتالي، فإن الصيغة العامة للبحث على نتفليكس هي https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
العنوان
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
index e9f59929ba8..849f27f0522 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
@@ -29,7 +29,8 @@
Obecný vzorec pro vyhledávání Netflixu je tedy https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Název
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
index 096abc5f10d..2a7d4aa328b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
index 15788acaa0b..0c72b11bf99 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
@@ -6,7 +6,7 @@
Neues Fenster
Neuer Tab
Browser aus Pfad festlegen:
- Auswählen
+ Wählen
Löschen
Bearbeiten
Hinzufügen
@@ -19,7 +19,7 @@
Suche
Autovervollständigung von Suchanfragen verwenden:
Daten automatisch vervollständigen aus:
- Bitte wähle einen Suchdienst
+ Bitte wählen Sie eine Websuche aus
Sind Sie sicher, dass Sie {0} löschen wollen?
Wenn Sie Flow eine Suche nach einer bestimmten Website hinzufügen möchten, geben Sie zunächst eine Dummy-Textzeichenfolge in die Suchleiste dieser Website ein und starten Sie die Suche. Kopieren Sie jetzt den Inhalt der Adressleiste des Browsers und fügen Sie ihn in das URL-Feld unten ein. Ersetzen Sie Ihre Testzeichenfolge durch {q}. Zum Beispiel, wenn Sie auf Netflix nach casino suchen, steht in der Adressleiste
https://www.netflix.com/search?q=Casino
@@ -30,23 +30,24 @@
https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Titel
Status
- Wähle Symbol
- Symbol
+ Icon auswählen
+ Icon
Abbrechen
- Ungültige Internetsuche
- Bitte Titel eingeben
- Aktions-Schlüsselwort ist bereits vorhanden. Bitte geben Sie ein anderes ein.
- Bitte URL eingeben
- Aktionsschlüsselwort existiert bereits. Bitte gebe ein anderes ein.
+ Ungültige Websuche
+ Bitte geben Sie einen Titel ein
+ Bitte geben Sie ein Aktions-Schlüsselwort ein
+ Bitte geben Sie eine URL ein
+ Aktions-Schlüsselwort ist bereits vorhanden. Bitte geben Sie ein anderes ein
Erfolg
Hinweis: Sie müssen keine benutzerdefinierten Bilder in diesem Verzeichnis ablegen, wenn die Version von Flow aktualisiert wird, gehen diese verloren. Flow kopiert automatisch jegliche Bilder außerhalb dieses Verzeichnisses herüber in den benutzerdefinierten Bildspeicherort von WebSearch.
- Internetsuche
+ Web-Suchen
Ermöglicht die Durchführung von Web-Suchen
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
index 6e992b94406..517ac0918e2 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
index bb78d36b0b7..e6e4a94d2cb 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
@@ -29,7 +29,8 @@
De esta manera, la fórmula genérica para una búsqueda en Netflix será https://www.netflix.com/search?q={q}
-
+ Copiar URL
+ Copiar URL de búsqueda al portapapeles
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
index f5988733e87..c6b1b145cdf 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
@@ -29,7 +29,8 @@
Ainsi, la formule générique pour une recherche Netflix est https://www.netflix.com/search?q={q}
-
+ Copier l'URL
+ Copier l'URL de la recherche dans le presse-papiers
Titre
@@ -45,7 +46,7 @@
Ajout
Astuce : Vous n'avez pas besoin de placer des images personnalisées dans ce dossier, si la version de Flow est mise à jour, elles seront perdues. Flow copiera automatiquement toutes les images en dehors de ce dossier dans l'emplacement de l'image personnalisée de la Recherche Web.
- Recherches Web
+ Recherches web
Permet d'effectuer des recherches web
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
new file mode 100644
index 00000000000..820bb141bfe
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
@@ -0,0 +1,52 @@
+
+
+
+ Search Source Setting
+ Open search in:
+ New Window
+ New Tab
+ Set browser from path:
+ Choose
+ מחק
+ ערוך
+ הוסף
+ Enabled
+ Enabled
+ Disabled
+ Confirm
+ Action Keyword
+ URL
+ Search
+ Use Search Query Autocomplete:
+ Autocomplete Data from:
+ Please select a web search
+ Are you sure you want to delete {0}?
+ If you want to add a search for a particular website to Flow, first enter a dummy text string in the search bar of that website, and launch the search. Now copy the contents of the browser's address bar, and paste it in the URL field below. Replace your test string with {q}. For example, if you search for casino on Netflix, its address bar reads
+ https://www.netflix.com/search?q=Casino
+
+ Now copy this entire string and paste it in the URL field below.
+ Then replace casino with {q}.
+ Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
+
+
+ Copy URL
+ Copy search URL to clipboard
+
+
+ Title
+ Status
+ Select Icon
+ Icon
+ ביטול
+ Invalid web search
+ Please enter a title
+ Please enter an action keyword
+ Please enter a URL
+ Action keyword already exists, please enter a different one
+ הצליח
+ Hint: You do not need to place custom images in this directory, if Flow's version is updated they will be lost. Flow will automatically copy any images outside of this directory across to WebSearch's custom image location.
+
+ Web Searches
+ Allows to perform web searches
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
index dc9bd7a2ee6..26c1e845945 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
@@ -29,7 +29,8 @@
Così la formula generica per una ricerca su Netflix è https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Titolo
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
index b5d4df43067..85ce0e28232 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
タイトル
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
index 1f43e20c29a..5ab5fffa3d9 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
이름
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
index b84daeb8797..4bba382a9b6 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
@@ -29,7 +29,8 @@
dvs. den generiske formelen for et søk på Netflix er https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tittel
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
index fb6fd435322..a48d9948715 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ URL kopiëren
+ Zoek-URL kopiëren naar klembord
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
index 1c426ee08cb..4f702d4a770 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
@@ -29,7 +29,8 @@
W ten sposób ogólna formuła wyszukiwania na Netflix to https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tytuł
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
index b2dedeb609a..d4135c79529 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
index 56d65e84938..16969dac70d 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
@@ -29,7 +29,8 @@
Assim, a fórmula genérica de uma pesquisa na Netflix é https://www.netflix.com/search?q={q}
-
+ Copiar URL
+ Copiar URL para a área de transferência
Título
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
index b8757f67b1a..ea163da7caf 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
@@ -28,7 +28,6 @@
Then replace casino with {q}.
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
Скопировать URL-адрес
Скопировать URL поиска в буфер обмена
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
index e23d12a16f3..44b765c58cb 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
@@ -29,7 +29,8 @@
Všeobecný vzorec pre vyhľadávanie na Netflix je teda https://www.netflix.com/search?q={q}
-
+ Kopírovať URL
+ Kopírovať URL vyhľadávanie do schránky
Názov
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
index 54ee243764d..5f180365581 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
index 05f3de09557..1506b753bae 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Başlık
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
index 87419023bfd..beb085d28ba 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
@@ -29,7 +29,8 @@
Таким чином, загальна формула для пошуку на Netflix має вигляд https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Назва
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
index a6de788b599..e3105283fad 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
Tiêu đề
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
index cd05cf7b8f2..d3df223cc71 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
@@ -29,7 +29,8 @@
那么 Netflix 搜索的表达式就是 https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
标题
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
index d50d658672a..eb58a4ec0ab 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
@@ -29,7 +29,8 @@
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
-
+ Copy URL
+ Copy search URL to clipboard
標題
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
index a716ef4c635..dac5f82bca3 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
@@ -126,7 +126,7 @@
File name, Should not translated
- Barrierefreiheitsoptionen
+ Optionen für Barrierefreiheit
Area Control Panel (legacy settings)
@@ -296,7 +296,7 @@
Programme
- SurfaceHub
+ Oberflächenhub
System
@@ -424,11 +424,11 @@
Mean the "Caps Lock" key
- Mobilfunknetz und SIM-Karte
+ Mobilfunk und SIM
Area NetworkAndInternet
- Wählen Sie aus, welche Ordner im Startmenü angezeigt werden
+ Wählen Sie, welche Ordner im Start erscheinen
Area Personalization
@@ -547,7 +547,7 @@
Area Control Panel (legacy settings)
- deuteranopia
+ Farbenfehlsichtigkeit
Medical: Mean you don't can see red colors
@@ -654,7 +654,7 @@
Area Privacy
- FindFast
+ Schnell finden
Area Control Panel (legacy settings)
@@ -697,7 +697,7 @@
Area Control Panel (legacy settings)
- Game DVR
+ DVR
Area Gaming
@@ -865,7 +865,7 @@
Area Apps
- Messaging
+ Nachrichten
Area Privacy
@@ -876,7 +876,7 @@
Area Privacy
- Microsoft Mail Post Office
+ Microsoft Mail Post
Area Control Panel (legacy settings)
@@ -1251,7 +1251,7 @@
Area System
- protanopia
+ Protanopie
Medical: Mean you don't can see green colors
@@ -1332,7 +1332,7 @@
Area Control Panel (legacy settings)
- schedtasks
+ sedtasks
File name, Should not translated
@@ -1412,7 +1412,7 @@
Area System
- Speech
+ Sprache
Area EaseOfAccess
@@ -1544,7 +1544,7 @@
Transparenz
- tritanopia
+ Farbenblindheit (Blau)
Medical: Mean you don't can see yellow and blue colors
@@ -1552,7 +1552,7 @@
Area UpdateAndSecurity
- TruePlay
+ TruePlaying
Area Gaming
@@ -2064,7 +2064,7 @@
Microsoft ChangJie-Einstellungen
- Replace sounds with visual cues
+ Sounds durch visuelle Hinweise ersetzen
Temporäre Internet-Dateieinstellungen ändern
@@ -2079,7 +2079,7 @@
Change the mouse pointer display or speed
- Back up your recovery key
+ Ihren Wiederherstellungsschlüssel sichern
Save backup copies of your files with File History
@@ -2133,7 +2133,7 @@
Change power-saving settings
- Optimise for blindness
+ Optimieren für Blindheit
@@ -2155,7 +2155,7 @@
Ihre Offline-Dateien verschlüsseln
- Train the computer to recognise your voice
+ Trainieren Sie den Computer, Ihre Stimme zu erkennen
Erweiterte Druckereinrichtung
@@ -2461,10 +2461,10 @@
Set your default programs
- Set up a broadband connection
+ Eine Breitbandverbindung einrichten
- Calibrate the screen for pen or touch input
+ Kalibrieren des Screens für Stift- oder Toucheingabe
Benutzerzertifikate verwalten
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
new file mode 100644
index 00000000000..2b6d5aa6399
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
@@ -0,0 +1,2514 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ אודות
+ Area System
+
+
+ access.cpl
+ File name, Should not translated
+
+
+ Accessibility Options
+ Area Control Panel (legacy settings)
+
+
+ Accessory apps
+ Area Privacy
+
+
+ Access work or school
+ Area UserAccounts
+
+
+ Account info
+ Area Privacy
+
+
+ Accounts
+ Area SurfaceHub
+
+
+ Action Center
+ Area Control Panel (legacy settings)
+
+
+ Activation
+ Area UpdateAndSecurity
+
+
+ Activity history
+ Area Privacy
+
+
+ Add Hardware
+ Area Control Panel (legacy settings)
+
+
+ Add/Remove Programs
+ Area Control Panel (legacy settings)
+
+
+ Add your phone
+ Area Phone
+
+
+ Administrative Tools
+ Area System
+
+
+ Advanced display settings
+ Area System, only available on devices that support advanced display options
+
+
+ Advanced graphics
+
+
+ Advertising ID
+ Area Privacy, Deprecated in Windows 10, version 1809 and later
+
+
+ Airplane mode
+ Area NetworkAndInternet
+
+
+ Alt+Tab
+ Means the key combination "Tabulator+Alt" on the keyboard
+
+
+ Alternative names
+
+
+ Animations
+
+
+ App color
+
+
+ App diagnostics
+ Area Privacy
+
+
+ App features
+ Area Apps
+
+
+ App
+ Short/modern name for application
+
+
+ Apps and Features
+ Area Apps
+
+
+ System settings
+ Type of the setting is a "Modern Windows settings". We use the same term as used in start menu search at the moment.
+
+
+ Apps for websites
+ Area Apps
+
+
+ App volume and device preferences
+ Area System, Added in Windows 10, version 1903
+
+
+ appwiz.cpl
+ File name, Should not translated
+
+
+ Area
+ Mean the settings area or settings category
+
+
+ Accounts
+
+
+ Administrative Tools
+ Area Control Panel (legacy settings)
+
+
+ Appearance and Personalization
+
+
+ Apps
+
+
+ Clock and Region
+
+
+ Control Panel
+
+
+ Cortana
+
+
+ Devices
+
+
+ Ease of access
+
+
+ Extras
+
+
+ Gaming
+
+
+ Hardware and Sound
+
+
+ Home page
+
+
+ Mixed reality
+
+
+ Network and Internet
+
+
+ Personalization
+
+
+ Phone
+
+
+ Privacy
+
+
+ Programs
+
+
+ SurfaceHub
+
+
+ System
+
+
+ System and Security
+
+
+ Time and language
+
+
+ Update and security
+
+
+ User accounts
+
+
+ Assigned access
+
+
+ Audio
+ Area EaseOfAccess
+
+
+ Audio alerts
+
+
+ Audio and speech
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ Automatic file downloads
+ Area Privacy
+
+
+ AutoPlay
+ Area Device
+
+
+ Background
+ Area Personalization
+
+
+ Background Apps
+ Area Privacy
+
+
+ Backup
+ Area UpdateAndSecurity
+
+
+ Backup and Restore
+ Area Control Panel (legacy settings)
+
+
+ Battery Saver
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Battery Saver settings
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Battery saver usage details
+
+
+ Battery use
+ Area System, only available on devices that have a battery, such as a tablet
+
+
+ Biometric Devices
+ Area Control Panel (legacy settings)
+
+
+ BitLocker Drive Encryption
+ Area Control Panel (legacy settings)
+
+
+ Blue light
+
+
+ Bluetooth
+ Area Device
+
+
+ Bluetooth devices
+ Area Control Panel (legacy settings)
+
+
+ Blue-yellow
+
+
+ Bopomofo IME
+ Area TimeAndLanguage
+
+
+ bpmf
+ Should not translated
+
+
+ Broadcasting
+ Area Gaming
+
+
+ Calendar
+ Area Privacy
+
+
+ Call history
+ Area Privacy
+
+
+ calling
+
+
+ Camera
+ Area Privacy
+
+
+ Cangjie IME
+ Area TimeAndLanguage
+
+
+ Caps Lock
+ Mean the "Caps Lock" key
+
+
+ Cellular and SIM
+ Area NetworkAndInternet
+
+
+ Choose which folders appear on Start
+ Area Personalization
+
+
+ Client service for NetWare
+ Area Control Panel (legacy settings)
+
+
+ Clipboard
+ Area System
+
+
+ Closed captions
+ Area EaseOfAccess
+
+
+ Color filters
+ Area EaseOfAccess
+
+
+ Color management
+ Area Control Panel (legacy settings)
+
+
+ Colors
+ Area Personalization
+
+
+ Command
+ The command to direct start a setting
+
+
+ Connected Devices
+ Area Device
+
+
+ Contacts
+ Area Privacy
+
+
+ Control Panel
+ Type of the setting is a "(legacy) Control Panel setting"
+
+
+ Copy command
+
+
+ Core Isolation
+ Means the protection of the system core
+
+
+ Cortana
+ Area Cortana
+
+
+ Cortana across my devices
+ Area Cortana
+
+
+ Cortana - Language
+ Area Cortana
+
+
+ Credential manager
+ Area Control Panel (legacy settings)
+
+
+ Crossdevice
+
+
+ Custom devices
+
+
+ Dark color
+
+
+ Dark mode
+
+
+ Data usage
+ Area NetworkAndInternet
+
+
+ Date and time
+ Area TimeAndLanguage
+
+
+ Default apps
+ Area Apps
+
+
+ Default camera
+ Area Device
+
+
+ Default location
+ Area Control Panel (legacy settings)
+
+
+ Default programs
+ Area Control Panel (legacy settings)
+
+
+ Default Save Locations
+ Area System
+
+
+ Delivery Optimization
+ Area UpdateAndSecurity
+
+
+ desk.cpl
+ File name, Should not translated
+
+
+ Desktop themes
+ Area Control Panel (legacy settings)
+
+
+ deuteranopia
+ Medical: Mean you don't can see red colors
+
+
+ Device manager
+ Area Control Panel (legacy settings)
+
+
+ Devices and printers
+ Area Control Panel (legacy settings)
+
+
+ DHCP
+ Should not translated
+
+
+ Dial-up
+ Area NetworkAndInternet
+
+
+ Direct access
+ Area NetworkAndInternet, only available if DirectAccess is enabled
+
+
+ Direct open your phone
+ Area EaseOfAccess
+
+
+ Display
+ Area EaseOfAccess
+
+
+ Display properties
+ Area Control Panel (legacy settings)
+
+
+ DNS
+ Should not translated
+
+
+ Documents
+ Area Privacy
+
+
+ Duplicating my display
+ Area System
+
+
+ During these hours
+ Area System
+
+
+ Ease of access center
+ Area Control Panel (legacy settings)
+
+
+ Edition
+ Means the "Windows Edition"
+
+
+ Email
+ Area Privacy
+
+
+ Email and app accounts
+ Area UserAccounts
+
+
+ Encryption
+ Area System
+
+
+ Environment
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ Ethernet
+ Area NetworkAndInternet
+
+
+ Exploit Protection
+
+
+ Extras
+ Area Extra, , only used for setting of 3rd-Party tools
+
+
+ Eye control
+ Area EaseOfAccess
+
+
+ Eye tracker
+ Area Privacy, requires eyetracker hardware
+
+
+ Family and other people
+ Area UserAccounts
+
+
+ Feedback and diagnostics
+ Area Privacy
+
+
+ File system
+ Area Privacy
+
+
+ FindFast
+ Area Control Panel (legacy settings)
+
+
+ findfast.cpl
+ File name, Should not translated
+
+
+ Find My Device
+ Area UpdateAndSecurity
+
+
+ Firewall
+
+
+ Focus assist - Quiet hours
+ Area System
+
+
+ Focus assist - Quiet moments
+ Area System
+
+
+ Folder options
+ Area Control Panel (legacy settings)
+
+
+ Fonts
+ Area EaseOfAccess
+
+
+ For developers
+ Area UpdateAndSecurity
+
+
+ Game bar
+ Area Gaming
+
+
+ Game controllers
+ Area Control Panel (legacy settings)
+
+
+ Game DVR
+ Area Gaming
+
+
+ מצב משחק
+ Area Gaming
+
+
+ Gateway
+ Should not translated
+
+
+ כללי
+ Area Privacy
+
+
+ Get programs
+ Area Control Panel (legacy settings)
+
+
+ Getting started
+ Area Control Panel (legacy settings)
+
+
+ Glance
+ Area Personalization, Deprecated in Windows 10, version 1809 and later
+
+
+ Graphics settings
+ Area System
+
+
+ Grayscale
+
+
+ Green week
+ Mean you don't can see green colors
+
+
+ Headset display
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ High contrast
+ Area EaseOfAccess
+
+
+ Holographic audio
+
+
+ Holographic Environment
+
+
+ Holographic Headset
+
+
+ Holographic Management
+
+
+ Home group
+ Area Control Panel (legacy settings)
+
+
+ ID
+ MEans The "Windows Identifier"
+
+
+ Image
+
+
+ Indexing options
+ Area Control Panel (legacy settings)
+
+
+ inetcpl.cpl
+ File name, Should not translated
+
+
+ Infrared
+ Area Control Panel (legacy settings)
+
+
+ Inking and typing
+ Area Privacy
+
+
+ Internet options
+ Area Control Panel (legacy settings)
+
+
+ intl.cpl
+ File name, Should not translated
+
+
+ Inverted colors
+
+
+ IP
+ Should not translated
+
+
+ Isolated Browsing
+
+
+ Japan IME settings
+ Area TimeAndLanguage, available if the Microsoft Japan input method editor is installed
+
+
+ joy.cpl
+ File name, Should not translated
+
+
+ Joystick properties
+ Area Control Panel (legacy settings)
+
+
+ jpnime
+ Should not translated
+
+
+ Keyboard
+ Area EaseOfAccess
+
+
+ Keypad
+
+
+ Keys
+
+
+ שפה
+ Area TimeAndLanguage
+
+
+ Light color
+
+
+ Light mode
+
+
+ Location
+ Area Privacy
+
+
+ Lock screen
+ Area Personalization
+
+
+ Magnifier
+ Area EaseOfAccess
+
+
+ Mail - Microsoft Exchange or Windows Messaging
+ Area Control Panel (legacy settings)
+
+
+ main.cpl
+ File name, Should not translated
+
+
+ Manage known networks
+ Area NetworkAndInternet
+
+
+ Manage optional features
+ Area Apps
+
+
+ Messaging
+ Area Privacy
+
+
+ Metered connection
+
+
+ Microphone
+ Area Privacy
+
+
+ Microsoft Mail Post Office
+ Area Control Panel (legacy settings)
+
+
+ mlcfg32.cpl
+ File name, Should not translated
+
+
+ mmsys.cpl
+ File name, Should not translated
+
+
+ Mobile devices
+
+
+ Mobile hotspot
+ Area NetworkAndInternet
+
+
+ modem.cpl
+ File name, Should not translated
+
+
+ Mono
+
+
+ More details
+ Area Cortana
+
+
+ Motion
+ Area Privacy
+
+
+ Mouse
+ Area EaseOfAccess
+
+
+ Mouse and touchpad
+ Area Device
+
+
+ Mouse, Fonts, Keyboard, and Printers properties
+ Area Control Panel (legacy settings)
+
+
+ Mouse pointer
+ Area EaseOfAccess
+
+
+ Multimedia properties
+ Area Control Panel (legacy settings)
+
+
+ Multitasking
+ Area System
+
+
+ Narrator
+ Area EaseOfAccess
+
+
+ Navigation bar
+ Area Personalization
+
+
+ netcpl.cpl
+ File name, Should not translated
+
+
+ netsetup.cpl
+ File name, Should not translated
+
+
+ Network
+ Area NetworkAndInternet
+
+
+ Network and sharing center
+ Area Control Panel (legacy settings)
+
+
+ Network connection
+ Area Control Panel (legacy settings)
+
+
+ Network properties
+ Area Control Panel (legacy settings)
+
+
+ Network Setup Wizard
+ Area Control Panel (legacy settings)
+
+
+ Network status
+ Area NetworkAndInternet
+
+
+ NFC
+ Area NetworkAndInternet
+
+
+ NFC Transactions
+ "NFC should not translated"
+
+
+ Night light
+
+
+ Night light settings
+ Area System
+
+
+ Note
+
+
+ Only available when you have connected a mobile device to your device.
+
+
+ Only available on devices that support advanced graphics options.
+
+
+ Only available on devices that have a battery, such as a tablet.
+
+
+ Deprecated in Windows 10, version 1809 (build 17763) and later.
+
+
+ Only available if Dial is paired.
+
+
+ Only available if DirectAccess is enabled.
+
+
+ Only available on devices that support advanced display options.
+
+
+ Only present if user is enrolled in WIP.
+
+
+ Requires eyetracker hardware.
+
+
+ Available if the Microsoft Japan input method editor is installed.
+
+
+ Available if the Microsoft Pinyin input method editor is installed.
+
+
+ Available if the Microsoft Wubi input method editor is installed.
+
+
+ Only available if the Mixed Reality Portal app is installed.
+
+
+ Only available on mobile and if the enterprise has deployed a provisioning package.
+
+
+ Added in Windows 10, version 1903 (build 18362).
+
+
+ Added in Windows 10, version 2004 (build 19041).
+
+
+ Only available if "settings apps" are installed, for example, by a 3rd party.
+
+
+ Only available if touchpad hardware is present.
+
+
+ Only available if the device has a Wi-Fi adapter.
+
+
+ Device must be Windows Anywhere-capable.
+
+
+ Only available if enterprise has deployed a provisioning package.
+
+
+ Notifications
+ Area Privacy
+
+
+ Notifications and actions
+ Area System
+
+
+ Num Lock
+ Mean the "Num Lock" key
+
+
+ nwc.cpl
+ File name, Should not translated
+
+
+ odbccp32.cpl
+ File name, Should not translated
+
+
+ ODBC Data Source Administrator (32-bit)
+ Area Control Panel (legacy settings)
+
+
+ ODBC Data Source Administrator (64-bit)
+ Area Control Panel (legacy settings)
+
+
+ Offline files
+ Area Control Panel (legacy settings)
+
+
+ Offline Maps
+ Area Apps
+
+
+ Offline Maps - Download maps
+ Area Apps
+
+
+ On-Screen
+
+
+ OS
+ Means the "Operating System"
+
+
+ Other devices
+ Area Privacy
+
+
+ Other options
+ Area EaseOfAccess
+
+
+ Other users
+
+
+ Parental controls
+ Area Control Panel (legacy settings)
+
+
+ Password
+
+
+ password.cpl
+ File name, Should not translated
+
+
+ Password properties
+ Area Control Panel (legacy settings)
+
+
+ Pen and input devices
+ Area Control Panel (legacy settings)
+
+
+ Pen and touch
+ Area Control Panel (legacy settings)
+
+
+ Pen and Windows Ink
+ Area Device
+
+
+ People Near Me
+ Area Control Panel (legacy settings)
+
+
+ Performance information and tools
+ Area Control Panel (legacy settings)
+
+
+ Permissions and history
+ Area Cortana
+
+
+ Personalization (category)
+ Area Personalization
+
+
+ Phone
+ Area Phone
+
+
+ Phone and modem
+ Area Control Panel (legacy settings)
+
+
+ Phone and modem - Options
+ Area Control Panel (legacy settings)
+
+
+ Phone calls
+ Area Privacy
+
+
+ Phone - Default apps
+ Area System
+
+
+ Picture
+
+
+ Pictures
+ Area Privacy
+
+
+ Pinyin IME settings
+ Area TimeAndLanguage, available if the Microsoft Pinyin input method editor is installed
+
+
+ Pinyin IME settings - domain lexicon
+ Area TimeAndLanguage
+
+
+ Pinyin IME settings - Key configuration
+ Area TimeAndLanguage
+
+
+ Pinyin IME settings - UDP
+ Area TimeAndLanguage
+
+
+ Playing a game full screen
+ Area Gaming
+
+
+ Plugin to search for Windows settings
+
+
+ Windows Settings
+
+
+ Power and sleep
+ Area System
+
+
+ powercfg.cpl
+ File name, Should not translated
+
+
+ Power options
+ Area Control Panel (legacy settings)
+
+
+ Presentation
+
+
+ Printers
+ Area Control Panel (legacy settings)
+
+
+ Printers and scanners
+ Area Device
+
+
+ Print screen
+ Mean the "Print screen" key
+
+
+ Problem reports and solutions
+ Area Control Panel (legacy settings)
+
+
+ Processor
+
+
+ Programs and features
+ Area Control Panel (legacy settings)
+
+
+ Projecting to this PC
+ Area System
+
+
+ protanopia
+ Medical: Mean you don't can see green colors
+
+
+ Provisioning
+ Area UserAccounts, only available if enterprise has deployed a provisioning package
+
+
+ Proximity
+ Area NetworkAndInternet
+
+
+ Proxy
+ Area NetworkAndInternet
+
+
+ Quickime
+ Area TimeAndLanguage
+
+
+ Quiet moments game
+
+
+ Radios
+ Area Privacy
+
+
+ RAM
+ Means the Read-Access-Memory (typical the used to inform about the size)
+
+
+ Recognition
+
+
+ Recovery
+ Area UpdateAndSecurity
+
+
+ Red eye
+ Mean red eye effect by over-the-night flights
+
+
+ Red-green
+ Mean the weakness you can't differ between red and green colors
+
+
+ Red week
+ Mean you don't can see red colors
+
+
+ Region
+ Area TimeAndLanguage
+
+
+ Regional language
+ Area TimeAndLanguage
+
+
+ Regional settings properties
+ Area Control Panel (legacy settings)
+
+
+ Region and language
+ Area Control Panel (legacy settings)
+
+
+ Region formatting
+
+
+ RemoteApp and desktop connections
+ Area Control Panel (legacy settings)
+
+
+ Remote Desktop
+ Area System
+
+
+ Scanners and cameras
+ Area Control Panel (legacy settings)
+
+
+ schedtasks
+ File name, Should not translated
+
+
+ Scheduled
+
+
+ Scheduled tasks
+ Area Control Panel (legacy settings)
+
+
+ Screen rotation
+ Area System
+
+
+ Scroll bars
+
+
+ Scroll Lock
+ Mean the "Scroll Lock" key
+
+
+ SDNS
+ Should not translated
+
+
+ Searching Windows
+ Area Cortana
+
+
+ SecureDNS
+ Should not translated
+
+
+ Security Center
+ Area Control Panel (legacy settings)
+
+
+ Security Processor
+
+
+ Session cleanup
+ Area SurfaceHub
+
+
+ Settings home page
+ Area Home, Overview-page for all areas of settings
+
+
+ Set up a kiosk
+ Area UserAccounts
+
+
+ Shared experiences
+ Area System
+
+
+ Shortcuts
+
+
+ wifi
+ dont translate this, is a short term to find entries
+
+
+ Sign-in options
+ Area UserAccounts
+
+
+ Sign-in options - Dynamic lock
+ Area UserAccounts
+
+
+ Size
+ Size for text and symbols
+
+
+ Sound
+ Area System
+
+
+ Speech
+ Area EaseOfAccess
+
+
+ Speech recognition
+ Area Control Panel (legacy settings)
+
+
+ Speech typing
+
+
+ Start
+ Area Personalization
+
+
+ Start places
+
+
+ Startup apps
+ Area Apps
+
+
+ sticpl.cpl
+ File name, Should not translated
+
+
+ Storage
+ Area System
+
+
+ Storage policies
+ Area System
+
+
+ Storage Sense
+ Area System
+
+
+ in
+ Example: Area "System" in System settings
+
+
+ Sync center
+ Area Control Panel (legacy settings)
+
+
+ Sync your settings
+ Area UserAccounts
+
+
+ sysdm.cpl
+ File name, Should not translated
+
+
+ System
+ Area Control Panel (legacy settings)
+
+
+ System properties and Add New Hardware wizard
+ Area Control Panel (legacy settings)
+
+
+ Tab
+ Means the key "Tabulator" on the keyboard
+
+
+ Tablet mode
+ Area System
+
+
+ Tablet PC settings
+ Area Control Panel (legacy settings)
+
+
+ Talk
+
+
+ Talk to Cortana
+ Area Cortana
+
+
+ Taskbar
+ Area Personalization
+
+
+ Taskbar color
+
+
+ Tasks
+ Area Privacy
+
+
+ Team Conferencing
+ Area SurfaceHub
+
+
+ Team device management
+ Area SurfaceHub
+
+
+ Text to speech
+ Area Control Panel (legacy settings)
+
+
+ Themes
+ Area Personalization
+
+
+ themes.cpl
+ File name, Should not translated
+
+
+ timedate.cpl
+ File name, Should not translated
+
+
+ Timeline
+
+
+ Touch
+
+
+ Touch feedback
+
+
+ Touchpad
+ Area Device
+
+
+ Transparency
+
+
+ tritanopia
+ Medical: Mean you don't can see yellow and blue colors
+
+
+ Troubleshoot
+ Area UpdateAndSecurity
+
+
+ TruePlay
+ Area Gaming
+
+
+ Typing
+ Area Device
+
+
+ Uninstall
+ Area MixedReality, only available if the Mixed Reality Portal app is installed.
+
+
+ USB
+ Area Device
+
+
+ User accounts
+ Area Control Panel (legacy settings)
+
+
+ Version
+ Means The "Windows Version"
+
+
+ Video playback
+ Area Apps
+
+
+ Videos
+ Area Privacy
+
+
+ Virtual Desktops
+
+
+ Virus
+ Means the virus in computers and software
+
+
+ Voice activation
+ Area Privacy
+
+
+ Volume
+
+
+ VPN
+ Area NetworkAndInternet
+
+
+ Wallpaper
+
+
+ Warmer color
+
+
+ Welcome center
+ Area Control Panel (legacy settings)
+
+
+ Welcome screen
+ Area SurfaceHub
+
+
+ wgpocpl.cpl
+ File name, Should not translated
+
+
+ Wheel
+ Area Device
+
+
+ Wi-Fi
+ Area NetworkAndInternet, only available if Wi-Fi calling is enabled
+
+
+ Wi-Fi Calling
+ Area NetworkAndInternet, only available if Wi-Fi calling is enabled
+
+
+ Wi-Fi settings
+ "Wi-Fi" should not translated
+
+
+ Window border
+
+
+ Windows Anytime Upgrade
+ Area Control Panel (legacy settings)
+
+
+ Windows Anywhere
+ Area UserAccounts, device must be Windows Anywhere-capable
+
+
+ Windows CardSpace
+ Area Control Panel (legacy settings)
+
+
+ Windows Defender
+ Area Control Panel (legacy settings)
+
+
+ Windows Firewall
+ Area Control Panel (legacy settings)
+
+
+ Windows Hello setup - Face
+ Area UserAccounts
+
+
+ Windows Hello setup - Fingerprint
+ Area UserAccounts
+
+
+ Windows Insider Program
+ Area UpdateAndSecurity
+
+
+ Windows Mobility Center
+ Area Control Panel (legacy settings)
+
+
+ Windows search
+ Area Cortana
+
+
+ Windows Security
+ Area UpdateAndSecurity
+
+
+ Windows Update
+ Area UpdateAndSecurity
+
+
+ Windows Update - Advanced options
+ Area UpdateAndSecurity
+
+
+ Windows Update - Check for updates
+ Area UpdateAndSecurity
+
+
+ Windows Update - Restart options
+ Area UpdateAndSecurity
+
+
+ Windows Update - View optional updates
+ Area UpdateAndSecurity
+
+
+ Windows Update - View update history
+ Area UpdateAndSecurity
+
+
+ Wireless
+
+
+ Workplace
+
+
+ Workplace provisioning
+ Area UserAccounts
+
+
+ Wubi IME settings
+ Area TimeAndLanguage, available if the Microsoft Wubi input method editor is installed
+
+
+ Wubi IME settings - UDP
+ Area TimeAndLanguage
+
+
+ Xbox Networking
+ Area Gaming
+
+
+ Your info
+ Area UserAccounts
+
+
+ Zoom
+ Mean zooming of things via a magnifier
+
+
+ Change device installation settings
+
+
+ Turn off background images
+
+
+ Navigation properties
+
+
+ Media streaming options
+
+
+ Make a file type always open in a specific program
+
+
+ Change the Narrator’s voice
+
+
+ Find and fix keyboard problems
+
+
+ Use screen reader
+
+
+ Show which workgroup this computer is on
+
+
+ Change mouse wheel settings
+
+
+ Manage computer certificates
+
+
+ Find and fix problems
+
+
+ Change settings for content received using Tap and send
+
+
+ Change default settings for media or devices
+
+
+ Print the speech reference card
+
+
+ Calibrate display colour
+
+
+ Manage file encryption certificates
+
+
+ View recent messages about your computer
+
+
+ Give other users access to this computer
+
+
+ Show hidden files and folders
+
+
+ Change Windows To Go start-up options
+
+
+ See which processes start up automatically when you start Windows
+
+
+ Tell if an RSS feed is available on a website
+
+
+ Add clocks for different time zones
+
+
+ Add a Bluetooth device
+
+
+ Customise the mouse buttons
+
+
+ Set tablet buttons to perform certain tasks
+
+
+ View installed fonts
+
+
+ Change the way currency is displayed
+
+
+ Edit group policy
+
+
+ Manage browser add-ons
+
+
+ Check processor speed
+
+
+ Check firewall status
+
+
+ Send or receive a file
+
+
+ Add or remove user accounts
+
+
+ Edit the system environment variables
+
+
+ Manage BitLocker
+
+
+ Auto-hide the taskbar
+
+
+ Change sound card settings
+
+
+ Make changes to accounts
+
+
+ Edit local users and groups
+
+
+ View network computers and devices
+
+
+ Install a program from the network
+
+
+ View scanners and cameras
+
+
+ Microsoft IME Register Word (Japanese)
+
+
+ Restore your files with File History
+
+
+ Turn On-Screen keyboard on or off
+
+
+ Block or allow third-party cookies
+
+
+ Find and fix audio recording problems
+
+
+ Create a recovery drive
+
+
+ Microsoft New Phonetic Settings
+
+
+ Generate a system health report
+
+
+ Fix problems with your computer
+
+
+ Back up and Restore (Windows 7)
+
+
+ Preview, delete, show or hide fonts
+
+
+ Microsoft Quick Settings
+
+
+ View reliability history
+
+
+ Access RemoteApp and desktops
+
+
+ Set up ODBC data sources
+
+
+ Reset Security Policies
+
+
+ Block or allow pop-ups
+
+
+ Turn autocomplete in Internet Explorer on or off
+
+
+ Microsoft Pinyin SimpleFast Options
+
+
+ Change what closing the lid does
+
+
+ Turn off unnecessary animations
+
+
+ Create a restore point
+
+
+ Turn off automatic window arrangement
+
+
+ Troubleshooting History
+
+
+ Diagnose your computer's memory problems
+
+
+ View recommended actions to keep Windows running smoothly
+
+
+ Change cursor blink rate
+
+
+ Add or remove programs
+
+
+ Create a password reset disk
+
+
+ Configure advanced user profile properties
+
+
+ Start or stop using AutoPlay for all media and devices
+
+
+ Change Automatic Maintenance settings
+
+
+ Specify single- or double-click to open
+
+
+ Select users who can use remote desktop
+
+
+ Show which programs are installed on your computer
+
+
+ Allow remote access to your computer
+
+
+ View advanced system settings
+
+
+ How to install a program
+
+
+ Change how your keyboard works
+
+
+ Automatically adjust for daylight saving time
+
+
+ Change the order of Windows SideShow gadgets
+
+
+ Check keyboard status
+
+
+ Control the computer without the mouse or keyboard
+
+
+ Change or remove a program
+
+
+ Change multi-touch gesture settings
+
+
+ Set up ODBC data sources (64-bit)
+
+
+ Configure proxy server
+
+
+ Change your homepage
+
+
+ Group similar windows on the taskbar
+
+
+ Change Windows SideShow settings
+
+
+ Use audio description for video
+
+
+ Change workgroup name
+
+
+ Find and fix printing problems
+
+
+ Change when the computer sleeps
+
+
+ Set up a virtual private network (VPN) connection
+
+
+ Accommodate learning abilities
+
+
+ Set up a dial-up connection
+
+
+ Set up a connection or network
+
+
+ How to change your Windows password
+
+
+ Make it easier to see the mouse pointer
+
+
+ Set up iSCSI initiator
+
+
+ Accommodate low vision
+
+
+ Manage offline files
+
+
+ Review your computer's status and resolve issues
+
+
+ Microsoft ChangJie Settings
+
+
+ Replace sounds with visual cues
+
+
+ Change temporary Internet file settings
+
+
+ Connect to the Internet
+
+
+ Find and fix audio playback problems
+
+
+ Change the mouse pointer display or speed
+
+
+ Back up your recovery key
+
+
+ Save backup copies of your files with File History
+
+
+ View current accessibility settings
+
+
+ Change tablet pen settings
+
+
+ Change how your mouse works
+
+
+ Show how much RAM is on this computer
+
+
+ Edit power plan
+
+
+ Adjust system volume
+
+
+ Defragment and optimise your drives
+
+
+ Set up ODBC data sources (32-bit)
+
+
+ Change Font Settings
+
+
+ Magnify portions of the screen using Magnifier
+
+
+ Change the file type associated with a file extension
+
+
+ View event logs
+
+
+ Manage Windows Credentials
+
+
+ Set up a microphone
+
+
+ Change how the mouse pointer looks
+
+
+ Change power-saving settings
+
+
+ Optimise for blindness
+
+
+
+
+
+
+ Turn Windows features on or off
+
+
+ Show which operating system your computer is running
+
+
+ View local services
+
+
+ Manage Work Folders
+
+
+ Encrypt your offline files
+
+
+ Train the computer to recognise your voice
+
+
+ Advanced printer setup
+
+
+ Change default printer
+
+
+ Edit environment variables for your account
+
+
+ Optimise visual display
+
+
+ Change mouse click settings
+
+
+ Change advanced colour management settings for displays, scanners and printers
+
+
+ Let Windows suggest Ease of Access settings
+
+
+ Clear disk space by deleting unnecessary files
+
+
+ View devices and printers
+
+
+ Private Character Editor
+
+
+ Record steps to reproduce a problem
+
+
+ Adjust the appearance and performance of Windows
+
+
+ Settings for Microsoft IME (Japanese)
+
+
+ Invite someone to connect to your PC and help you, or offer to help someone else
+
+
+ Run programs made for previous versions of Windows
+
+
+ Choose the order of how your screen rotates
+
+
+ Change how Windows searches
+
+
+ Set flicks to perform certain tasks
+
+
+ Change account type
+
+
+ Change screen saver
+
+
+ Change User Account Control settings
+
+
+ Turn on easy access keys
+
+
+ Identify and repair network problems
+
+
+ Find and fix networking and connection problems
+
+
+ Play CDs or other media automatically
+
+
+ View basic information about your computer
+
+
+ Choose how you open links
+
+
+ Allow Remote Assistance invitations to be sent from this computer
+
+
+ Task Manager
+
+
+ Turn flicks on or off
+
+
+ Add a language
+
+
+ View network status and tasks
+
+
+ Turn Magnifier on or off
+
+
+ See the name of this computer
+
+
+ View network connections
+
+
+ Perform recommended maintenance tasks automatically
+
+
+ Manage disk space used by your offline files
+
+
+ Turn High Contrast on or off
+
+
+ Change the way time is displayed
+
+
+ Change how web pages are displayed in tabs
+
+
+ Change the way dates and lists are displayed
+
+
+ Manage audio devices
+
+
+ Change security settings
+
+
+ Check security status
+
+
+ Delete cookies or temporary files
+
+
+ Specify which hand you write with
+
+
+ Change touch input settings
+
+
+ How to change the size of virtual memory
+
+
+ Hear text read aloud with Narrator
+
+
+ Set up USB game controllers
+
+
+ Show which domain your computer is on
+
+
+ View all problem reports
+
+
+ 16-Bit Application Support
+
+
+ Set up dialling rules
+
+
+ Enable or disable session cookies
+
+
+ Give administrative rights to a domain user
+
+
+ Choose when to turn off display
+
+
+ Move the pointer with the keypad using MouseKeys
+
+
+ Change Windows SideShow-compatible device settings
+
+
+ Adjust commonly used mobility settings
+
+
+ Change text-to-speech settings
+
+
+ Set the time and date
+
+
+ Change location settings
+
+
+ Change mouse settings
+
+
+ Manage Storage Spaces
+
+
+ Show or hide file extensions
+
+
+ Allow an app through Windows Firewall
+
+
+ Change system sounds
+
+
+ Adjust ClearType text
+
+
+ Turn screen saver on or off
+
+
+ Find and fix windows update problems
+
+
+ Change Bluetooth settings
+
+
+ Connect to a network
+
+
+ Change the search provider in Internet Explorer
+
+
+ Join a domain
+
+
+ Add a device
+
+
+ Find and fix problems with Windows Search
+
+
+ Choose a power plan
+
+
+ Change how the mouse pointer looks when it’s moving
+
+
+ Uninstall a program
+
+
+ Create and format hard disk partitions
+
+
+ Change date, time or number formats
+
+
+ Change PC wake-up settings
+
+
+ Manage network passwords
+
+
+ Change input methods
+
+
+ Manage advanced sharing settings
+
+
+ Change battery settings
+
+
+ Rename this computer
+
+
+ Lock or unlock the taskbar
+
+
+ Manage Web Credentials
+
+
+ Change the time zone
+
+
+ Start speech recognition
+
+
+ View installed updates
+
+
+ What's happened to the Quick Launch toolbar?
+
+
+ Change search options for files and folders
+
+
+ Adjust settings before giving a presentation
+
+
+ Scan a document or picture
+
+
+ Change the way measurements are displayed
+
+
+ Press key combinations one at a time
+
+
+ Restore data, files or computer from backup (Windows 7)
+
+
+ Set your default programs
+
+
+ Set up a broadband connection
+
+
+ Calibrate the screen for pen or touch input
+
+
+ Manage user certificates
+
+
+ Schedule tasks
+
+
+ Ignore repeated keystrokes using FilterKeys
+
+
+ Find and fix bluescreen problems
+
+
+ Hear a tone when keys are pressed
+
+
+ Delete browsing history
+
+
+ Change what the power buttons do
+
+
+ Create standard user account
+
+
+ Take speech tutorials
+
+
+ View system resource usage in Task Manager
+
+
+ Create an account
+
+
+ Get more features with a new edition of Windows
+
+
+ Control Panel
+
+
+ TaskLink
+
+
+ Unknown
+
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
index 418ea06c542..e7f8e1683e4 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
@@ -1905,7 +1905,7 @@
Microsoft Quick Settings
- View reliability history
+ Ver histórico de fiabilidade
Access RemoteApp and desktops
@@ -1923,7 +1923,7 @@
Ativar ou desativar conclusão automática no Internet Explorer
- Microsoft Pinyin SimpleFast Options
+ Opções SimpleFast do Microsoft Pinyin
Change what closing the lid does
@@ -1947,16 +1947,16 @@
Ver ações recomendadas para manter o sistema a funcionar nas melhores condições
- Change cursor blink rate
+ Alterar a frequência de piscar do cursor
Adicionar ou remover programas
- Create a password reset disk
+ Criar disco de redefinição da palavra-passe
- Configure advanced user profile properties
+ Configurar propriedades avançadas do perfil de utilizador
Start or stop using AutoPlay for all media and devices
@@ -1971,10 +1971,10 @@
Utilizadores que podem utilizar o ambiente de trabalho remoto
- Show which programs are installed on your computer
+ Mostre que programas estão instalados no seu computador
- Allow remote access to your computer
+ Permitir o acesso remoto ao seu computador
Ver definições avançadas do sistema
@@ -1986,10 +1986,10 @@
Alterar modo de funcionamento do teclado
- Automatically adjust for daylight saving time
+ Ajustar automaticamente para horário de verão
- Change the order of Windows SideShow gadgets
+ Alterar a ordem dos Windows SideShow gadgets
Analisar estado do teclado
@@ -2037,34 +2037,34 @@
Accommodate learning abilities
- Set up a dial-up connection
+ Configurar uma ligação telefónica
- Set up a connection or network
+ Configurar uma ligação ou rede
Como alterar a palavra-passe do Windows
- Make it easier to see the mouse pointer
+ Tornar mais fácil ver o ponteiro do rato
- Set up iSCSI initiator
+ Configurar o iniciador iSCSI
- Accommodate low vision
+ Ajustar para baixa visão
Gerir ficheiros offline
- Review your computer's status and resolve issues
+ Verificar o estado do computador e resolver problemas
- Microsoft ChangJie Settings
+ Configurações Microsoft ChangJie
- Replace sounds with visual cues
+ Substituir sons por pistas visuais
Change temporary Internet file settings
@@ -2079,10 +2079,10 @@
Alterar exibição e/ou velocidade do ponteiro do rato
- Back up your recovery key
+ Cópia de segurança da chave de recuperação
- Save backup copies of your files with File History
+ Guardar cópias de segurança dos ficheiros no Histórico de Ficheiros
View current accessibility settings
@@ -2155,7 +2155,7 @@
Encrypt your offline files
- Train the computer to recognise your voice
+ Treinar o computador para reconhecer a sua voz
Configuração avançada de impressora
@@ -2218,7 +2218,7 @@
Alterar proteção de ecrã
- Change User Account Control settings
+ Alterar Configurações de Controlo da Conta do Utilizador
Turn on easy access keys
@@ -2455,7 +2455,7 @@
Press key combinations one at a time
- Restore data, files or computer from backup (Windows 7)
+ Restaurar dados, ficheiros ou computador a partir de cópia de segurança (Windows 7)
Set your default programs
From 0153f71083b755ff2df85c16757e7341e4069d2e Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Wed, 25 Dec 2024 11:20:09 -0600
Subject: [PATCH 0101/1335] use stackalloc if possible and fix some incorrect
use of safehandle
---
.../Hotkey/GlobalHotkey.cs | 2 +-
.../SharedCommands/ShellCommand.cs | 19 +++----
Flow.Launcher/Helper/DWMDropShadow.cs | 17 +++---
.../Helper/WallpaperPathRetrieval.cs | 24 +++++----
Flow.Launcher/Helper/WindowsInteropHelper.cs | 41 +++++++++++----
.../ProcessHelper.cs | 7 +--
.../Programs/ShellLinkHelper.cs | 30 ++++-------
.../Programs/ShellLocalization.cs | 52 +++++++++----------
8 files changed, 96 insertions(+), 96 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
index 2bc7db9bf65..b2a14075581 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
+++ b/Flow.Launcher.Infrastructure/Hotkey/GlobalHotkey.cs
@@ -88,7 +88,7 @@ private static LRESULT HookKeyboardCallback(int nCode, WPARAM wParam, LPARAM lPa
public void Dispose()
{
- PInvoke.UnhookWindowsHookEx(new HHOOK(hookId.DangerousGetHandle()));
+ hookId.Dispose();
}
~GlobalHotkey()
diff --git a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
index 9639f1b1ad4..9ea582118a7 100644
--- a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
@@ -25,6 +25,7 @@ public static Process RunAsDifferentUser(ProcessStartInfo processStartInfo)
CheckSecurityWindow();
Thread.Sleep(25);
}
+
while (containsSecurityWindow) // while this process contains a "Windows Security" dialog, stay open
{
containsSecurityWindow = false;
@@ -52,24 +53,20 @@ private static BOOL CheckSecurityThread(HWND hwnd, LPARAM lParam)
private static unsafe string GetWindowTitle(HWND hwnd)
{
var capacity = PInvoke.GetWindowTextLength(hwnd) + 1;
- char[] buffer = new char[capacity];
+ int length;
+ Span buffer = stackalloc char[capacity];
fixed (char* pBuffer = buffer)
{
// If the window has no title bar or text, if the title bar is empty,
// or if the window or control handle is invalid, the return value is zero.
- if (PInvoke.GetWindowText(hwnd, (PWSTR)pBuffer, capacity) == 0)
- {
- return string.Empty;
- }
-
- // Truncate the buffer to the actual length of the string
- int validLength = Array.IndexOf(buffer, '\0');
- if (validLength < 0) validLength = capacity;
- return new string(buffer, 0, validLength);
+ length = PInvoke.GetWindowText(hwnd, (PWSTR)pBuffer, capacity);
}
+
+ return buffer[..length].ToString();
}
- public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "", bool createNoWindow = false)
+ public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "",
+ string arguments = "", string verb = "", bool createNoWindow = false)
{
var info = new ProcessStartInfo
{
diff --git a/Flow.Launcher/Helper/DWMDropShadow.cs b/Flow.Launcher/Helper/DWMDropShadow.cs
index 7cb719d074d..58817d70e03 100644
--- a/Flow.Launcher/Helper/DWMDropShadow.cs
+++ b/Flow.Launcher/Helper/DWMDropShadow.cs
@@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Interop;
using Windows.Win32;
+using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Controls;
@@ -38,24 +39,22 @@ private static void window_SourceInitialized(object sender, EventArgs e) //fixed
///
/// Window to which the shadow will be applied
/// True if the method succeeded, false if not
- private unsafe static bool DropShadow(Window window)
+ private static unsafe bool DropShadow(Window window)
{
try
{
WindowInteropHelper helper = new WindowInteropHelper(window);
int val = 2;
- int ret1 = PInvoke.DwmSetWindowAttribute(new(helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
+ var ret1 = PInvoke.DwmSetWindowAttribute(new (helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
- if (ret1 == 0)
+ if (ret1 == HRESULT.S_OK)
{
var m = new MARGINS { cyBottomHeight = 0, cxLeftWidth = 0, cxRightWidth = 0, cyTopHeight = 0 };
- int ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
- return ret2 == 0;
- }
- else
- {
- return false;
+ var ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
+ return ret2 == HRESULT.S_OK;
}
+
+ return false;
}
catch (Exception)
{
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 8ab06e78d08..8a42d480ff9 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -1,5 +1,8 @@
-using System.Linq;
+using System;
+using System.Linq;
+using System.Runtime.InteropServices;
using System.Text;
+using System.Windows.Documents;
using System.Windows.Media;
using Microsoft.Win32;
using Windows.Win32;
@@ -9,19 +12,17 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
-
private static readonly int MAX_PATH = 260;
public static unsafe string GetWallpaperPath()
{
- var wallpaper = new StringBuilder(MAX_PATH);
- PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH, &wallpaper, 0);
-
- var str = wallpaper.ToString();
- if (string.IsNullOrEmpty(str))
- return null;
-
- return str;
+ var wallpaperPtr = stackalloc char[MAX_PATH];
+ PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH,
+ wallpaperPtr,
+ 0);
+ var wallpaper = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(wallpaperPtr);
+
+ return wallpaper.ToString();
}
public static Color GetWallpaperColor()
@@ -32,13 +33,14 @@ public static Color GetWallpaperColor()
{
try
{
- var parts = strResult.Trim().Split(new[] {' '}, 3).Select(byte.Parse).ToList();
+ var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList();
return Color.FromRgb(parts[0], parts[1], parts[2]);
}
catch
{
}
}
+
return Colors.Transparent;
}
}
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index 6656b0c5b26..caf3f0a7f60 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -1,5 +1,7 @@
using System;
+using System.ComponentModel;
using System.Drawing;
+using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
@@ -56,18 +58,17 @@ public unsafe static bool IsWindowFullscreen()
}
string windowClass;
- int capacity = 256;
- char[] buffer = new char[capacity];
+ const int capacity = 256;
+ Span buffer = stackalloc char[capacity];
+ int validLength;
fixed (char* pBuffer = buffer)
{
- PInvoke.GetClassName(hWnd, pBuffer, capacity);
-
- // Truncate the buffer to the actual length of the string
- int validLength = Array.IndexOf(buffer, '\0');
- if (validLength < 0) validLength = capacity;
- windowClass = new string(buffer, 0, validLength);
+ validLength = PInvoke.GetClassName(hWnd, pBuffer, capacity);
}
+ windowClass = buffer[..validLength].ToString();
+
+
//for Win+Tab (Flip3D)
if (windowClass == WINDOW_CLASS_WINTAB)
{
@@ -87,14 +88,15 @@ public unsafe static bool IsWindowFullscreen()
{
var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
- if (!hWndDesktop.Equals(IntPtr.Zero))
+ if (hWndDesktop.Value != (IntPtr.Zero))
{
return false;
}
}
Rectangle screenBounds = Screen.FromHandle(hWnd).Bounds;
- return (appBounds.bottom - appBounds.top) == screenBounds.Height && (appBounds.right - appBounds.left) == screenBounds.Width;
+ return (appBounds.bottom - appBounds.top) == screenBounds.Height &&
+ (appBounds.right - appBounds.left) == screenBounds.Width;
}
///
@@ -104,7 +106,23 @@ public unsafe static bool IsWindowFullscreen()
public static void DisableControlBox(Window win)
{
var hwnd = new HWND(new WindowInteropHelper(win).Handle);
- PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE) & ~(int)WINDOW_STYLE.WS_SYSMENU);
+
+ var style = PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE);
+
+ if (style == 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
+
+ style &= ~(int)WINDOW_STYLE.WS_SYSMENU;
+
+ var previousStyle = PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE,
+ style);
+
+ if (previousStyle == 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
}
///
@@ -127,6 +145,7 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
using var src = new HwndSource(new HwndSourceParameters());
matrix = src.CompositionTarget.TransformFromDevice;
}
+
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index abc254d8694..519e8a79297 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -98,7 +98,7 @@ public unsafe string TryGetProcessFilename(Process p)
using var safeHandle = new SafeProcessHandle(handle.Value, true);
uint capacity = 2000;
- char[] buffer = new char[capacity];
+ Span buffer = new char[capacity];
fixed (char* pBuffer = buffer)
{
if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, (PWSTR)pBuffer, ref capacity))
@@ -106,10 +106,7 @@ public unsafe string TryGetProcessFilename(Process p)
return string.Empty;
}
- // Truncate the buffer to the actual length of the string
- int validLength = Array.IndexOf(buffer, '\0');
- if (validLength < 0) validLength = (int)capacity;
- return new string(buffer, 0, validLength);
+ return buffer[..(int)capacity].ToString();
}
}
catch
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index ad1f3ab564d..f194ae973d6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -31,14 +31,14 @@ public unsafe string retrieveTargetPath(string path)
((IShellLinkW)link).Resolve(hwnd, 0);
const int MAX_PATH = 260;
- char[] buffer = new char[MAX_PATH];
+ Span buffer = stackalloc char[MAX_PATH];
var data = new WIN32_FIND_DATAW();
var target = string.Empty;
- fixed (char* bufferChar = buffer)
+ fixed (char* bufferPtr = buffer)
{
- ((IShellLinkW)link).GetPath((PWSTR)bufferChar, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
- target = GetStringFromBuffer(buffer, MAX_PATH);
+ ((IShellLinkW)link).GetPath((PWSTR)bufferPtr, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
+ target = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
}
// To set the app description
@@ -46,11 +46,10 @@ public unsafe string retrieveTargetPath(string path)
{
try
{
- char[] buffer1 = new char[MAX_PATH];
- fixed (char* buffer1Char = buffer1)
+ fixed (char* bufferPtr = buffer)
{
- ((IShellLinkW)link).GetDescription((PWSTR)buffer1Char, MAX_PATH);
- description = GetStringFromBuffer(buffer1, MAX_PATH);
+ ((IShellLinkW)link).GetDescription(bufferPtr, MAX_PATH);
+ description = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
}
}
catch (COMException e)
@@ -61,11 +60,10 @@ public unsafe string retrieveTargetPath(string path)
e);
}
- char[] buffer2 = new char[MAX_PATH];
- fixed (char* buffer2Char = buffer2)
+ fixed (char* bufferPtr = buffer)
{
- ((IShellLinkW)link).GetArguments((PWSTR)buffer2Char, MAX_PATH);
- arguments = GetStringFromBuffer(buffer2, MAX_PATH);
+ ((IShellLinkW)link).GetArguments(bufferPtr, MAX_PATH);
+ arguments = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
}
}
@@ -74,13 +72,5 @@ public unsafe string retrieveTargetPath(string path)
return target;
}
-
- private static unsafe string GetStringFromBuffer(char[] buffer, int maxLength)
- {
- // Truncate the buffer to the actual length of the string
- int validLength = Array.IndexOf(buffer, '\0');
- if (validLength < 0) validLength = maxLength;
- return new string(buffer, 0, validLength);
- }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
index e36618b0de5..fac3ab181e7 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Runtime.InteropServices;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.LibraryLoader;
@@ -20,39 +21,34 @@ public static class ShellLocalization
/// The localized name as string or .
public static unsafe string GetLocalizedName(string path)
{
- int capacity = 1024;
- char[] resourcePathBuffer = new char[capacity];
+ const int capacity = 1024;
+ Span buffer = new char[capacity];
// If there is no resource to localize a file name the method returns a non zero value.
- fixed (char* resourcePath = resourcePathBuffer)
+ fixed (char* bufferPtr = buffer)
{
- var result = PInvoke.SHGetLocalizedName(path, (PWSTR)resourcePath, (uint)capacity, out var id);
- if (result == HRESULT.S_OK)
+ var result = PInvoke.SHGetLocalizedName(path, bufferPtr, capacity, out var id);
+ if (result != HRESULT.S_OK)
{
- int validLength = Array.IndexOf(resourcePathBuffer, '\0');
- if (validLength < 0) validLength = capacity;
- var resourcePathStr = new string(resourcePathBuffer, 0, validLength);
- _ = PInvoke.ExpandEnvironmentStrings(resourcePathStr, resourcePath, (uint)capacity);
- var handle = PInvoke.LoadLibraryEx(resourcePathStr,
- LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
- IntPtr safeHandle = handle.DangerousGetHandle();
- if (safeHandle != IntPtr.Zero)
- {
- char[] localizedNameBuffer = new char[capacity];
- fixed (char* localizedName = localizedNameBuffer)
- {
- if (PInvoke.LoadString(handle, (uint)id, (PWSTR)localizedName, capacity) != 0)
- {
- validLength = Array.IndexOf(localizedNameBuffer, '\0');
- if (validLength < 0) validLength = capacity;
- var lString = new string(localizedNameBuffer, 0, validLength);
- PInvoke.FreeLibrary(new(safeHandle));
- return lString;
- }
- }
+ return string.Empty;
+ }
+
+ var resourcePathStr = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
+ _ = PInvoke.ExpandEnvironmentStrings(resourcePathStr, bufferPtr, capacity);
+ using var handle = PInvoke.LoadLibraryEx(resourcePathStr,
+ LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
+ if (handle.IsInvalid)
+ {
+ return string.Empty;
+ }
+
+ // not sure about the behavior of Pinvoke.LoadString, so we clear the buffer before using it (so it must be a null-terminated string)
+ buffer.Clear();
- PInvoke.FreeLibrary(new(safeHandle));
- }
+ if (PInvoke.LoadString(handle, (uint)id, bufferPtr, capacity) != 0)
+ {
+ var lString = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
+ return lString;
}
}
From 02a45661c4f836e9c21aff68f9872795cf1ee04c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 26 Dec 2024 13:04:15 +0800
Subject: [PATCH 0102/1335] Add consistent error handling for GetArguments
---
.../Programs/ShellLinkHelper.cs | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
index f194ae973d6..a77b2ace839 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -35,10 +35,18 @@ public unsafe string retrieveTargetPath(string path)
var data = new WIN32_FIND_DATAW();
var target = string.Empty;
- fixed (char* bufferPtr = buffer)
+ try
{
- ((IShellLinkW)link).GetPath((PWSTR)bufferPtr, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
- target = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
+ fixed (char* bufferPtr = buffer)
+ {
+ ((IShellLinkW)link).GetPath((PWSTR)bufferPtr, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
+ target = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
+ }
+ }
+ catch (COMException e)
+ {
+ ProgramLogger.LogException($"|IShellLinkW|retrieveTargetPath|{path}" +
+ "|Error occurred while getting program arguments", e);
}
// To set the app description
@@ -66,11 +74,11 @@ public unsafe string retrieveTargetPath(string path)
arguments = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
}
}
-
+
// To release unmanaged memory
Marshal.ReleaseComObject(link);
return target;
- }
+ }
}
}
From b2532fc88e09977b2c62d4eec3b8ec1ec0dd43d6 Mon Sep 17 00:00:00 2001
From: "pp.stabrawa"
Date: Fri, 27 Dec 2024 12:43:43 +0100
Subject: [PATCH 0103/1335] Order search result by window title
---
.../Main.cs | 30 ++++++++-----
.../ProcessHelper.cs | 44 ++++++++++++++++++-
2 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
index be2a2dd6673..03b563c9bf1 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using Flow.Launcher.Infrastructure;
@@ -60,30 +60,33 @@ public List LoadContextMenus(Result result)
return menuOptions;
}
+ private record RunningProcessInfo(string ProcessName, string MainWindowTitle);
+
private List CreateResultsFromQuery(Query query)
{
string termToSearch = query.Search;
- var processlist = processHelper.GetMatchingProcesses(termToSearch);
-
- if (!processlist.Any())
+ var processList = processHelper.GetMatchingProcesses(termToSearch);
+ var processWithNonEmptyMainWindowTitleList = processHelper.GetProcessesWithNonEmptyWindowTitle();
+
+ if (!processList.Any())
{
return null;
}
var results = new List();
- foreach (var pr in processlist)
+ foreach (var pr in processList)
{
var p = pr.Process;
var path = processHelper.TryGetProcessFilename(p);
results.Add(new Result()
{
IcoPath = path,
- Title = p.ProcessName + " - " + p.Id,
+ Title = processWithNonEmptyMainWindowTitleList.TryGetValue(p.Id, out var mainWindowTitle) ? mainWindowTitle : p.ProcessName + " - " + p.Id,
SubTitle = path,
TitleHighlightData = StringMatcher.FuzzySearch(termToSearch, p.ProcessName).MatchData,
Score = pr.Score,
- ContextData = p.ProcessName,
+ ContextData = new RunningProcessInfo(p.ProcessName, mainWindowTitle),
AutoCompleteText = $"{_context.CurrentPluginMetadata.ActionKeyword}{Plugin.Query.TermSeparator}{p.ProcessName}",
Action = (c) =>
{
@@ -95,22 +98,25 @@ private List CreateResultsFromQuery(Query query)
});
}
- var sortedResults = results.OrderBy(x => x.Title).ToList();
+ var sortedResults = results
+ .OrderBy(x => string.IsNullOrEmpty(((RunningProcessInfo)x.ContextData).MainWindowTitle))
+ .ThenBy(x => x.Title)
+ .ToList();
// When there are multiple results AND all of them are instances of the same executable
// add a quick option to kill them all at the top of the results.
var firstResult = sortedResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.SubTitle));
- if (processlist.Count > 1 && !string.IsNullOrEmpty(termToSearch) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
+ if (processList.Count > 1 && !string.IsNullOrEmpty(termToSearch) && sortedResults.All(r => r.SubTitle == firstResult?.SubTitle))
{
sortedResults.Insert(1, new Result()
{
IcoPath = firstResult?.IcoPath,
- Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), firstResult?.ContextData),
- SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processlist.Count),
+ Title = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all"), ((RunningProcessInfo)firstResult?.ContextData).ProcessName),
+ SubTitle = string.Format(_context.API.GetTranslation("flowlauncher_plugin_processkiller_kill_all_count"), processList.Count),
Score = 200,
Action = (c) =>
{
- foreach (var p in processlist)
+ foreach (var p in processList)
{
processHelper.TryKill(p.Process);
}
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index 0acc39fbb1c..5cc94dfdf48 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Infrastructure;
+using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using System;
using System.Collections.Generic;
@@ -11,6 +11,20 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
internal class ProcessHelper
{
+ [DllImport("user32.dll")]
+ private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
+
+ private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
+
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
+
+ [DllImport("user32.dll")]
+ private static extern bool IsWindowVisible(IntPtr hWnd);
+
+ [DllImport("user32.dll")]
+ private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
+
private readonly HashSet _systemProcessList = new HashSet()
{
"conhost",
@@ -60,6 +74,34 @@ public List GetMatchingProcesses(string searchTerm)
return processlist;
}
+ ///
+ /// Returns a dictionary of process IDs and their window titles for processes that have a visible main window with a non-empty title.
+ ///
+ public Dictionary GetProcessesWithNonEmptyWindowTitle()
+ {
+ var processDict = new Dictionary();
+ EnumWindows((hWnd, lParam) =>
+ {
+ StringBuilder windowTitle = new StringBuilder();
+ GetWindowText(hWnd, windowTitle, windowTitle.Capacity);
+
+ if (!string.IsNullOrWhiteSpace(windowTitle.ToString()) && IsWindowVisible(hWnd))
+ {
+ GetWindowThreadProcessId(hWnd, out var processId);
+ var process = Process.GetProcessById((int)processId);
+
+ if (!processDict.ContainsKey((int)processId))
+ {
+ processDict.Add((int)processId, windowTitle.ToString());
+ }
+ }
+
+ return true;
+ }, IntPtr.Zero);
+
+ return processDict;
+ }
+
///
/// Returns all non-system processes whose file path matches the given processPath
///
From 9350e82b7793414871dcc59ae95a5b84268aa365 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 27 Dec 2024 12:57:17 -0600
Subject: [PATCH 0104/1335] only stackalloc the getwindowtitle buffer when
length is small.
---
Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
index 9ea582118a7..a0440e30de9 100644
--- a/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs
@@ -54,12 +54,12 @@ private static unsafe string GetWindowTitle(HWND hwnd)
{
var capacity = PInvoke.GetWindowTextLength(hwnd) + 1;
int length;
- Span buffer = stackalloc char[capacity];
+ Span buffer = capacity < 1024 ? stackalloc char[capacity] : new char[capacity];
fixed (char* pBuffer = buffer)
{
// If the window has no title bar or text, if the title bar is empty,
// or if the window or control handle is invalid, the return value is zero.
- length = PInvoke.GetWindowText(hwnd, (PWSTR)pBuffer, capacity);
+ length = PInvoke.GetWindowText(hwnd, pBuffer, capacity);
}
return buffer[..length].ToString();
From 4b9c23d49bcf823641258ab003225edd9face248 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 30 Dec 2024 22:46:08 +0000
Subject: [PATCH 0105/1335] Bump nunit from 3.14.0 to 4.3.2
Bumps [nunit](https://github.com/nunit/nunit) from 3.14.0 to 4.3.2.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v3.14.0...4.3.2)
---
updated-dependencies:
- dependency-name: nunit
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Test/Flow.Launcher.Test.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
index 8286e142e67..0241a374e41 100644
--- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj
+++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj
@@ -49,7 +49,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
From 921d6a3beb6a3c05ca00e6ce70a41fbf9e98b21b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 2 Jan 2025 18:47:25 +0800
Subject: [PATCH 0106/1335] Add support for system language item
---
.../Resource/Internationalization.cs | 51 ++++++++++++++++---
1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1505e84f819..aac6ecc1e04 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,6 +18,8 @@ public class Internationalization
{
public Settings Settings { get; set; }
private const string Folder = "Languages";
+ private const string SystemLanguageCode = "System";
+ private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
private readonly List _languageDirectories = new List();
@@ -68,8 +70,18 @@ private void LoadDefaultLanguage()
public void ChangeLanguage(string languageCode)
{
languageCode = languageCode.NonNull();
- Language language = GetLanguageByLanguageCode(languageCode);
- ChangeLanguage(language);
+
+ // Get actual language if language code is system
+ var isSystem = false;
+ if (languageCode == SystemLanguageCode)
+ {
+ languageCode = GetSystemLanguageCode();
+ isSystem = true;
+ }
+
+ // Get language by language code and change language
+ var language = GetLanguageByLanguageCode(languageCode);
+ ChangeLanguage(language, isSystem);
}
private Language GetLanguageByLanguageCode(string languageCode)
@@ -87,11 +99,10 @@ private Language GetLanguageByLanguageCode(string languageCode)
}
}
- public void ChangeLanguage(Language language)
+ private void ChangeLanguage(Language language, bool isSystem)
{
language = language.NonNull();
-
RemoveOldLanguageFiles();
if (language != AvailableLanguages.English)
{
@@ -103,7 +114,7 @@ public void ChangeLanguage(Language language)
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
- Settings.Language = language.LanguageCode;
+ Settings.Language = isSystem ? SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
@@ -167,7 +178,35 @@ private void LoadLanguage(Language language)
public List LoadAvailableLanguages()
{
- return AvailableLanguages.GetAvailableLanguages();
+ var list = AvailableLanguages.GetAvailableLanguages();
+ list.Insert(0, new Language(SystemLanguageCode, "System"));
+ return list;
+ }
+
+ private string GetSystemLanguageCode()
+ {
+ var availableLanguages = AvailableLanguages.GetAvailableLanguages();
+
+ // Retrieve the language identifiers for the current culture
+ var currentCulture = CultureInfo.CurrentCulture;
+ var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
+ var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
+ var fullName = currentCulture.Name;
+
+ // Try to find a match in the available languages list
+ foreach (var language in availableLanguages)
+ {
+ var languageCode = language.LanguageCode;
+
+ if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
+ {
+ return languageCode;
+ }
+ }
+
+ return DefaultLanguageCode;
}
public string GetTranslation(string key)
From 0ae3cfcdd6f735b6f8e16ffa0e782c394fbd2e68 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 2 Jan 2025 18:50:02 +0800
Subject: [PATCH 0107/1335] Add display translation for system language item
---
.../Resource/AvailableLanguages.cs | 34 ++++++++++++++++++-
.../Resource/Internationalization.cs | 2 +-
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/AvailableLanguages.cs b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
index c385cd8e871..ecaecf64689 100644
--- a/Flow.Launcher.Core/Resource/AvailableLanguages.cs
+++ b/Flow.Launcher.Core/Resource/AvailableLanguages.cs
@@ -30,7 +30,6 @@ internal static class AvailableLanguages
public static Language Vietnamese = new Language("vi-vn", "Tiếng Việt");
public static Language Hebrew = new Language("he", "עברית");
-
public static List GetAvailableLanguages()
{
List languages = new List
@@ -63,5 +62,38 @@ public static List GetAvailableLanguages()
};
return languages;
}
+
+ public static string GetSystemTranslation(string languageCode)
+ {
+ return languageCode switch
+ {
+ "en" => "System",
+ "zh-cn" => "系统",
+ "zh-tw" => "系統",
+ "uk-UA" => "Система",
+ "ru" => "Система",
+ "fr" => "Système",
+ "ja" => "システム",
+ "nl" => "Systeem",
+ "pl" => "System",
+ "da" => "System",
+ "de" => "System",
+ "ko" => "시스템",
+ "sr" => "Систем",
+ "pt-pt" => "Sistema",
+ "pt-br" => "Sistema",
+ "es" => "Sistema",
+ "es-419" => "Sistema",
+ "it" => "Sistema",
+ "nb-NO" => "System",
+ "sk" => "Systém",
+ "tr" => "Sistem",
+ "cs" => "Systém",
+ "ar" => "النظام",
+ "vi-vn" => "Hệ thống",
+ "he" => "מערכת",
+ _ => "System",
+ };
+ }
}
}
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index aac6ecc1e04..4db3e863306 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -179,7 +179,7 @@ private void LoadLanguage(Language language)
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(SystemLanguageCode, "System"));
+ list.Insert(0, new Language(SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
return list;
}
From e0f0bed8223203e8676e16ecf9d2756a5fc59be1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 00:33:24 +0800
Subject: [PATCH 0108/1335] Revert "Fix clipboard action under sta thread
issue"
---
.../NativeMethods.txt | 5 +-
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Infrastructure/Win32Helper.cs | 138 ------------------
Flow.Launcher/PublicAPIInstance.cs | 39 +++--
4 files changed, 20 insertions(+), 164 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index d8777ff277c..f117534a1ff 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -16,7 +16,4 @@ WM_KEYUP
WM_SYSKEYDOWN
WM_SYSKEYUP
-EnumWindows
-
-OleInitialize
-OleUninitialize
\ No newline at end of file
+EnumWindows
\ No newline at end of file
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 83f06279c3b..0bcc9368d22 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -230,7 +230,7 @@ public SearchPrecisionScore QuerySearchPrecision
[JsonIgnore]
public ObservableCollection BuiltinShortcuts { get; set; } = new()
{
- new BuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", () => Win32Helper.StartSTATaskAsync(Clipboard.GetText).Result),
+ new BuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", Clipboard.GetText),
new BuiltinShortcutModel("{active_explorer_path}", "shortcut_active_explorer_path", FileExplorerHelper.GetActiveExplorerPath)
};
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 6d6c7286412..867fef4f509 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -1,150 +1,12 @@
using System;
using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows;
-using Windows.Win32;
namespace Flow.Launcher.Infrastructure
{
public static class Win32Helper
{
- #region STA Thread
-
- /*
- Found on https://github.com/files-community/Files
- */
-
- public static Task StartSTATaskAsync(Action action)
- {
- var taskCompletionSource = new TaskCompletionSource();
- Thread thread = new(() =>
- {
- PInvoke.OleInitialize();
-
- try
- {
- action();
- taskCompletionSource.SetResult();
- }
- catch (System.Exception)
- {
- taskCompletionSource.SetResult();
- }
- finally
- {
- PInvoke.OleUninitialize();
- }
- })
- {
- IsBackground = true,
- Priority = ThreadPriority.Normal
- };
-
- thread.SetApartmentState(ApartmentState.STA);
- thread.Start();
-
- return taskCompletionSource.Task;
- }
-
- public static Task StartSTATaskAsync(Func func)
- {
- var taskCompletionSource = new TaskCompletionSource();
- Thread thread = new(async () =>
- {
- PInvoke.OleInitialize();
-
- try
- {
- await func();
- taskCompletionSource.SetResult();
- }
- catch (System.Exception)
- {
- taskCompletionSource.SetResult();
- }
- finally
- {
- PInvoke.OleUninitialize();
- }
- })
- {
- IsBackground = true,
- Priority = ThreadPriority.Normal
- };
-
- thread.SetApartmentState(ApartmentState.STA);
- thread.Start();
-
- return taskCompletionSource.Task;
- }
-
- public static Task StartSTATaskAsync(Func func)
- {
- var taskCompletionSource = new TaskCompletionSource();
-
- Thread thread = new(() =>
- {
- PInvoke.OleInitialize();
-
- try
- {
- taskCompletionSource.SetResult(func());
- }
- catch (System.Exception)
- {
- taskCompletionSource.SetResult(default);
- }
- finally
- {
- PInvoke.OleUninitialize();
- }
- })
- {
- IsBackground = true,
- Priority = ThreadPriority.Normal
- };
-
- thread.SetApartmentState(ApartmentState.STA);
- thread.Start();
-
- return taskCompletionSource.Task;
- }
-
- public static Task StartSTATaskAsync(Func> func)
- {
- var taskCompletionSource = new TaskCompletionSource();
-
- Thread thread = new(async () =>
- {
- PInvoke.OleInitialize();
- try
- {
- taskCompletionSource.SetResult(await func());
- }
- catch (System.Exception)
- {
- taskCompletionSource.SetResult(default);
- }
- finally
- {
- PInvoke.OleUninitialize();
- }
- })
- {
- IsBackground = true,
- Priority = ThreadPriority.Normal
- };
-
- thread.SetApartmentState(ApartmentState.STA);
- thread.Start();
-
- return taskCompletionSource.Task;
- }
-
- #endregion
-
#region Blur Handling
/*
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index dcdb798fff2..f0295cf244a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -117,38 +117,35 @@ public void ShellRun(string cmd, string filename = "cmd.exe")
ShellCommand.Execute(startInfo);
}
- public async void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
+ public void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
{
if (string.IsNullOrEmpty(stringToCopy))
return;
- await Win32Helper.StartSTATaskAsync(() =>
+ var isFile = File.Exists(stringToCopy);
+ if (directCopy && (isFile || Directory.Exists(stringToCopy)))
{
- var isFile = File.Exists(stringToCopy);
- if (directCopy && (isFile || Directory.Exists(stringToCopy)))
- {
- var paths = new StringCollection
+ var paths = new StringCollection
{
stringToCopy
};
- Clipboard.SetFileDropList(paths);
+ Clipboard.SetFileDropList(paths);
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
- GetTranslation("completedSuccessfully"));
- }
- else
- {
- Clipboard.SetDataObject(stringToCopy);
+ if (showDefaultNotification)
+ ShowMsg(
+ $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
+ GetTranslation("completedSuccessfully"));
+ }
+ else
+ {
+ Clipboard.SetDataObject(stringToCopy);
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
- GetTranslation("completedSuccessfully"));
- }
- });
+ if (showDefaultNotification)
+ ShowMsg(
+ $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
+ GetTranslation("completedSuccessfully"));
+ }
}
public void StartLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Visible;
From 5d623123fc72554a87a8fbf8d0e33f52a3638d3c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 14:02:50 +0800
Subject: [PATCH 0109/1335] Fix operator equal application issue
---
Flow.Launcher.Infrastructure/FileExplorerHelper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index b738b9c88f6..65f424e33f3 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -68,7 +68,7 @@ private static IEnumerable GetZOrder(List hWnds)
var numRemaining = hWnds.Count;
PInvoke.EnumWindows((wnd, _) =>
{
- var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.Value);
+ var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.Value.ToInt64());
if (searchIndex != -1)
{
z[searchIndex] = index;
From 37058f765185341a08007d4c713d944e25303b79 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 21:55:44 +0800
Subject: [PATCH 0110/1335] Improve code quality.
---
.../Flow.Launcher.Plugin.PluginsManager/Main.cs | 2 +-
.../PluginsManager.cs | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
index bec84f48410..156135f813d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -51,7 +51,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
return query.FirstSearch.ToLower() switch
{
//search could be url, no need ToLower() when passed in
- Settings.InstallCommand => await pluginManager.RequestInstallOrUpdate(query.SecondToEndSearch, token, query.IsReQuery),
+ Settings.InstallCommand => await pluginManager.RequestInstallOrUpdateAsync(query.SecondToEndSearch, token, query.IsReQuery),
Settings.UninstallCommand => pluginManager.RequestUninstall(query.SecondToEndSearch),
Settings.UpdateCommand => await pluginManager.RequestUpdateAsync(query.SecondToEndSearch, token, query.IsReQuery),
_ => pluginManager.GetDefaultHotKeys().Where(hotkey =>
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 305d248d3e8..b1b1a75021f 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -324,7 +324,7 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
x.Name));
- }, TaskContinuationOptions.OnlyOnFaulted);
+ }, token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
return true;
},
@@ -337,7 +337,7 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
});
// Update all result
- if (resultsForUpdate.Count() > 1)
+ if (resultsForUpdate.Count > 1)
{
var updateAllResult = new Result
{
@@ -351,13 +351,13 @@ await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
{
message = string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"),
- resultsForUpdate.Count(), Environment.NewLine);
+ resultsForUpdate.Count, Environment.NewLine);
}
else
{
message = string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"),
- resultsForUpdate.Count());
+ resultsForUpdate.Count);
}
if (Context.API.ShowMsgBox(message,
@@ -401,7 +401,7 @@ await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFileP
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"),
- resultsForUpdate.Count()));
+ resultsForUpdate.Count));
Context.API.RestartApp();
}
else
@@ -409,7 +409,7 @@ await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFileP
Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"),
- resultsForUpdate.Count()));
+ resultsForUpdate.Count));
}
return true;
@@ -545,7 +545,7 @@ private bool InstallSourceKnown(string url)
Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
}
- internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token,
+ internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
From 562b233c157f2d11bc00f744f2772223037c4eb4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 4 Jan 2025 23:11:13 +0800
Subject: [PATCH 0111/1335] Add progress box support for downloading plugin
---
Flow.Launcher.Core/ProgressBoxEx.xaml | 106 ++++++++++++++++++
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 76 +++++++++++++
.../PluginsManager.cs | 59 +++++++++-
3 files changed, 239 insertions(+), 2 deletions(-)
create mode 100644 Flow.Launcher.Core/ProgressBoxEx.xaml
create mode 100644 Flow.Launcher.Core/ProgressBoxEx.xaml.cs
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml b/Flow.Launcher.Core/ProgressBoxEx.xaml
new file mode 100644
index 00000000000..4cce822217e
--- /dev/null
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
new file mode 100644
index 00000000000..61ba397de4b
--- /dev/null
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+using Flow.Launcher.Infrastructure.Logger;
+
+namespace Flow.Launcher.Core
+{
+ public partial class ProgressBoxEx : Window
+ {
+ private ProgressBoxEx()
+ {
+ InitializeComponent();
+ }
+
+ public static ProgressBoxEx Show(string caption)
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ return Application.Current.Dispatcher.Invoke(() => Show(caption));
+ }
+
+ try
+ {
+ var prgBox = new ProgressBoxEx
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ return prgBox;
+ }
+ catch (Exception e)
+ {
+ Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
+ return null;
+ }
+ }
+
+ public void ReportProgress(double progress)
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ Application.Current.Dispatcher.Invoke(() => ReportProgress(progress));
+ return;
+ }
+
+ if (progress < 0)
+ {
+ ProgressBar.Value = 0;
+ }
+ else if (progress >= 100)
+ {
+ ProgressBar.Value = 100;
+ }
+ else
+ {
+ ProgressBar.Value = progress;
+ }
+ }
+
+ private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void Button_Cancel(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index b1b1a75021f..39390ae101f 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -142,6 +143,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
+ ProgressBoxEx prgBox = null;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -149,7 +151,42 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (File.Exists(filePath))
File.Delete(filePath);
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ using var httpClient = new HttpClient();
+ using var response = await httpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+
+ response.EnsureSuccessStatusCode();
+
+ var totalBytes = response.Content.Headers.ContentLength ?? -1L;
+ var canReportProgress = totalBytes != -1;
+
+ if (canReportProgress && (prgBox = ProgressBoxEx.Show("Download plugin...")) != null)
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
+
+ while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
+ totalRead += read;
+
+ var progressValue = totalRead * 100 / totalBytes;
+ prgBox.ReportProgress(progressValue);
+ }
+
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox.Close();
+ prgBox = null;
+ });
+ }
+ else
+ {
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ }
}
else
{
@@ -164,6 +201,15 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ // force close progress box
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (prgBox != null)
+ {
+ prgBox.Close();
+ prgBox = null;
+ }
+ });
return;
}
catch (Exception e)
@@ -172,6 +218,15 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
plugin.Name));
Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ // force close progress box
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (prgBox != null)
+ {
+ prgBox.Close();
+ prgBox = null;
+ }
+ });
return;
}
From 54f02e04e6d67d46152e2480d553ec7628ed9980 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:08:56 +0800
Subject: [PATCH 0112/1335] Use public api for ProgressBoxEx & Add support for
force close event
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 45 +++++++++++++++----
Flow.Launcher.Plugin/IProgressBoxEx.cs | 20 +++++++++
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 11 ++++-
Flow.Launcher/PublicAPIInstance.cs | 2 +
.../PluginsManager.cs | 7 ++-
5 files changed, 72 insertions(+), 13 deletions(-)
create mode 100644 Flow.Launcher.Plugin/IProgressBoxEx.cs
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 61ba397de4b..b6801d2c1f0 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -2,26 +2,31 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core
{
- public partial class ProgressBoxEx : Window
+ public partial class ProgressBoxEx : Window, IProgressBoxEx
{
- private ProgressBoxEx()
+ private readonly Action _forceClosed;
+ private bool _isClosed;
+
+ private ProgressBoxEx(Action forceClosed)
{
+ _forceClosed = forceClosed;
InitializeComponent();
}
- public static ProgressBoxEx Show(string caption)
+ public static IProgressBoxEx Show(string caption, Action forceClosed)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- return Application.Current.Dispatcher.Invoke(() => Show(caption));
+ return Application.Current.Dispatcher.Invoke(() => Show(caption, forceClosed));
}
try
{
- var prgBox = new ProgressBoxEx
+ var prgBox = new ProgressBoxEx(forceClosed)
{
Title = caption
};
@@ -51,6 +56,7 @@ public void ReportProgress(double progress)
else if (progress >= 100)
{
ProgressBar.Value = 100;
+ Close();
}
else
{
@@ -58,19 +64,42 @@ public void ReportProgress(double progress)
}
}
+ private new void Close()
+ {
+ if (_isClosed)
+ {
+ return;
+ }
+
+ base.Close();
+ _isClosed = true;
+ }
+
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
- Close();
+ ForceClose();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
- Close();
+ ForceClose();
}
private void Button_Cancel(object sender, RoutedEventArgs e)
{
- Close();
+ ForceClose();
+ }
+
+ private void ForceClose()
+ {
+ if (_isClosed)
+ {
+ return;
+ }
+
+ base.Close();
+ _isClosed = true;
+ _forceClosed?.Invoke();
}
}
}
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
new file mode 100644
index 00000000000..0b245411ff1
--- /dev/null
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -0,0 +1,20 @@
+namespace Flow.Launcher.Plugin;
+
+///
+/// Interface for progress box
+///
+public interface IProgressBoxEx
+{
+ ///
+ /// Show progress box
+ ///
+ ///
+ /// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
+ ///
+ public void ReportProgress(double progress);
+
+ ///
+ /// Close progress box.
+ ///
+ public void Close();
+}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index a0186b7a214..9cd45a1d313 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Plugin.SharedModels;
+using Flow.Launcher.Plugin.SharedModels;
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
@@ -316,5 +316,14 @@ public interface IPublicAPI
/// Specifies the default result of the message box.
/// Specifies which message box button is clicked by the user.
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK);
+
+ ///
+ /// Displays a standardised Flow message box.
+ /// If there is issue when showing the message box, it will return null.
+ ///
+ /// The caption of the message box.
+ /// When user closes the progress box manually by button or esc key, this action will be called.
+ /// A progress box interface.
+ public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf244a..b403d604662 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,6 +324,8 @@ public bool IsGameModeOn()
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
+ public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null) => ProgressBoxEx.Show(caption, forceClosed);
+
#endregion
#region Private Methods
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 39390ae101f..f7383ff2f9c 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -143,7 +142,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- ProgressBoxEx prgBox = null;
+ IProgressBoxEx prgBox = null;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -159,7 +158,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = ProgressBoxEx.Show("Download plugin...")) != null)
+ if (canReportProgress && (prgBox = Context.API.ShowProgressBox("Download plugin...")) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
From d0bab86377d51234337ab2f682f320e9dd80cc47 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:11:03 +0800
Subject: [PATCH 0113/1335] Improve code quality
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 2 +-
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index b6801d2c1f0..9a32f730387 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -17,7 +17,7 @@ private ProgressBoxEx(Action forceClosed)
InitializeComponent();
}
- public static IProgressBoxEx Show(string caption, Action forceClosed)
+ public static IProgressBoxEx Show(string caption, Action forceClosed = null)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f7383ff2f9c..2ac4be93e7c 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -158,7 +158,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = Context.API.ShowProgressBox("Download plugin...")) != null)
+ if (canReportProgress && (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...")) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
From f69dd0f15572d1135ac753563d8f3ecb9ab40dcf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 00:13:32 +0800
Subject: [PATCH 0114/1335] Improve documents
---
Flow.Launcher.Plugin/IProgressBoxEx.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 0b245411ff1..6468e3c83a6 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -6,7 +6,7 @@
public interface IProgressBoxEx
{
///
- /// Show progress box
+ /// Show progress box. It should be called from the main ui thread.
///
///
/// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
@@ -14,7 +14,7 @@ public interface IProgressBoxEx
public void ReportProgress(double progress);
///
- /// Close progress box.
+ /// Close progress box. It should be called from the main ui thread.
///
public void Close();
}
From 56069e657c55a0714dc0c0a6571ac554c12391b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 15:31:14 +0800
Subject: [PATCH 0115/1335] Improve code quality
---
Flow.Launcher.Infrastructure/FileExplorerHelper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index 65f424e33f3..d908b0fde0a 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -68,7 +68,7 @@ private static IEnumerable GetZOrder(List hWnds)
var numRemaining = hWnds.Count;
PInvoke.EnumWindows((wnd, _) =>
{
- var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.Value.ToInt64());
+ var searchIndex = hWnds.FindIndex(x => new IntPtr(x.HWND) == wnd);
if (searchIndex != -1)
{
z[searchIndex] = index;
From c06ba595b4f784757958702a3abcec1aed9e7fea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:08:07 +0800
Subject: [PATCH 0116/1335] Add support for cancelling download
---
.../PluginsManager.cs | 24 ++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 2ac4be93e7c..a1b37f428d6 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -143,6 +143,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
IProgressBoxEx prgBox = null;
+ var downloadCancelled = false;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -158,7 +159,13 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
- if (canReportProgress && (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...")) != null)
+ if (canReportProgress &&
+ (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
+ {
+ httpClient.CancelPendingRequests();
+ downloadCancelled = true;
+ prgBox = null;
+ })) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
@@ -173,27 +180,38 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
totalRead += read;
var progressValue = totalRead * 100 / totalBytes;
+
+ // check if user cancelled download before reporting progress
+ if (downloadCancelled)
+ return;
+
prgBox.ReportProgress(progressValue);
}
+ // check if user cancelled download before closing progress box
+ if (downloadCancelled)
+ return;
+
Application.Current.Dispatcher.Invoke(() =>
{
prgBox.Close();
prgBox = null;
});
+
+ Install(plugin, filePath);
}
else
{
await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ Install(plugin, filePath);
}
}
else
{
filePath = plugin.LocalInstallPath;
- }
-
Install(plugin, filePath);
}
+ }
catch (HttpRequestException e)
{
Context.API.ShowMsgError(
From 07bb16c8f30813eece608b09cde5bbced5ac91a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:08:23 +0800
Subject: [PATCH 0117/1335] Improve code quality
---
.../PluginsManager.cs | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index a1b37f428d6..f1c634640d7 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -161,7 +161,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (canReportProgress &&
(prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
- {
+ {
httpClient.CancelPendingRequests();
downloadCancelled = true;
prgBox = null;
@@ -209,15 +209,11 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
else
{
filePath = plugin.LocalInstallPath;
- Install(plugin, filePath);
- }
+ Install(plugin, filePath);
+ }
}
catch (HttpRequestException e)
{
- Context.API.ShowMsgError(
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
- Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
- Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
// force close progress box
Application.Current.Dispatcher.Invoke(() =>
{
@@ -227,14 +223,17 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
prgBox = null;
}
});
+
+ // show error message
+ Context.API.ShowMsgError(
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
+ Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
+ Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+
return;
}
catch (Exception e)
{
- Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
- string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
- plugin.Name));
- Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
// force close progress box
Application.Current.Dispatcher.Invoke(() =>
{
@@ -244,6 +243,13 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
prgBox = null;
}
});
+
+ // show error message
+ Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
+ plugin.Name));
+ Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+
return;
}
From c907c291480aeb800dba9cadd45e9c2d50917600 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 5 Jan 2025 21:16:49 +0800
Subject: [PATCH 0118/1335] Fix plugin install issue
---
.../PluginsManager.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f1c634640d7..fd222d909e7 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -197,20 +197,22 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
prgBox.Close();
prgBox = null;
});
-
- Install(plugin, filePath);
}
else
{
await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- Install(plugin, filePath);
}
}
else
{
filePath = plugin.LocalInstallPath;
- Install(plugin, filePath);
}
+
+ // check if user cancelled download before installing plugin
+ if (downloadCancelled)
+ return;
+
+ Install(plugin, filePath);
}
catch (HttpRequestException e)
{
From 3ccd8b42ae53ccd33f66492f6134078a2656c96b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 16:58:08 +0800
Subject: [PATCH 0119/1335] Move SystemLanguageCode to constant
---
Flow.Launcher.Core/Resource/Internationalization.cs | 7 +++----
Flow.Launcher.Infrastructure/Constant.cs | 2 ++
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 4db3e863306..70f23c89721 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,7 +18,6 @@ public class Internationalization
{
public Settings Settings { get; set; }
private const string Folder = "Languages";
- private const string SystemLanguageCode = "System";
private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
@@ -73,7 +72,7 @@ public void ChangeLanguage(string languageCode)
// Get actual language if language code is system
var isSystem = false;
- if (languageCode == SystemLanguageCode)
+ if (languageCode == Constant.SystemLanguageCode)
{
languageCode = GetSystemLanguageCode();
isSystem = true;
@@ -114,7 +113,7 @@ private void ChangeLanguage(Language language, bool isSystem)
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
- Settings.Language = isSystem ? SystemLanguageCode : language.LanguageCode;
+ Settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
@@ -179,7 +178,7 @@ private void LoadLanguage(Language language)
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
+ list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
return list;
}
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index 2889e5ec7ed..f03d327f2e3 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -52,5 +52,7 @@ public static class Constant
public const string SponsorPage = "https://github.com/sponsors/Flow-Launcher";
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
public const string Docs = "https://flowlauncher.com/docs";
+
+ public const string SystemLanguageCode = "System";
}
}
From 6febbe719a956d1e9928e9d690c70ffa55105467 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 16:58:19 +0800
Subject: [PATCH 0120/1335] Use system language as default in settings
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 83f06279c3b..5b5d10e6e0f 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -13,7 +13,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public class Settings : BaseModel, IHotkeySettings
{
- private string language = "en";
+ private string language = Constant.SystemLanguageCode;
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
From 46c2c1f6683e50652afbfa541f187d15fb6275b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 19:20:47 +0800
Subject: [PATCH 0121/1335] Change system language code to lowercase
---
Flow.Launcher.Infrastructure/Constant.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs
index f03d327f2e3..c86ed432467 100644
--- a/Flow.Launcher.Infrastructure/Constant.cs
+++ b/Flow.Launcher.Infrastructure/Constant.cs
@@ -53,6 +53,6 @@ public static class Constant
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
public const string Docs = "https://flowlauncher.com/docs";
- public const string SystemLanguageCode = "System";
+ public const string SystemLanguageCode = "system";
}
}
From 675ee9e3952fcc4093dd6f70e3da0d3bae917f47 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:16:12 +0800
Subject: [PATCH 0122/1335] Add translation for progress box title
---
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fd222d909e7..0ed849bb3ee 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -159,8 +159,9 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = totalBytes != -1;
+ var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
if (canReportProgress &&
- (prgBox = Context.API.ShowProgressBox($"Download {plugin.Name}...", () =>
+ (prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
{
httpClient.CancelPendingRequests();
downloadCancelled = true;
From 0fabe31fe4344acb49bae294ac4cf23981a1951d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:16:28 +0800
Subject: [PATCH 0123/1335] Improve code quality
---
.../PluginsManager.cs | 29 ++++++++++---------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 0ed849bb3ee..bbb5c179edb 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -163,9 +163,12 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (canReportProgress &&
(prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
{
- httpClient.CancelPendingRequests();
- downloadCancelled = true;
- prgBox = null;
+ if (prgBox != null)
+ {
+ httpClient.CancelPendingRequests();
+ downloadCancelled = true;
+ prgBox = null;
+ }
})) != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@@ -185,19 +188,19 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
// check if user cancelled download before reporting progress
if (downloadCancelled)
return;
-
- prgBox.ReportProgress(progressValue);
+ else
+ prgBox.ReportProgress(progressValue);
}
// check if user cancelled download before closing progress box
if (downloadCancelled)
return;
-
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox.Close();
- prgBox = null;
- });
+ else
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox.Close();
+ prgBox = null;
+ });
}
else
{
@@ -212,8 +215,8 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
// check if user cancelled download before installing plugin
if (downloadCancelled)
return;
-
- Install(plugin, filePath);
+ else
+ Install(plugin, filePath);
}
catch (HttpRequestException e)
{
From cc0fb66b2245dbc1e7f4098b5da492b19a8868ac Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:26:05 +0800
Subject: [PATCH 0124/1335] Extract duplicate cleanup code into a method
---
.../PluginsManager.cs | 32 +++++++------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index bbb5c179edb..a41a82c67f4 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,11 +196,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (downloadCancelled)
return;
else
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox.Close();
- prgBox = null;
- });
+ CleanupProgressBoxEx(prgBox);
}
else
{
@@ -221,14 +217,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (HttpRequestException e)
{
// force close progress box
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (prgBox != null)
- {
- prgBox.Close();
- prgBox = null;
- }
- });
+ CleanupProgressBoxEx(prgBox);
// show error message
Context.API.ShowMsgError(
@@ -241,14 +230,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (Exception e)
{
// force close progress box
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (prgBox != null)
- {
- prgBox.Close();
- prgBox = null;
- }
- });
+ CleanupProgressBoxEx(prgBox);
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
@@ -274,6 +256,14 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
}
+ private static void CleanupProgressBoxEx(IProgressBoxEx prgBox)
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ prgBox?.Close();
+ });
+ }
+
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
From bc84910e56c041d59fa966737a15fa3fdb7511fa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:30:28 +0800
Subject: [PATCH 0125/1335] Use static HttpClient instance for heavy load issue
---
.../PluginsManager.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index a41a82c67f4..9670f490947 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -17,7 +17,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
- const string zip = "zip";
+ private static readonly HttpClient HttpClient = new();
+
+ private const string zip = "zip";
private PluginInitContext Context { get; set; }
@@ -151,8 +153,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (File.Exists(filePath))
File.Delete(filePath);
- using var httpClient = new HttpClient();
- using var response = await httpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+ using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
@@ -165,7 +166,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
{
if (prgBox != null)
{
- httpClient.CancelPendingRequests();
+ HttpClient.CancelPendingRequests();
downloadCancelled = true;
prgBox = null;
}
From aff6b1aff1fa80fa79e9eecd0a630d1ce3ed7e28 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 6 Jan 2025 21:32:02 +0800
Subject: [PATCH 0126/1335] Perserve prgBox value when force close
---
Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 9670f490947..2923f7eefba 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -168,7 +168,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
{
HttpClient.CancelPendingRequests();
downloadCancelled = true;
- prgBox = null;
}
})) != null)
{
From 8aebf958aa940770c23854167d4c0304a7890fd3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 12:13:46 +0800
Subject: [PATCH 0127/1335] Check ui thread when calling close function &
Update documents
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 7 ++++++-
Flow.Launcher.Plugin/IProgressBoxEx.cs | 4 ++--
.../PluginsManager.cs | 14 +++-----------
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 9a32f730387..f5d34617b86 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -66,11 +66,16 @@ public void ReportProgress(double progress)
private new void Close()
{
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ Application.Current.Dispatcher.Invoke(Close);
+ }
+
if (_isClosed)
{
return;
}
-
+
base.Close();
_isClosed = true;
}
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 6468e3c83a6..27b0618959b 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -6,7 +6,7 @@
public interface IProgressBoxEx
{
///
- /// Show progress box. It should be called from the main ui thread.
+ /// Show progress box.
///
///
/// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
@@ -14,7 +14,7 @@ public interface IProgressBoxEx
public void ReportProgress(double progress);
///
- /// Close progress box. It should be called from the main ui thread.
+ /// Close progress box.
///
public void Close();
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 2923f7eefba..0af2af5ec8f 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,7 +196,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (downloadCancelled)
return;
else
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
}
else
{
@@ -217,7 +217,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (HttpRequestException e)
{
// force close progress box
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
// show error message
Context.API.ShowMsgError(
@@ -230,7 +230,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (Exception e)
{
// force close progress box
- CleanupProgressBoxEx(prgBox);
+ prgBox?.Close();
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
@@ -256,14 +256,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
}
- private static void CleanupProgressBoxEx(IProgressBoxEx prgBox)
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- prgBox?.Close();
- });
- }
-
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
From 122887e6a61f629a4574fe1ebfa62b7a115e9b2f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 16:37:52 +0800
Subject: [PATCH 0128/1335] Await close event from non-ui thread
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 10 ++++++++--
Flow.Launcher.Plugin/IProgressBoxEx.cs | 6 ++++--
.../PluginsManager.cs | 6 +++---
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index f5d34617b86..00f4a8050aa 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
@@ -64,13 +65,18 @@ public void ReportProgress(double progress)
}
}
- private new void Close()
+ public async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- Application.Current.Dispatcher.Invoke(Close);
+ await Application.Current.Dispatcher.InvokeAsync(Close);
}
+ Close();
+ }
+
+ private new void Close()
+ {
if (_isClosed)
{
return;
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
index 27b0618959b..50ee6eb5536 100644
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ b/Flow.Launcher.Plugin/IProgressBoxEx.cs
@@ -1,4 +1,6 @@
-namespace Flow.Launcher.Plugin;
+using System.Threading.Tasks;
+
+namespace Flow.Launcher.Plugin;
///
/// Interface for progress box
@@ -16,5 +18,5 @@ public interface IProgressBoxEx
///
/// Close progress box.
///
- public void Close();
+ public Task CloseAsync();
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 0af2af5ec8f..f5399d53dcc 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -196,7 +196,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (downloadCancelled)
return;
else
- prgBox?.Close();
+ await prgBox?.CloseAsync();
}
else
{
@@ -217,7 +217,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (HttpRequestException e)
{
// force close progress box
- prgBox?.Close();
+ await prgBox?.CloseAsync();
// show error message
Context.API.ShowMsgError(
@@ -230,7 +230,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
catch (Exception e)
{
// force close progress box
- prgBox?.Close();
+ await prgBox?.CloseAsync();
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
From 6220b34aabc7043977ad7316aa0417e7d8e2b1c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 17:33:39 +0800
Subject: [PATCH 0129/1335] Fix dulplicated close event
---
Flow.Launcher.Core/ProgressBoxEx.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
index 00f4a8050aa..dc1f27404a0 100644
--- a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher.Core/ProgressBoxEx.xaml.cs
@@ -70,6 +70,7 @@ public async Task CloseAsync()
if (!Application.Current.Dispatcher.CheckAccess())
{
await Application.Current.Dispatcher.InvokeAsync(Close);
+ return;
}
Close();
From 501633435942fa701c53e25ec0b074df0cbbe3df Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 17:37:53 +0800
Subject: [PATCH 0130/1335] Avoid cancelling all pending requests on shared
HttpClient instance
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f5399d53dcc..081f8d489e6 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -153,7 +153,8 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (File.Exists(filePath))
File.Delete(filePath);
- using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
+ using var cts = new CancellationTokenSource();
+ using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead, cts.Token).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
@@ -166,7 +167,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
{
if (prgBox != null)
{
- HttpClient.CancelPendingRequests();
+ cts.Cancel();
downloadCancelled = true;
}
})) != null)
From ad0270079d9404dd37b385a6d9db8b52e0668d99 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 20:57:43 +0800
Subject: [PATCH 0131/1335] Use System.Text.Json to replace Newtonsoft.Json for
better performance
---
.../Utilities.cs | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
index 9800fa0209c..19f911818fc 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
@@ -1,10 +1,9 @@
using Flow.Launcher.Core.ExternalPlugins;
-using Flow.Launcher.Infrastructure.UserSettings;
using ICSharpCode.SharpZipLib.Zip;
-using Newtonsoft.Json;
using System.IO;
using System.IO.Compression;
using System.Linq;
+using System.Text.Json;
namespace Flow.Launcher.Plugin.PluginsManager
{
@@ -72,12 +71,10 @@ internal static UserPlugin GetPluginInfoFromZip(string filePath)
if (pluginJsonEntry != null)
{
- using (StreamReader reader = new StreamReader(pluginJsonEntry.Open()))
- {
- string pluginJsonContent = reader.ReadToEnd();
- plugin = JsonConvert.DeserializeObject(pluginJsonContent);
- plugin.IcoPath = "Images\\zipfolder.png";
- }
+ using StreamReader reader = new StreamReader(pluginJsonEntry.Open());
+ string pluginJsonContent = reader.ReadToEnd();
+ plugin = JsonSerializer.Deserialize(pluginJsonContent);
+ plugin.IcoPath = "Images\\zipfolder.png";
}
}
From 381e64e69797256980d3353c150fa35fe7273dec Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:13:24 +0800
Subject: [PATCH 0132/1335] Move ProgressBoxEx to main project for better
development experience
---
{Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml | 0
{Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml.cs | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename {Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml (100%)
rename {Flow.Launcher.Core => Flow.Launcher}/ProgressBoxEx.xaml.cs (100%)
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
similarity index 100%
rename from Flow.Launcher.Core/ProgressBoxEx.xaml
rename to Flow.Launcher/ProgressBoxEx.xaml
diff --git a/Flow.Launcher.Core/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
similarity index 100%
rename from Flow.Launcher.Core/ProgressBoxEx.xaml.cs
rename to Flow.Launcher/ProgressBoxEx.xaml.cs
From 20ffff6d1b8464d6aa20c7e32e12aac1e5abd6a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:30:11 +0800
Subject: [PATCH 0133/1335] Use api to call api functions
---
Flow.Launcher/ActionKeywords.xaml.cs | 2 +-
Flow.Launcher/App.xaml.cs | 4 +++-
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 4 ++--
Flow.Launcher/Helper/HotKeyMapper.cs | 2 +-
Flow.Launcher/PriorityChangeWindow.xaml.cs | 4 ++--
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 12 ++++++------
.../ViewModels/SettingsPaneProxyViewModel.cs | 2 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
10 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index ba47a4ded22..c3966e61850 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -44,7 +44,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
else
{
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 4d1adc6cd51..58da35e85b6 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -15,13 +15,15 @@
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp
+ public partial class App : IDisposable, ISingleInstanceApp, IApp
{
+ public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8fa..47460ff7d32 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -63,7 +63,7 @@ public void UpdateItem(CustomPluginHotkey item)
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
Close();
return;
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb35..4589b45ec72 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -43,13 +43,13 @@ private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
{
if (String.IsNullOrEmpty(Key) || String.IsNullOrEmpty(Value))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
return;
}
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
return;
}
DialogResult = !update || originalKey != Key || originalValue != Value;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 8b30b8be1f5..b40406e4282 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -46,7 +46,7 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
{
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
- MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs
index 2154b058d1c..fbe2a941d26 100644
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs
@@ -24,7 +24,7 @@ public PriorityChangeWindow(string pluginId, PluginViewModel pluginViewModel)
this.pluginViewModel = pluginViewModel;
if (plugin == null)
{
- MessageBoxEx.Show(translater.GetTranslation("cannotFindSpecifiedPlugin"));
+ App.API.ShowMsgBox(translater.GetTranslation("cannotFindSpecifiedPlugin"));
Close();
}
}
@@ -44,7 +44,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs e)
else
{
string msg = translater.GetTranslation("invalidPriority");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(msg);
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 6e81db5e00d..05fb16f5cc1 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -62,7 +62,7 @@ private void OpenWelcomeWindow()
[RelayCommand]
private void AskClearLogFolderConfirmation()
{
- var confirmResult = MessageBoxEx.Show(
+ var confirmResult = App.API.ShowMsgBox(
InternationalizationManager.Instance.GetTranslation("clearlogfolderMessage"),
InternationalizationManager.Instance.GetTranslation("clearlogfolder"),
MessageBoxButton.YesNo
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 6d8af9a3f62..fb57f499bbc 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -42,11 +42,11 @@ private void CustomHotkeyDelete()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
),
@@ -67,7 +67,7 @@ private void CustomHotkeyEdit()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -88,11 +88,11 @@ private void CustomShortcutDelete()
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
- var result = MessageBoxEx.Show(
+ var result = App.API.ShowMsgBox(
string.Format(
InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
),
@@ -112,7 +112,7 @@ private void CustomShortcutEdit()
var item = SelectedCustomShortcut;
if (item is null)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
return;
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index 1c840fb2703..e2f9e516ca4 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -22,7 +22,7 @@ public SettingsPaneProxyViewModel(Settings settings, Updater updater)
private void OnTestProxyClicked()
{
var message = TestProxy();
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation(message));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation(message));
}
private string TestProxy()
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 8d8ccb78041..980b2a811a4 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -49,7 +49,7 @@ public bool DropShadowEffect
{
if (ThemeManager.Instance.BlurEnabled && value)
{
- MessageBoxEx.Show(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
+ App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
return;
}
From 8b910500c6f3a2fe170cdc8261c6d0add722b744 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:43:33 +0800
Subject: [PATCH 0134/1335] Add IApp & AppExtensions for accessing the
properties & functions from anywhere in the application
---
Flow.Launcher.Core/AppExtensions.cs | 15 +++++++++++++++
Flow.Launcher.Core/IApp.cs | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 Flow.Launcher.Core/AppExtensions.cs
create mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
new file mode 100644
index 00000000000..b02612d72f9
--- /dev/null
+++ b/Flow.Launcher.Core/AppExtensions.cs
@@ -0,0 +1,15 @@
+using System.Windows;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core;
+
+///
+/// Extension properties and functions of the current application singleton object.
+///
+public static class AppExtensions
+{
+ ///
+ /// Gets the public API of the current application singleton object.
+ ///
+ public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
+}
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
new file mode 100644
index 00000000000..233fd5ed1c3
--- /dev/null
+++ b/Flow.Launcher.Core/IApp.cs
@@ -0,0 +1,13 @@
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Core
+{
+ ///
+ /// Interface for the current application singleton object exposing the properties
+ /// and functions that can be accessed from anywhere in the application.
+ ///
+ public interface IApp
+ {
+ public IPublicAPI PublicAPI { get; }
+ }
+}
From 88e84378daee2906bdbfa131ba4d012225464df1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:44:24 +0800
Subject: [PATCH 0135/1335] Use api in app extensions to call api functions
---
Flow.Launcher.Core/Configuration/Portable.cs | 20 +++++++++----------
.../Environments/AbstractPluginEnvironment.cs | 6 +++---
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 2 +-
.../Resource/Internationalization.cs | 2 +-
Flow.Launcher.Core/Resource/Theme.cs | 4 ++--
Flow.Launcher.Core/Updater.cs | 10 +++++-----
10 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index d7c73fb46ac..cb375c58639 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -40,7 +40,7 @@ public void DisablePortableMode()
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +64,7 @@ public void EnablePortableMode()
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- MessageBoxEx.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +95,13 @@ public void RemoveUninstallerEntry()
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +157,13 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
+ if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +172,9 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
- MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
+ AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +186,7 @@ public bool CanUpdatePortability()
if (roamingLocationExists && portableLocationExists)
{
- MessageBoxEx.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 6d41e23834e..cada0503197 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -57,7 +57,7 @@ internal IEnumerable Setup()
EnvName,
Environment.NewLine
);
- if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +82,7 @@ internal IEnumerable Setup()
}
else
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +98,7 @@ private void EnsureLatestInstalled(string expectedPath, string currentPath, stri
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 96c29646e8f..56bc20b4f4d 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ internal PythonEnvironment(List pluginMetadataList, PluginsSetti
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 0d6f109e07f..1d43b815a21 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ internal TypeScriptEnvironment(List pluginMetadataList, PluginsS
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 582a4407c45..49bf4e958f0 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ internal TypeScriptV2Environment(List pluginMetadataList, Plugin
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1dadc..9e1cf3b9d13 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 7973c66baa7..8cbeb7473f7 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -119,7 +119,7 @@ public static IEnumerable DotNetPlugins(List source)
_ = Task.Run(() =>
{
- MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1505e84f819..a1cefabe381 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -124,7 +124,7 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (MessageBoxEx.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 1d840930663..8622d4caf05 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -108,7 +108,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +118,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index b92d8656873..8745d54b792 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -53,7 +53,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- MessageBoxEx.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +68,9 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show);
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show))
- MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
+ AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +83,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
From d36aef57e9bff40af03ab6143753b0cfd4b14348 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 9 Jan 2025 21:48:13 +0800
Subject: [PATCH 0136/1335] Change ProgressBoxEx namespace
---
Flow.Launcher/ProgressBoxEx.xaml | 4 ++--
Flow.Launcher/ProgressBoxEx.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
index 4cce822217e..3102cfb7255 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml
+++ b/Flow.Launcher/ProgressBoxEx.xaml
@@ -1,9 +1,9 @@
Date: Thu, 9 Jan 2025 21:50:07 +0800
Subject: [PATCH 0137/1335] Move MessageBoxEx to main project for better
development experience
---
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml | 4 ++--
{Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml (98%)
rename {Flow.Launcher.Core => Flow.Launcher}/MessageBoxEx.xaml.cs (99%)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher/MessageBoxEx.xaml
similarity index 98%
rename from Flow.Launcher.Core/MessageBoxEx.xaml
rename to Flow.Launcher/MessageBoxEx.xaml
index fff107a68a4..be12ca16c20 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher/MessageBoxEx.xaml
@@ -1,9 +1,9 @@
Date: Thu, 9 Jan 2025 12:48:43 -0600
Subject: [PATCH 0138/1335] resolve link before using File.Replace
---
.../Storage/JsonStorage.cs | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 64225062785..33bc1ff6c9c 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -31,11 +31,12 @@ namespace Flow.Launcher.Infrastructure.Storage
protected JsonStorage()
{
}
+
public JsonStorage(string filePath)
{
FilePath = filePath;
DirectoryPath = Path.GetDirectoryName(filePath) ?? throw new ArgumentException("Invalid file path");
-
+
Helper.ValidateDirectory(DirectoryPath);
}
@@ -97,6 +98,7 @@ private async ValueTask LoadBackupOrDefaultAsync()
return default;
}
}
+
private void RestoreBackup()
{
Log.Info($"|JsonStorage.Load|Failed to load settings.json, {BackupFilePath} restored successfully");
@@ -179,25 +181,21 @@ private void BackupOriginFile()
public void Save()
{
string serialized = JsonSerializer.Serialize(Data,
- new JsonSerializerOptions
- {
- WriteIndented = true
- });
+ new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(TempFilePath, serialized);
AtomicWriteSetting();
}
+
public async Task SaveAsync()
{
var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
- new JsonSerializerOptions
- {
- WriteIndented = true
- });
+ new JsonSerializerOptions { WriteIndented = true });
AtomicWriteSetting();
}
+
private void AtomicWriteSetting()
{
if (!File.Exists(FilePath))
@@ -206,9 +204,9 @@ private void AtomicWriteSetting()
}
else
{
- File.Replace(TempFilePath, FilePath, BackupFilePath);
+ var finalFilePath = new FileInfo(FilePath).LinkTarget ?? FilePath;
+ File.Replace(TempFilePath, finalFilePath, BackupFilePath);
}
}
-
}
}
From cfc0534a545b4a369b850057800862406c28347d Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 9 Jan 2025 22:52:09 -0600
Subject: [PATCH 0139/1335] Bump SemanticVersioning from 3.0.0-beta2 to 3.0.0
(#3172)
Bumps [SemanticVersioning](https://github.com/adamreeve/semver.net) from 3.0.0-beta2 to 3.0.0.
- [Release notes](https://github.com/adamreeve/semver.net/releases)
- [Commits](https://github.com/adamreeve/semver.net/compare/3.0.0-beta2...3.0.0)
---
updated-dependencies:
- dependency-name: SemanticVersioning
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 4ec249c2b79..788beddfb37 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -99,7 +99,7 @@
-
+
From ed7265d24457e2934a02ab3a1959a3222996219c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 13:06:37 +0800
Subject: [PATCH 0140/1335] Remove override close event
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index eff0bd80c49..507710e90c9 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -10,7 +10,6 @@ namespace Flow.Launcher
public partial class ProgressBoxEx : Window, IProgressBoxEx
{
private readonly Action _forceClosed;
- private bool _isClosed;
private ProgressBoxEx(Action forceClosed)
{
@@ -76,17 +75,6 @@ public async Task CloseAsync()
Close();
}
- private new void Close()
- {
- if (_isClosed)
- {
- return;
- }
-
- base.Close();
- _isClosed = true;
- }
-
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
ForceClose();
@@ -104,13 +92,7 @@ private void Button_Cancel(object sender, RoutedEventArgs e)
private void ForceClose()
{
- if (_isClosed)
- {
- return;
- }
-
- base.Close();
- _isClosed = true;
+ Close();
_forceClosed?.Invoke();
}
}
From f1746b09e02ed16be46f142a45f55c4340f33417 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 10 Jan 2025 16:26:20 +1100
Subject: [PATCH 0141/1335] New Crowdin updates (#3149)
New translations
---
Flow.Launcher/Languages/de.xaml | 4 +-
Flow.Launcher/Languages/es.xaml | 4 +-
Flow.Launcher/Languages/he.xaml | 108 +++++++++---------
.../Languages/he.xaml | 28 ++---
.../Properties/Resources.de-DE.resx | 4 +-
5 files changed, 74 insertions(+), 74 deletions(-)
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 7f2e2bd8d03..c7e775ae319 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -65,8 +65,8 @@
Letzte Abfrage beibehalten
Letzte Abfrage auswählen
Letzte Abfrage leeren
- Preserve Last Action Keyword
- Select Last Action Keyword
+ Letztes Aktions-Schlüsselwort beibehalten
+ Letztes Aktions-Schlüsselwort auswählen
Feste Fensterhöhe
Die Fensterhöhe ist durch Ziehen nicht anpassbar.
Maximal gezeigte Ergebnisse
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index bf22aea48c9..c7595f69ba6 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -65,8 +65,8 @@
Mantener la última consulta
Seleccionar la última consulta
Limpiar la última consulta
- Conservar palabra clave de última acción
- Seleccionar palabra clave de última acción
+ Conservar última palabra clave de acción
+ Seleccionar última palabra clave de acción
Altura de la ventana fija
La altura de la ventana no se puede ajustar arrastrando el ratón.
Número máximo de resultados mostrados
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index eeb33da1727..f3c9bb3079f 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -9,7 +9,7 @@
אנא בחר את קובץ ההפעלה {0}
לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).
נכשל בהפעלת תוספים
- תוספים: {0} - נכשלים בטעינה ויהיו מושבתים, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
+ תוספים: {0} - נכשלו בטעינה ויושבתו, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
רישום מקש הקיצור "{0}" נכשל. ייתכן שמקש הקיצור נמצא בשימוש על ידי תוכנה אחרת. שנה למקש קיצור אחר, או צא מהתוכנה האחרת.
@@ -54,10 +54,10 @@
צג ראשי
צג מותאם אישית
Search Window Position on Monitor
- Center
- Center Top
- Left Top
- Right Top
+ מרכז
+ מרכז עליון
+ שמאל עליון
+ ימין עליון
Custom Position
שפה
Last Query Style
@@ -83,16 +83,16 @@
Please select pythonw.exe
Always Start Typing in English Mode
Temporarily change your input method to English mode when activating Flow.
- Auto Update
- Select
+ עדכון אוטומטי
+ בחר
Hide Flow Launcher on startup
Flow Launcher search window is hidden in the tray after starting up.
Hide tray icon
When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.
Query Search Precision
Changes minimum match score required for results.
- None
- Low
+ ללא
+ נמוך
Regular
Search with Pinyin
Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
@@ -120,26 +120,26 @@
Priority
Change Plugin Results Priority
Plugin Directory
- by
+ מאת
Init time:
Query time:
- Version
- Website
- Uninstall
+ גרסה
+ אתר
+ הסר התקנה
חנות תוספים
- New Release
+ שחרור חדש
Recently Updated
תוספים
- Installed
+ מותקן
רענן
התקן
- Uninstall
+ הסר התקנה
עדכון
Plugin already installed
- New Version
+ גרסה חדשה
This plugin has been updated within the last 7 days
New Update is Available
@@ -164,7 +164,7 @@
Query Box Font
Result Title Font
Result Subtitle Font
- Reset
+ אפס
Customize
Window Mode
Opacity
@@ -196,9 +196,9 @@
- Hotkey
- Hotkeys
- Open Flow Launcher
+ מקש קיצור
+ מקשי קיצור
+ פתח את Flow Launcher
Enter shortcut to show/hide Flow Launcher.
Toggle Preview
Enter shortcut to show/hide preview in search window.
@@ -206,24 +206,24 @@
List of currently registered hotkeys
Open Result Modifier Key
Select a modifier key to open selected result via keyboard.
- Show Hotkey
+ הצג מקש קיצור
Show result selection hotkey with results.
Auto Complete
Runs autocomplete for the selected items.
Select Next Item
Select Previous Item
- Next Page
- Previous Page
+ הדף הבא
+ הדף הקודם
Cycle Previous Query
Cycle Next Query
Open Context Menu
Open Native Context Menu
Open Setting Window
- Copy File Path
+ העתק את נתיב הקובץ
Toggle Game Mode
Toggle History
Open Containing Folder
- Run As Admin
+ הרץ כמנהל
Refresh Search Results
Reload Plugins Data
Quick Adjust Window Width
@@ -234,13 +234,13 @@
Custom Query Shortcuts
Built-in Shortcuts
שאילתה
- Shortcut
- Expansion
- Description
+ קיצור דרך
+ הרחבה
+ תיאור
מחק
ערוך
הוסף
- None
+ ללא
אנא בחר פריט
Are you sure you want to delete {0} plugin hotkey?
Are you sure you want to delete shortcut: {0} with expansion {1}?
@@ -259,8 +259,8 @@
Enable HTTP Proxy
HTTP Server
Port
- User Name
- Password
+ שם משתמש
+ סיסמא
Test Proxy
שמור
Server field can't be empty
@@ -272,11 +272,11 @@
אודות
- Website
- GitHub
- Docs
- Version
- Icons
+ אתר אינטרנט
+ Github
+ תיעוד
+ גרסה
+ סמלים
You have activated Flow Launcher {0} times
Check for Updates
Become A Sponsor
@@ -302,8 +302,8 @@
Select File Manager
Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
- File Manager
- Profile Name
+ מנהל קבצים
+ שם פרופיל
File Manager Path
Arg For Folder
Arg For File
@@ -314,9 +314,9 @@
Browser
Browser Name
Browser Path
- New Window
- New Tab
- Private Mode
+ חלון חדש
+ כרטיסייה חדשה
+ מצב פרטיות
Change Priority
@@ -362,14 +362,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
שמור
Overwrite
ביטול
- Reset
+ אפס
מחק
- OK
- Yes
- No
+ אישור
+ כן
+ לא
- Version
+ גרסה
זמן
Please tell us how application crashed so we can fix it
שלח דיווח
@@ -377,21 +377,21 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
כללי
חריגים
Exception Type
- Source
+ מקור
Stack Trace
- Sending
+ שולח
Report sent successfully
Failed to send report
Flow Launcher got an error
- Please wait...
+ אנא המתן...
Checking for new update
You already have the latest Flow Launcher version
- Update found
- Updating...
+ עדכון נמצא
+ מעדכן...
Flow Launcher was not able to move your user profile data to the new update version.
Please manually move your profile data folder from {0} to {1}
@@ -405,7 +405,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.
This upgrade will restart Flow Launcher
Following files will be updated
- Update files
+ עדכן קבצים
Update description
@@ -416,7 +416,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
Search and run all files and applications on your PC
Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.
- Hotkeys
+ מקשי קיצור
Action Keyword and Commands
Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.
Let's Start Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
index 0e1753d6745..f87dd7d6336 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/he.xaml
@@ -29,8 +29,8 @@
Everything Setting
Preview Panel
Size
- Date Created
- Date Modified
+ תאריך יצירה
+ תאריך שינוי
Display File Info
Date and time format
Sort Option:
@@ -126,20 +126,20 @@
Failed to load Everything SDK
אזהרה: שירות Everything אינו פועל
שגיאה במהלך שאילתה לEverything
- Sort By
+ מיין לפי
Name
- Path
+ נתיב
Size
Extension
Type Name
- Date Created
- Date Modified
- Attributes
+ תאריך יצירה
+ תאריך שינוי
+ מאפיינים
File List FileName
Run Count
- Date Recently Changed
- Date Accessed
- Date Run
+ תאריך שינוי אחרון
+ תאריך גישה
+ תאריך הרצה
↑
↓
Warning: This is not a Fast Sort option, searches may be slow
@@ -149,11 +149,11 @@
Click to launch or install Everything
Everything Installation
- Installing Everything service. Please wait...
- Successfully installed Everything service
- Failed to automatically install Everything service. Please manually install it from https://www.voidtools.com
+ מתקין את שירות Everything. אנא המתן...
+ שירות Everything הותקן בהצלחה
+ התקנה אוטומטית של שירות Everything נכשלה. אנא הורד אותו ידנית מ- https://www.voidtools.com
Click here to start it
- Unable to find an Everything installation, would you like to manually select a location?{0}{0}Click no and Everything will be automatically installed for you
+ לא מצליח למצוא התקנה של Everything, האם תרצה לבחור מיקום באופן ידני?{0}{0}לחץ על לא וEverything יותקן עבורך אוטומטית
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
index dac5f82bca3..dcc74d52031 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
@@ -2130,7 +2130,7 @@
Ändern, wie der Mauszeiger ausschaut
- Change power-saving settings
+ Energiespareinstellungen ändern
Optimieren für Blindheit
@@ -2143,7 +2143,7 @@
Windows-Features ein- oder ausschalten
- Show which operating system your computer is running
+ Betriebssystem, welches auf deinem Computer läuft, anzeigen
Lokale Dienste ansehen
From 95b4c4c766bc07b77285f7e7a0e525d35c6b08d0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 13:34:10 +0800
Subject: [PATCH 0142/1335] Improve code quality
---
Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
index 19f911818fc..743f5b25bff 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
@@ -71,9 +71,8 @@ internal static UserPlugin GetPluginInfoFromZip(string filePath)
if (pluginJsonEntry != null)
{
- using StreamReader reader = new StreamReader(pluginJsonEntry.Open());
- string pluginJsonContent = reader.ReadToEnd();
- plugin = JsonSerializer.Deserialize(pluginJsonContent);
+ using Stream stream = pluginJsonEntry.Open();
+ plugin = JsonSerializer.Deserialize(stream);
plugin.IcoPath = "Images\\zipfolder.png";
}
}
From 297d1914127fd10d9ac230438e7a327d362dbc6f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 19:13:19 +0800
Subject: [PATCH 0143/1335] Use function to delegate the progress task
---
Flow.Launcher.Plugin/IProgressBoxEx.cs | 22 ------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 7 +-
Flow.Launcher/ProgressBoxEx.xaml.cs | 50 ++++++++-----
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../PluginsManager.cs | 72 +++++++++----------
5 files changed, 74 insertions(+), 79 deletions(-)
delete mode 100644 Flow.Launcher.Plugin/IProgressBoxEx.cs
diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
deleted file mode 100644
index 50ee6eb5536..00000000000
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Flow.Launcher.Plugin;
-
-///
-/// Interface for progress box
-///
-public interface IProgressBoxEx
-{
- ///
- /// Show progress box.
- ///
- ///
- /// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
- ///
- public void ReportProgress(double progress);
-
- ///
- /// Close progress box.
- ///
- public Task CloseAsync();
-}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 9cd45a1d313..c4bfd7033fb 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,8 +322,13 @@ public interface IPublicAPI
/// If there is issue when showing the message box, it will return null.
///
/// The caption of the message box.
+ ///
+ /// Time-consuming task function, whose input is the action to report progress.
+ /// The input of the action is the progress value which is a double value between 0 and 100.
+ /// If there are any exceptions, this action will be null.
+ ///
/// When user closes the progress box manually by button or esc key, this action will be called.
/// A progress box interface.
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 507710e90c9..37ee2b0cb29 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -3,11 +3,10 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin;
namespace Flow.Launcher
{
- public partial class ProgressBoxEx : Window, IProgressBoxEx
+ public partial class ProgressBoxEx : Window
{
private readonly Action _forceClosed;
@@ -17,31 +16,48 @@ private ProgressBoxEx(Action forceClosed)
InitializeComponent();
}
- public static IProgressBoxEx Show(string caption, Action forceClosed = null)
+ public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null)
{
- if (!Application.Current.Dispatcher.CheckAccess())
- {
- return Application.Current.Dispatcher.Invoke(() => Show(caption, forceClosed));
- }
-
+ ProgressBoxEx prgBox = null;
try
{
- var prgBox = new ProgressBoxEx(forceClosed)
+ if (!Application.Current.Dispatcher.CheckAccess())
{
- Title = caption
- };
- prgBox.TitleTextBlock.Text = caption;
- prgBox.Show();
- return prgBox;
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ prgBox = new ProgressBoxEx(forceClosed)
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ });
+ }
+
+ await reportProgressAsync(prgBox.ReportProgress).ConfigureAwait(false);
}
catch (Exception e)
{
Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
- return null;
+
+ await reportProgressAsync(null).ConfigureAwait(false);
+ }
+ finally
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ await Application.Current.Dispatcher.InvokeAsync(async () =>
+ {
+ if (prgBox != null)
+ {
+ await prgBox.CloseAsync();
+ }
+ });
+ }
}
}
- public void ReportProgress(double progress)
+ private void ReportProgress(double progress)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
@@ -64,7 +80,7 @@ public void ReportProgress(double progress)
}
}
- public async Task CloseAsync()
+ private async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b403d604662..95d371fb09f 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ public bool IsGameModeOn()
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null) => ProgressBoxEx.Show(caption, forceClosed);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);
#endregion
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 081f8d489e6..c3ed04a4da2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -144,7 +144,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- IProgressBoxEx prgBox = null;
var downloadCancelled = false;
try
{
@@ -162,42 +161,45 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var canReportProgress = totalBytes != -1;
var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- if (canReportProgress &&
- (prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
- {
- if (prgBox != null)
- {
- cts.Cancel();
- downloadCancelled = true;
- }
- })) != null)
+ if (canReportProgress)
{
- await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
-
- var buffer = new byte[8192];
- long totalRead = 0;
- int read;
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
+ {
+ // cannot use progress box
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ }
+ else
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
- while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
- {
- await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
- totalRead += read;
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
- var progressValue = totalRead * 100 / totalBytes;
+ while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
+ totalRead += read;
- // check if user cancelled download before reporting progress
- if (downloadCancelled)
- return;
- else
- prgBox.ReportProgress(progressValue);
- }
+ var progressValue = totalRead * 100 / totalBytes;
- // check if user cancelled download before closing progress box
- if (downloadCancelled)
- return;
- else
- await prgBox?.CloseAsync();
+ // check if user cancelled download before reporting progress
+ if (downloadCancelled)
+ return;
+ else
+ reportProgress(progressValue);
+ }
+ }
+ },
+ () =>
+ {
+ cts.Cancel();
+ downloadCancelled = true;
+ });
}
else
{
@@ -217,9 +219,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
catch (HttpRequestException e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
@@ -230,9 +229,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
catch (Exception e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
From cc921c7d291b45b4128cdb2b1423a2631a6ee422 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 10 Jan 2025 19:17:54 +0800
Subject: [PATCH 0144/1335] Improve progress box when exception happens
---
.../PluginsManager.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index c3ed04a4da2..b6495d8f260 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -145,6 +145,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
var downloadCancelled = false;
+ var exceptionHappened = false;
try
{
if (!plugin.IsFromLocalInstallPath)
@@ -168,8 +169,10 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
{
if (reportProgress == null)
{
- // cannot use progress box
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
}
else
{
@@ -200,6 +203,11 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
cts.Cancel();
downloadCancelled = true;
});
+
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!downloadCancelled))
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
}
else
{
From 4b38e0e714abf705e8f337dbcb26f29893105c7e Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 10 Jan 2025 13:11:35 -0600
Subject: [PATCH 0145/1335] properly dispose the filestream
---
Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 33bc1ff6c9c..507838d9477 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -190,7 +190,7 @@ public void Save()
public async Task SaveAsync()
{
- var tempOutput = File.OpenWrite(TempFilePath);
+ await using var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
new JsonSerializerOptions { WriteIndented = true });
AtomicWriteSetting();
From 2a1d502affe50f43aafd38e7ee3ff5435993cbef Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 10 Jan 2025 13:18:14 -0600
Subject: [PATCH 0146/1335] fix build error
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index ae4fd639d07..f95266c7fe0 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -138,7 +138,7 @@ public virtual async Task ReloadDataAsync()
SetupJsonRPC();
try
{
- await RPC.InvokeAsync("reload", context);
+ await RPC.InvokeAsync("reload", Context);
}
catch (RemoteMethodNotFoundException e)
{
From a9d77d8bcfa423b4b4db67cff8a8bc97a223ad3e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 10 Jan 2025 19:31:36 +0000
Subject: [PATCH 0147/1335] Bump Mages from 2.0.2 to 3.0.0 (#3154)
---
.../Flow.Launcher.Plugin.Calculator.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
index 69c03b877fd..1b985acf9b1 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
@@ -62,7 +62,7 @@
-
+
\ No newline at end of file
From 2de63f73a5bb3eb64a61a04ab190b39ab466d2f5 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Fri, 10 Jan 2025 13:36:09 -0600
Subject: [PATCH 0148/1335] change equality related testing
---
Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
index 3d05e56796f..b4e0736c6c2 100644
--- a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
+++ b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
@@ -78,8 +78,8 @@ public async Task GivenModel_WhenSerializeWithDifferentNamingPolicy_ThenExpectSa
foreach (var ((result1, result2), referenceResult) in results1.Zip(results2).Zip(reference.Result))
{
- Assert.AreEqual(result1, result2);
- Assert.AreEqual(result1, referenceResult);
+ Assert.AreEqual(result1.Title, result2.Title);
+ Assert.AreEqual(result1.Title, referenceResult.Title);
Assert.IsNotNull(result1);
Assert.IsNotNull(result1.AsyncAction);
From df3cb58c6c2bac0f71e73a003f99b04a881d83d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 12:38:08 +0800
Subject: [PATCH 0149/1335] Improve code quality
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 37ee2b0cb29..a04ed057685 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -46,12 +46,9 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
{
if (!Application.Current.Dispatcher.CheckAccess())
{
- await Application.Current.Dispatcher.InvokeAsync(async () =>
+ await Application.Current.Dispatcher.InvokeAsync(() =>
{
- if (prgBox != null)
- {
- await prgBox.CloseAsync();
- }
+ prgBox?.Close();
});
}
}
@@ -80,17 +77,6 @@ private void ReportProgress(double progress)
}
}
- private async Task CloseAsync()
- {
- if (!Application.Current.Dispatcher.CheckAccess())
- {
- await Application.Current.Dispatcher.InvokeAsync(Close);
- return;
- }
-
- Close();
- }
-
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
{
ForceClose();
From 029cb38c61855756cfcc4e75dc833c987bcbc50b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 13:19:45 +0800
Subject: [PATCH 0150/1335] Fix progress box action under ui thread
---
Flow.Launcher/ProgressBoxEx.xaml.cs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index a04ed057685..7c55d62c0e5 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -33,6 +33,15 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
prgBox.Show();
});
}
+ else
+ {
+ prgBox = new ProgressBoxEx(forceClosed)
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ }
await reportProgressAsync(prgBox.ReportProgress).ConfigureAwait(false);
}
@@ -51,6 +60,10 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
prgBox?.Close();
});
}
+ else
+ {
+ prgBox?.Close();
+ }
}
}
From 8eb5a4dfcaa063d647f31e01211a4ef947344849 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 11 Jan 2025 13:24:41 +0800
Subject: [PATCH 0151/1335] Improve HttpDownloadAsync function & Use it in
PluginManager plugin
---
.../JsonRPCV2Models/JsonRPCPublicAPI.cs | 7 +-
Flow.Launcher.Infrastructure/Http/Http.cs | 41 +++++++++-
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 +-
Flow.Launcher/PublicAPIInstance.cs | 4 +-
.../PluginsManager.cs | 82 +++++--------------
5 files changed, 68 insertions(+), 72 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index b8bfee591e6..a82cae5d254 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
@@ -121,10 +120,10 @@ public Task HttpGetStreamAsync(string url, CancellationToken token = def
return _api.HttpGetStreamAsync(url, token);
}
- public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
+ public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null,
CancellationToken token = default)
{
- return _api.HttpDownloadAsync(url, filePath, token);
+ return _api.HttpDownloadAsync(url, filePath, reportProgress, token);
}
public void AddActionKeyword(string pluginId, string newActionKeyword)
@@ -162,13 +161,11 @@ public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null
_api.OpenDirectory(DirectoryPath, FileNameOrFilePath);
}
-
public void OpenUrl(string url, bool? inPrivate = null)
{
_api.OpenUrl(url, inPrivate);
}
-
public void OpenAppUri(string appUri)
{
_api.OpenAppUri(appUri);
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 14b8eef4e16..0b5d1b05a1a 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -83,15 +83,50 @@ var userName when string.IsNullOrEmpty(userName) =>
}
}
- public static async Task DownloadAsync([NotNull] string url, [NotNull] string filePath, CancellationToken token = default)
+ public static async Task DownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default)
{
try
{
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
+
if (response.StatusCode == HttpStatusCode.OK)
{
- await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
- await response.Content.CopyToAsync(fileStream, token);
+ var totalBytes = response.Content.Headers.ContentLength ?? -1L;
+ var canReportProgress = totalBytes != -1;
+
+ if (canReportProgress && reportProgress != null)
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync(token);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
+ double progressValue = 0;
+
+ reportProgress(0);
+
+ while ((read = await contentStream.ReadAsync(buffer, token)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read), token);
+ totalRead += read;
+
+ progressValue = totalRead * 100.0 / totalBytes;
+
+ if (token.IsCancellationRequested)
+ return;
+ else
+ reportProgress(progressValue);
+ }
+
+ if (progressValue < 100)
+ reportProgress(100);
+ }
+ else
+ {
+ await using var fileStream = new FileStream(filePath, FileMode.CreateNew);
+ await response.Content.CopyToAsync(fileStream, token);
+ }
}
else
{
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index c4bfd7033fb..8376fd07ba7 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -181,9 +181,13 @@ public interface IPublicAPI
///
/// URL to download file
/// path to save downloaded file
+ ///
+ /// Action to report progress. The input of the action is the progress value which is a double value between 0 and 100.
+ /// It will be called if url support range request and the reportProgress is not null.
+ ///
/// place to store file
/// Task showing the progress
- Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, CancellationToken token = default);
+ Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default);
///
/// Add ActionKeyword for specific plugin
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 95d371fb09f..7706a64ba9d 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -164,8 +164,8 @@ public MatchResult FuzzySearch(string query, string stringToCompare) =>
public Task HttpGetStreamAsync(string url, CancellationToken token = default) =>
Http.GetStreamAsync(url);
- public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
- CancellationToken token = default) => Http.DownloadAsync(url, filePath, token);
+ public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null,
+ CancellationToken token = default) => Http.DownloadAsync(url, filePath, reportProgress, token);
public void AddActionKeyword(string pluginId, string newActionKeyword) =>
PluginManager.AddActionKeyword(pluginId, newActionKeyword);
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index b6495d8f260..aee76e65ebf 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -17,8 +17,6 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
- private static readonly HttpClient HttpClient = new();
-
private const string zip = "zip";
private PluginInitContext Context { get; set; }
@@ -144,75 +142,37 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- var downloadCancelled = false;
var exceptionHappened = false;
try
{
+ using var cts = new CancellationTokenSource();
+
if (!plugin.IsFromLocalInstallPath)
{
if (File.Exists(filePath))
File.Delete(filePath);
- using var cts = new CancellationTokenSource();
- using var response = await HttpClient.GetAsync(plugin.UrlDownload, HttpCompletionOption.ResponseHeadersRead, cts.Token).ConfigureAwait(false);
-
- response.EnsureSuccessStatusCode();
-
- var totalBytes = response.Content.Headers.ContentLength ?? -1L;
- var canReportProgress = totalBytes != -1;
-
var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- if (canReportProgress)
- {
- await Context.API.ShowProgressBoxAsync(prgBoxTitle,
- async (reportProgress) =>
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
{
- if (reportProgress == null)
- {
- // when reportProgress is null, it means there is expcetion with the progress box
- // so we record it with exceptionHappened and return so that progress box will close instantly
- exceptionHappened = true;
- return;
- }
- else
- {
- await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
-
- var buffer = new byte[8192];
- long totalRead = 0;
- int read;
-
- while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
- {
- await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
- totalRead += read;
-
- var progressValue = totalRead * 100 / totalBytes;
-
- // check if user cancelled download before reporting progress
- if (downloadCancelled)
- return;
- else
- reportProgress(progressValue);
- }
- }
- },
- () =>
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
+ }
+ else
{
- cts.Cancel();
- downloadCancelled = true;
- });
-
- // if exception happened while downloading and user does not cancel downloading,
- // we need to redownload the plugin
- if (exceptionHappened && (!downloadCancelled))
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- }
- else
- {
- await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
- }
+ await Http.DownloadAsync(plugin.UrlDownload, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ }
+ }, cts.Cancel);
+
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!cts.IsCancellationRequested))
+ await Http.DownloadAsync(plugin.UrlDownload, filePath, null, cts.Token).ConfigureAwait(false);
}
else
{
@@ -220,7 +180,7 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
}
// check if user cancelled download before installing plugin
- if (downloadCancelled)
+ if (cts.IsCancellationRequested)
return;
else
Install(plugin, filePath);
From 32cac76c827681b436bd8bdc8de03e608181260c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 18:44:52 +0800
Subject: [PATCH 0152/1335] Improve Settings management
---
.../UserSettings/Settings.cs | 16 ++++++++++++++--
Flow.Launcher/App.xaml.cs | 8 ++++++--
.../ViewModel/SettingWindowViewModel.cs | 13 +++----------
3 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0bcc9368d22..3e43e3d32b5 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text.Json.Serialization;
using System.Windows;
using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
@@ -13,6 +13,18 @@ namespace Flow.Launcher.Infrastructure.UserSettings
{
public class Settings : BaseModel, IHotkeySettings
{
+ private FlowLauncherJsonStorage _storage;
+
+ public void Initialize(FlowLauncherJsonStorage storage)
+ {
+ _storage = storage;
+ }
+
+ public void Save()
+ {
+ _storage.Save();
+ }
+
private string language = "en";
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 58da35e85b6..9d7a0671e2d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -14,6 +14,7 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -52,6 +53,10 @@ private async void OnStartupAsync(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+
_portable.PreStartCleanUpAfterPortabilityUpdate();
Log.Info(
@@ -62,8 +67,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_updater, _portable);
- _settings = _settingsVM.Settings;
+ _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
_settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 04dd6312b37..95a1eb67553 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,6 +1,5 @@
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
-using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -8,21 +7,17 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- private readonly FlowLauncherJsonStorage _storage;
-
public Updater Updater { get; }
public IPortable Portable { get; }
public Settings Settings { get; }
- public SettingWindowViewModel(Updater updater, IPortable portable)
+ public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
{
- _storage = new FlowLauncherJsonStorage();
-
+ Settings = settings;
Updater = updater;
Portable = portable;
- Settings = _storage.Load();
}
public async void UpdateApp()
@@ -30,14 +25,12 @@ public async void UpdateApp()
await Updater.UpdateAppAsync(App.API, false);
}
-
-
///
/// Save Flow settings. Plugins settings are not included.
///
public void Save()
{
- _storage.Save();
+ Settings.Save();
}
public double SettingWindowWidth
From 1b76a2bc1a1c3356b3bab5c3be61b3427b1de7fd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:45:36 +0800
Subject: [PATCH 0153/1335] Use dependency injection for all services
---
.../Flow.Launcher.Infrastructure.csproj | 1 +
.../PinyinAlphabet.cs | 8 ++-
Flow.Launcher.Infrastructure/StringMatcher.cs | 5 +-
Flow.Launcher/App.xaml.cs | 65 +++++++++++--------
Flow.Launcher/Flow.Launcher.csproj | 5 +-
Flow.Launcher/PublicAPIInstance.cs | 12 ++--
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +-
.../ViewModel/SettingWindowViewModel.cs | 11 ++--
8 files changed, 67 insertions(+), 45 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index 1475252caee..84b6031613a 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -54,6 +54,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
index 7d72359684d..8eaa757bec1 100644
--- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
+++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@@ -6,6 +6,7 @@
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure
{
@@ -129,7 +130,12 @@ public class PinyinAlphabet : IAlphabet
private Settings _settings;
- public void Initialize([NotNull] Settings settings)
+ public PinyinAlphabet()
+ {
+ Initialize(Ioc.Default.GetRequiredService());
+ }
+
+ private void Initialize([NotNull] Settings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index bd5dbdda9be..7134fc7603a 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Plugin.SharedModels;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin.SharedModels;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -15,7 +16,7 @@ public class StringMatcher
public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = alphabet;
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9d7a0671e2d..8cd054148a9 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.ExternalPlugins.Environments;
@@ -18,23 +19,18 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
- public partial class App : IDisposable, ISingleInstanceApp, IApp
+ public partial class App : IDisposable, ISingleInstanceApp
{
- public IPublicAPI PublicAPI => API;
public static PublicAPIInstance API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
- private MainViewModel _mainVM;
- private SettingWindowViewModel _settingsVM;
- private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo);
- private readonly Portable _portable = new Portable();
- private readonly PinyinAlphabet _alphabet = new PinyinAlphabet();
- private StringMatcher _stringMatcher;
[STAThread]
public static void Main()
@@ -53,37 +49,51 @@ private async void OnStartupAsync(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ // Initialize settings
var storage = new FlowLauncherJsonStorage();
_settings = storage.Load();
_settings.Initialize(storage);
-
- _portable.PreStartCleanUpAfterPortabilityUpdate();
-
- Log.Info(
- "|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
+
+ Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
+
+ Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+
+ Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
+
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
var imageLoadertask = ImageLoader.InitializeAsync();
- _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
- _alphabet.Initialize(_settings);
- _stringMatcher = new StringMatcher(_alphabet);
- StringMatcher.Instance = _stringMatcher;
- _stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
+ var stringMatcher = Ioc.Default.GetRequiredService();
+ StringMatcher.Instance = stringMatcher;
+ stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
InternationalizationManager.Instance.Settings = _settings;
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
PluginManager.LoadPlugins(_settings.PluginSettings);
- _mainVM = new MainViewModel(_settings);
- API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet);
+ API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -91,14 +101,15 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
await PluginManager.InitializePluginsAsync(API);
await imageLoadertask;
- var window = new MainWindow(_settings, _mainVM);
+ var mainVM = Ioc.Default.GetRequiredService();
+ var window = new MainWindow(_settings, mainVM);
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = window;
Current.MainWindow.Title = Constant.FlowLauncher;
- HotKeyMapper.Initialize(_mainVM);
+ HotKeyMapper.Initialize(mainVM);
// main windows needs initialized before theme change because of blur settings
ThemeManager.Instance.Settings = _settings;
@@ -147,11 +158,11 @@ private void AutoUpdates()
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await _updater.UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
}
});
}
@@ -194,7 +205,7 @@ public void Dispose()
public void OnSecondAppStarted()
{
- _mainVM.Show();
+ Ioc.Default.GetRequiredService().Show();
}
}
}
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 4ec249c2b79..cab3915d5c0 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
@@ -83,12 +83,13 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
all
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf244a..50765294cf8 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -25,7 +25,7 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher
{
@@ -33,15 +33,15 @@ public class PublicAPIInstance : IPublicAPI
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly PinyinAlphabet _alphabet;
+ private readonly IAlphabet _alphabet;
#region Constructor
- public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
+ public PublicAPIInstance()
{
- _settingsVM = settingsVM;
- _mainVM = mainVM;
- _alphabet = alphabet;
+ _settingsVM = Ioc.Default.GetRequiredService();
+ _mainVM = Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3f8..f5141a8fa58 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -25,6 +25,7 @@
using System.ComponentModel;
using Flow.Launcher.Infrastructure.Image;
using System.Windows.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.ViewModel
{
@@ -58,13 +59,13 @@ public partial class MainViewModel : BaseModel, ISavable
#region Constructor
- public MainViewModel(Settings settings)
+ public MainViewModel()
{
_queryTextBeforeLeaveResults = "";
_queryText = "";
_lastQuery = new Query();
- Settings = settings;
+ Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
{
switch (args.PropertyName)
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 95a1eb67553..7549db1a3ab 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,4 +1,5 @@
-using Flow.Launcher.Core;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -13,11 +14,11 @@ public class SettingWindowViewModel : BaseModel
public Settings Settings { get; }
- public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable)
+ public SettingWindowViewModel()
{
- Settings = settings;
- Updater = updater;
- Portable = portable;
+ Settings = Ioc.Default.GetRequiredService();
+ Updater = Ioc.Default.GetRequiredService();
+ Portable = Ioc.Default.GetRequiredService();
}
public async void UpdateApp()
From a748141b1e8d7342336068ef65cc0890eac63992 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 19:47:49 +0800
Subject: [PATCH 0154/1335] Use IPublicAPI instead
---
Flow.Launcher/App.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 8cd054148a9..9b86c6cc4ee 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -27,7 +27,7 @@ namespace Flow.Launcher
{
public partial class App : IDisposable, ISingleInstanceApp
{
- public static PublicAPIInstance API { get; private set; }
+ public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
private Settings _settings;
@@ -93,7 +93,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService() as PublicAPIInstance;
+ API = Ioc.Default.GetRequiredService();
Http.API = API;
Http.Proxy = _settings.Proxy;
From 3cb9d1dce4b606cc80fb3a7fc9e51da08237c1b8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 12 Jan 2025 20:04:44 +0800
Subject: [PATCH 0155/1335] Remove IApp & AppExtensions and use dependency
injection instead
---
Flow.Launcher.Core/AppExtensions.cs | 15 ------------
Flow.Launcher.Core/Configuration/Portable.cs | 24 +++++++++++--------
.../Environments/AbstractPluginEnvironment.cs | 11 +++++----
.../Environments/PythonEnvironment.cs | 2 +-
.../Environments/TypeScriptEnvironment.cs | 2 +-
.../Environments/TypeScriptV2Environment.cs | 2 +-
Flow.Launcher.Core/IApp.cs | 13 ----------
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 3 ++-
.../Resource/Internationalization.cs | 3 ++-
Flow.Launcher.Core/Resource/Theme.cs | 7 ++++--
Flow.Launcher.Core/Updater.cs | 17 +++++++------
Flow.Launcher/App.xaml.cs | 2 ++
.../ViewModel/SettingWindowViewModel.cs | 10 ++++++--
14 files changed, 54 insertions(+), 59 deletions(-)
delete mode 100644 Flow.Launcher.Core/AppExtensions.cs
delete mode 100644 Flow.Launcher.Core/IApp.cs
diff --git a/Flow.Launcher.Core/AppExtensions.cs b/Flow.Launcher.Core/AppExtensions.cs
deleted file mode 100644
index b02612d72f9..00000000000
--- a/Flow.Launcher.Core/AppExtensions.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Windows;
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core;
-
-///
-/// Extension properties and functions of the current application singleton object.
-///
-public static class AppExtensions
-{
- ///
- /// Gets the public API of the current application singleton object.
- ///
- public static IPublicAPI API => (Application.Current as IApp)!.PublicAPI;
-}
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index cb375c58639..069154364ab 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -9,11 +9,15 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
///
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
///
@@ -40,7 +44,7 @@ public void DisablePortableMode()
#endif
IndicateDeletion(DataLocation.PortableDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -64,7 +68,7 @@ public void EnablePortableMode()
#endif
IndicateDeletion(DataLocation.RoamingDataPath);
- AppExtensions.API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
+ API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");
UpdateManager.RestartApp(Constant.ApplicationFileName);
@@ -95,13 +99,13 @@ public void RemoveUninstallerEntry()
public void MoveUserDataFolder(string fromLocation, string toLocation)
{
- FilesFolders.CopyAll(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}
public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
- FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
}
public void CreateShortcuts()
@@ -157,13 +161,13 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => API.ShowMsgBox(s));
- if (AppExtensions.API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
+ if (API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- FilesFolders.OpenPath(Constant.RootDirectory, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));
Environment.Exit(0);
}
@@ -172,9 +176,9 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
- FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => API.ShowMsgBox(s));
- AppExtensions.API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
+ API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
@@ -186,7 +190,7 @@ public bool CanUpdatePortability()
if (roamingLocationExists && portableLocationExists)
{
- AppExtensions.API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
+ API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index cada0503197..451df6147fa 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -8,11 +8,14 @@
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
+ protected readonly IPublicAPI API = Ioc.Default.GetRequiredService();
+
internal abstract string Language { get; }
internal abstract string EnvName { get; }
@@ -25,7 +28,7 @@ public abstract class AbstractPluginEnvironment
internal virtual string FileDialogFilter => string.Empty;
- internal abstract string PluginsSettingsFilePath { get; set; }
+ internal abstract string PluginsSettingsFilePath { get; set; }
internal List PluginMetadataList;
@@ -57,7 +60,7 @@ internal IEnumerable Setup()
EnvName,
Environment.NewLine
);
- if (AppExtensions.API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
@@ -82,7 +85,7 @@ internal IEnumerable Setup()
}
else
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -98,7 +101,7 @@ private void EnsureLatestInstalled(string expectedPath, string currentPath, stri
if (expectedPath == currentPath)
return;
- FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
InstallEnvironment();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 56bc20b4f4d..607c1906215 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -28,7 +28,7 @@ internal PythonEnvironment(List pluginMetadataList, PluginsSetti
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 1d43b815a21..399f7cc03fd 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -25,7 +25,7 @@ internal TypeScriptEnvironment(List pluginMetadataList, PluginsS
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 49bf4e958f0..e8cb72e11d6 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -25,7 +25,7 @@ internal TypeScriptV2Environment(List pluginMetadataList, Plugin
internal override void InstallEnvironment()
{
- FilesFolders.RemoveFolderIfExists(InstallPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
diff --git a/Flow.Launcher.Core/IApp.cs b/Flow.Launcher.Core/IApp.cs
deleted file mode 100644
index 233fd5ed1c3..00000000000
--- a/Flow.Launcher.Core/IApp.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Core
-{
- ///
- /// Interface for the current application singleton object exposing the properties
- /// and functions that can be accessed from anywhere in the application.
- ///
- public interface IApp
- {
- public IPublicAPI PublicAPI { get; }
- }
-}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 9e1cf3b9d13..a776c10ab2f 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -519,7 +519,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
var newPluginPath = Path.Combine(installDirectory, folderName);
- FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => AppExtensions.API.ShowMsgBox(s));
+ FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => API.ShowMsgBox(s));
Directory.Delete(tempFolderPluginPath, true);
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 8cbeb7473f7..4827cf69d41 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -4,6 +4,7 @@
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins.Environments;
#pragma warning disable IDE0005
using Flow.Launcher.Infrastructure.Logger;
@@ -119,7 +120,7 @@ public static IEnumerable DotNetPlugins(List source)
_ = Task.Run(() =>
{
- AppExtensions.API.ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
+ Ioc.Default.GetRequiredService().ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index a1cefabe381..de066dda125 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -11,6 +11,7 @@
using Flow.Launcher.Plugin;
using System.Globalization;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Resource
{
@@ -124,7 +125,7 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;
- if (AppExtensions.API.ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (Ioc.Default.GetRequiredService().ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;
return true;
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 8622d4caf05..2749da53209 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -11,6 +11,8 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
{
@@ -22,6 +24,7 @@ public class Theme
private const int ShadowExtraMargin = 32;
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
private readonly List _themeDirectories = new List();
private ResourceDictionary _oldResource;
private string _oldTheme;
@@ -108,7 +111,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
@@ -118,7 +121,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
- AppExtensions.API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
+ API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 8745d54b792..37341805517 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,14 +17,17 @@
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core
{
public class Updater
{
- public string GitHubRepository { get; }
+ private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
- public Updater(string gitHubRepository)
+ public string GitHubRepository { get; set; }
+
+ public void Initialize(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
}
@@ -53,7 +56,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- AppExtensions.API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
@@ -68,9 +71,9 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
- FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s));
- if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => AppExtensions.API.ShowMsgBox(s)))
- AppExtensions.API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
+ if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
+ API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -83,7 +86,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (AppExtensions.API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9b86c6cc4ee..0d6d9855c72 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,6 +74,8 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
+ Ioc.Default.GetRequiredService().Initialize();
+
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 7549db1a3ab..bbd47e731cf 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -8,15 +8,21 @@ namespace Flow.Launcher.ViewModel;
public class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; }
+ public Updater Updater { get; private set; }
- public IPortable Portable { get; }
+ public IPortable Portable { get; private set; }
public Settings Settings { get; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
+ }
+
+ public void Initialize()
+ {
+ // We don not initialize Updater and Portable in the constructor because we want to avoid
+ // recrusive dependency injection
Updater = Ioc.Default.GetRequiredService();
Portable = Ioc.Default.GetRequiredService();
}
From 2a423f09bb3fe6c3dfb6dd9f03cce4ce410c5936 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 09:36:14 +0800
Subject: [PATCH 0156/1335] Improve code quality
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 7134fc7603a..b3a265e29fe 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -8,13 +8,13 @@ namespace Flow.Launcher.Infrastructure
{
public class StringMatcher
{
- private readonly MatchOption _defaultMatchOption = new MatchOption();
+ private readonly MatchOption _defaultMatchOption = new();
public SearchPrecisionScore UserSettingSearchPrecision { get; set; }
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
_alphabet = Ioc.Default.GetRequiredService();
}
@@ -242,16 +242,16 @@ private bool IsAcronymCount(string stringToCompare, int compareStringIndex)
return false;
}
- private bool IsAcronymChar(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymChar(string stringToCompare, int compareStringIndex)
=> char.IsUpper(stringToCompare[compareStringIndex]) ||
compareStringIndex == 0 || // 0 index means char is the start of the compare string, which is an acronym
char.IsWhiteSpace(stringToCompare[compareStringIndex - 1]);
- private bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
+ private static bool IsAcronymNumber(string stringToCompare, int compareStringIndex)
=> stringToCompare[compareStringIndex] >= 0 && stringToCompare[compareStringIndex] <= 9;
// To get the index of the closest space which preceeds the first matching index
- private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
+ private static int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex)
{
var closestSpaceIndex = -1;
From ff110b3c49ec139da1222e3ffcb210596eb4642e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:01:50 +0800
Subject: [PATCH 0157/1335] Fix test project build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29fe..5822057a27f 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ public class StringMatcher
private readonly IAlphabet _alphabet;
- public StringMatcher()
+ public StringMatcher(IAlphabet alphabet = null)
{
- _alphabet = Ioc.Default.GetRequiredService();
+ _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From c3f71c213e8b24870292f4489515558850c9c5b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:18:35 +0800
Subject: [PATCH 0158/1335] Revert "Fix test project build issue"
This reverts commit ff110b3c49ec139da1222e3ffcb210596eb4642e.
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index 5822057a27f..b3a265e29fe 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -14,9 +14,9 @@ public class StringMatcher
private readonly IAlphabet _alphabet;
- public StringMatcher(IAlphabet alphabet = null)
+ public StringMatcher()
{
- _alphabet = alphabet ?? Ioc.Default.GetRequiredService();
+ _alphabet = Ioc.Default.GetRequiredService();
}
public static StringMatcher Instance { get; internal set; }
From 3bebb690935e4b99a508f5a9e98593760f45360c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 10:21:14 +0800
Subject: [PATCH 0159/1335] Fix unitest build issue
---
Flow.Launcher.Infrastructure/StringMatcher.cs | 6 +++++
Flow.Launcher.Test/FuzzyMatcherTest.cs | 22 ++++++++++---------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs
index b3a265e29fe..f5f02cbfcae 100644
--- a/Flow.Launcher.Infrastructure/StringMatcher.cs
+++ b/Flow.Launcher.Infrastructure/StringMatcher.cs
@@ -19,6 +19,12 @@ public StringMatcher()
_alphabet = Ioc.Default.GetRequiredService();
}
+ // This is a workaround to allow unit tests to set the instance
+ public StringMatcher(IAlphabet alphabet)
+ {
+ _alphabet = alphabet;
+ }
+
public static StringMatcher Instance { get; internal set; }
public static MatchResult FuzzySearch(string query, string stringToCompare)
diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs
index d7f1432184c..d97ce227c1a 100644
--- a/Flow.Launcher.Test/FuzzyMatcherTest.cs
+++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs
@@ -21,6 +21,8 @@ public class FuzzyMatcherTest
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
private const string VisualStudioCode = "Visual Studio Code";
+ private readonly IAlphabet alphabet = null;
+
public List GetSearchStrings()
=> new List
{
@@ -59,7 +61,7 @@ public void MatchTest()
};
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in sources)
{
results.Add(new Result
@@ -81,7 +83,7 @@ public void MatchTest()
public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(string searchString)
{
var compareString = "Can have rum only in my glass";
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore;
Assert.True(scoreResult == 0);
@@ -97,7 +99,7 @@ public void GivenQueryString_WhenAppliedPrecisionFiltering_ThenShouldReturnGreat
string searchTerm)
{
var results = new List();
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
foreach (var str in GetSearchStrings())
{
results.Add(new Result
@@ -147,7 +149,7 @@ public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring(
string queryString, string compareString, int expectedScore)
{
// When, Given
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
// Should
@@ -181,7 +183,7 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -232,7 +234,7 @@ public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings(
bool expectedPrecisionResult)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = expectedPrecisionScore};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = expectedPrecisionScore};
// Given
var matchResult = matcher.FuzzyMatch(queryString, compareString);
@@ -260,7 +262,7 @@ public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord(
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
+ var matcher = new StringMatcher(alphabet) {UserSettingSearchPrecision = SearchPrecisionScore.Regular};
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -293,7 +295,7 @@ public void WhenGivenTwoStrings_Scoring_ShouldGiveMoreWeightToTheStringCloserToI
string queryString, string compareString1, string compareString2)
{
// When
- var matcher = new StringMatcher { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
+ var matcher = new StringMatcher(alphabet) { UserSettingSearchPrecision = SearchPrecisionScore.Regular };
// Given
var compareString1Result = matcher.FuzzyMatch(queryString, compareString1);
@@ -323,7 +325,7 @@ public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(
string secondName, string secondDescription, string secondExecutableName)
{
// Act
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore;
var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore;
var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore;
@@ -358,7 +360,7 @@ public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(
public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString, string compareString,
int desiredScore)
{
- var matcher = new StringMatcher();
+ var matcher = new StringMatcher(alphabet);
var score = matcher.FuzzyMatch(queryString, compareString).Score;
Assert.IsTrue(score == desiredScore,
$@"Query: ""{queryString}""
From 8d8384965ea5d39c62d7ce2b865114555b393146 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 13 Jan 2025 12:00:45 +0800
Subject: [PATCH 0160/1335] Improve dependency injection in updater & settings
view model & settings page
---
Flow.Launcher.Core/Updater.cs | 20 ++++++++--------
Flow.Launcher/App.xaml.cs | 7 +++---
.../CustomQueryHotkeySetting.xaml.cs | 5 +---
Flow.Launcher/PublicAPIInstance.cs | 20 +++++++++++-----
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
.../SettingsPaneGeneralViewModel.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 5 ++--
Flow.Launcher/SettingWindow.xaml.cs | 18 ++++++++++-----
.../ViewModel/SettingWindowViewModel.cs | 23 ++-----------------
9 files changed, 46 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 37341805517..7a25447b4d3 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -34,14 +34,14 @@ public void Initialize(string gitHubRepository)
private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);
- public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
+ public async Task UpdateAppAsync(bool silentUpdate = true)
{
await UpdateLock.WaitAsync().ConfigureAwait(false);
try
{
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("pleaseWait"),
- api.GetTranslation("update_flowlauncher_update_check"));
+ API.ShowMsg(API.GetTranslation("pleaseWait"),
+ API.GetTranslation("update_flowlauncher_update_check"));
using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false);
@@ -56,13 +56,13 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
- API.ShowMsgBox(api.GetTranslation("update_flowlauncher_already_on_latest"));
+ API.ShowMsgBox(API.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"),
- api.GetTranslation("update_flowlauncher_updating"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_update_found"),
+ API.GetTranslation("update_flowlauncher_updating"));
await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);
@@ -73,7 +73,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
- API.ShowMsgBox(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
+ API.ShowMsgBox(string.Format(API.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
@@ -86,7 +86,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
- if (API.ShowMsgBox(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ if (API.ShowMsgBox(newVersionTips, API.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
@@ -99,8 +99,8 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
if (!silentUpdate)
- api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"),
- api.GetTranslation("update_flowlauncher_check_connection"));
+ API.ShowMsg(API.GetTranslation("update_flowlauncher_fail"),
+ API.GetTranslation("update_flowlauncher_check_connection"));
}
finally
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 0d6d9855c72..9384aae3d3b 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -74,8 +74,6 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
- Ioc.Default.GetRequiredService().Initialize();
-
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
@@ -96,6 +94,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
PluginManager.LoadPlugins(_settings.PluginSettings);
API = Ioc.Default.GetRequiredService();
+ ((PublicAPIInstance)API).Initialize();
Http.API = API;
Http.Proxy = _settings.Proxy;
@@ -160,11 +159,11 @@ private void AutoUpdates()
{
// check update every 5 hours
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
while (await timer.WaitForNextTickAsync())
// check updates on startup
- await Ioc.Default.GetRequiredService().UpdateAppAsync(API);
+ await Ioc.Default.GetRequiredService().UpdateAppAsync();
}
});
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 47460ff7d32..eab2705d004 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -6,20 +6,17 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.Core;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- private SettingWindow _settingWidow;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
public Settings Settings { get; }
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
+ public CustomQueryHotkeySetting(Settings settings)
{
- _settingWidow = settingWidow;
Settings = settings;
InitializeComponent();
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 50765294cf8..54e97f6c61e 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -26,6 +26,7 @@
using System.Diagnostics;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -33,19 +34,26 @@ public class PublicAPIInstance : IPublicAPI
{
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private readonly IAlphabet _alphabet;
- #region Constructor
+ private Updater _updater;
+
+ #region Constructor & Initialization
public PublicAPIInstance()
{
_settingsVM = Ioc.Default.GetRequiredService();
_mainVM = Ioc.Default.GetRequiredService();
- _alphabet = Ioc.Default.GetRequiredService();
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
+ public void Initialize()
+ {
+ // We need to initialize Updater not in the constructor because we want to avoid
+ // recrusive dependency injection
+ _updater = Ioc.Default.GetRequiredService();
+ }
+
#endregion
#region Public API
@@ -78,14 +86,14 @@ public void RestartApp()
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _settingsVM.UpdateApp();
+ public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
public void SaveAppAllSettings()
{
PluginManager.Save();
_mainVM.Save();
_settingsVM.Save();
- ImageLoader.Save();
+ _ = ImageLoader.Save();
}
public Task ReloadAllPluginData() => PluginManager.ReloadDataAsync();
@@ -105,7 +113,7 @@ public void OpenSettingDialog()
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
+ SettingWindow sw = SingletonWindowOpener.Open();
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 05fb16f5cc1..cb434f399f0 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -96,7 +96,7 @@ private void OpenLogsFolder()
}
[RelayCommand]
- private Task UpdateApp() => _updater.UpdateAppAsync(App.API, false);
+ private Task UpdateApp() => _updater.UpdateAppAsync(false);
private void ClearLogFolder()
{
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3d94355e687..4e498ba23fa 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -160,7 +160,7 @@ private string GetFileFromDialog(string title, string filter = "")
private void UpdateApp()
{
- _ = _updater.UpdateAppAsync(App.API, false);
+ _ = _updater.UpdateAppAsync(false);
}
public bool AutoUpdates
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index fb57f499bbc..b13aaefe3e9 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -7,7 +7,6 @@
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Flow.Launcher.Core;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -71,7 +70,7 @@ private void CustomHotkeyEdit()
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings);
+ var window = new CustomQueryHotkeySetting(Settings);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -79,7 +78,7 @@ private void CustomHotkeyEdit()
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings).ShowDialog();
+ new CustomQueryHotkeySetting(Settings).ShowDialog();
}
[RelayCommand]
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cb3f1e4a113..ab639e987ed 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -3,6 +3,7 @@
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Helper;
@@ -17,16 +18,21 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
+ private readonly Updater _updater;
+ private readonly IPortable _portable;
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
+ public SettingWindow()
{
+ var viewModel = Ioc.Default.GetRequiredService();
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
- _api = api;
+ _updater = Ioc.Default.GetRequiredService();
+ _portable = Ioc.Default.GetRequiredService();
+ _api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
}
@@ -125,7 +131,7 @@ public void InitializePosition()
WindowState = _settings.SettingWindowState;
}
- private bool IsPositionValid(double top, double left)
+ private static bool IsPositionValid(double top, double left)
{
foreach (var screen in Screen.AllScreens)
{
@@ -145,7 +151,7 @@ private double WindowLeft()
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
- var left = (dip2.X - this.ActualWidth) / 2 + dip1.X;
+ var left = (dip2.X - ActualWidth) / 2 + dip1.X;
return left;
}
@@ -154,13 +160,13 @@ private double WindowTop()
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
- var top = (dip2.Y - this.ActualHeight) / 2 + dip1.Y - 20;
+ var top = (dip2.Y - ActualHeight) / 2 + dip1.Y - 20;
return top;
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
+ var paneData = new PaneData(_settings, _updater, _portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index bbd47e731cf..37276a1addf 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,37 +1,18 @@
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel;
-public class SettingWindowViewModel : BaseModel
+public partial class SettingWindowViewModel : BaseModel
{
- public Updater Updater { get; private set; }
-
- public IPortable Portable { get; private set; }
-
- public Settings Settings { get; }
+ public Settings Settings { get; init; }
public SettingWindowViewModel()
{
Settings = Ioc.Default.GetRequiredService();
}
- public void Initialize()
- {
- // We don not initialize Updater and Portable in the constructor because we want to avoid
- // recrusive dependency injection
- Updater = Ioc.Default.GetRequiredService();
- Portable = Ioc.Default.GetRequiredService();
- }
-
- public async void UpdateApp()
- {
- await Updater.UpdateAppAsync(App.API, false);
- }
-
///
/// Save Flow settings. Plugins settings are not included.
///
From 43965f4751fc31f978ae272c22bc9dab703ed006 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 13 Jan 2025 22:11:23 +0000
Subject: [PATCH 0161/1335] Bump BitFaster.Caching from 2.5.2 to 2.5.3
Bumps [BitFaster.Caching](https://github.com/bitfaster/BitFaster.Caching) from 2.5.2 to 2.5.3.
- [Release notes](https://github.com/bitfaster/BitFaster.Caching/releases)
- [Commits](https://github.com/bitfaster/BitFaster.Caching/compare/v2.5.2...v2.5.3)
---
updated-dependencies:
- dependency-name: BitFaster.Caching
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Infrastructure.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index 1475252caee..1d6ee5c86aa 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -53,7 +53,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
From 8e5d77878af93e42de831b505a6c926e271917c0 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 18 Jan 2025 20:51:06 +1100
Subject: [PATCH 0162/1335] remove equality test
---
.../Plugins/JsonRPCPluginTest.cs | 23 -------------------
1 file changed, 23 deletions(-)
diff --git a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
index b4e0736c6c2..42a4630fe5c 100644
--- a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
+++ b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
@@ -63,28 +63,5 @@ public async Task GivenVariousJsonText_WhenVariousNamingCase_ThenExpectNotNullRe
})
};
- [TestCaseSource(typeof(JsonRPCPluginTest), nameof(ResponseModelsSource))]
- public async Task GivenModel_WhenSerializeWithDifferentNamingPolicy_ThenExpectSameResult_Async(JsonRPCQueryResponseModel reference)
- {
- var camelText = JsonSerializer.Serialize(reference, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
-
- var pascalText = JsonSerializer.Serialize(reference);
-
- var results1 = await QueryAsync(new Query { Search = camelText }, default);
- var results2 = await QueryAsync(new Query { Search = pascalText }, default);
-
- Assert.IsNotNull(results1);
- Assert.IsNotNull(results2);
-
- foreach (var ((result1, result2), referenceResult) in results1.Zip(results2).Zip(reference.Result))
- {
- Assert.AreEqual(result1.Title, result2.Title);
- Assert.AreEqual(result1.Title, referenceResult.Title);
-
- Assert.IsNotNull(result1);
- Assert.IsNotNull(result1.AsyncAction);
- }
- }
-
}
}
From 874a785be40cf57755fd0ebadfb554f6517ac8e8 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 18 Jan 2025 21:06:11 +1100
Subject: [PATCH 0163/1335] cache keywordIndex
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 75825042153..d48583f2696 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -26,20 +26,21 @@ public List Query(Query query)
LoadThemes();
}
- string search = query.Search[(query.Search.IndexOf(Keyword, StringComparison.Ordinal) + Keyword.Length + 1)..];
+ int keywordIndex = query.Search.IndexOf(Keyword, StringComparison.Ordinal);
+ string search = query.Search[(keywordIndex + Keyword.Length + 1)..];
if (string.IsNullOrWhiteSpace(search))
{
return themes.Select(CreateThemeResult)
- .OrderBy(x => x.Title)
- .ToList();
+ .OrderBy(x => x.Title)
+ .ToList();
}
return themes.Select(theme => (theme, matchResult: context.API.FuzzySearch(search, theme)))
- .Where(x => x.matchResult.IsSearchPrecisionScoreMet())
- .Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
- .OrderBy(x => x.Title)
- .ToList();
+ .Where(x => x.matchResult.IsSearchPrecisionScoreMet())
+ .Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
+ .OrderBy(x => x.Title)
+ .ToList();
}
private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs args)
From 40050545005adcfaa2acec8f046deeaea79d3049 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 18 Jan 2025 21:16:04 +1100
Subject: [PATCH 0164/1335] implement the complete IDisposable pattern
---
.../Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 25 ++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index d48583f2696..ca19bd33d80 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -83,12 +83,31 @@ private static Result CreateThemeResult(string theme, int score, IList high
};
}
- public void Dispose()
+ private bool disposed;
+ protected virtual void Dispose(bool disposing)
{
- if (context != null && context.API != null)
+ if (!disposed)
{
- context.API.VisibilityChanged -= OnVisibilityChanged;
+ if (disposing)
+ {
+ // Dispose managed resources
+ if (context?.API != null)
+ {
+ context.API.VisibilityChanged -= OnVisibilityChanged;
+ }
+ }
+ // Free unmanaged resources
+ disposed = true;
}
}
+ ~ThemeSelector()
+ {
+ Dispose(false);
+ }
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
}
}
From abe943b69339963dff909ecf5c8d9aaa6dc391ce Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 18 Jan 2025 18:39:44 +0800
Subject: [PATCH 0165/1335] Fix system language code fetch issue
---
.../Resource/Internationalization.cs | 58 +++++++++----------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 70f23c89721..13efdda56ec 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -23,19 +23,45 @@ public class Internationalization
private const string Extension = ".xaml";
private readonly List _languageDirectories = new List();
private readonly List _oldResources = new List();
+ private readonly string SystemLanguageCode;
public Internationalization()
{
AddFlowLauncherLanguageDirectory();
+ SystemLanguageCode = GetSystemLanguageCode();
}
-
private void AddFlowLauncherLanguageDirectory()
{
var directory = Path.Combine(Constant.ProgramDirectory, Folder);
_languageDirectories.Add(directory);
}
+ private static string GetSystemLanguageCode()
+ {
+ var availableLanguages = AvailableLanguages.GetAvailableLanguages();
+
+ // Retrieve the language identifiers for the current culture
+ var currentCulture = CultureInfo.CurrentCulture;
+ var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
+ var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
+ var fullName = currentCulture.Name;
+
+ // Try to find a match in the available languages list
+ foreach (var language in availableLanguages)
+ {
+ var languageCode = language.LanguageCode;
+
+ if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
+ {
+ return languageCode;
+ }
+ }
+
+ return DefaultLanguageCode;
+ }
internal void AddPluginLanguageDirectories(IEnumerable plugins)
{
@@ -74,7 +100,7 @@ public void ChangeLanguage(string languageCode)
var isSystem = false;
if (languageCode == Constant.SystemLanguageCode)
{
- languageCode = GetSystemLanguageCode();
+ languageCode = SystemLanguageCode;
isSystem = true;
}
@@ -178,36 +204,10 @@ private void LoadLanguage(Language language)
public List LoadAvailableLanguages()
{
var list = AvailableLanguages.GetAvailableLanguages();
- list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(GetSystemLanguageCode())));
+ list.Insert(0, new Language(Constant.SystemLanguageCode, AvailableLanguages.GetSystemTranslation(SystemLanguageCode)));
return list;
}
- private string GetSystemLanguageCode()
- {
- var availableLanguages = AvailableLanguages.GetAvailableLanguages();
-
- // Retrieve the language identifiers for the current culture
- var currentCulture = CultureInfo.CurrentCulture;
- var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
- var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
- var fullName = currentCulture.Name;
-
- // Try to find a match in the available languages list
- foreach (var language in availableLanguages)
- {
- var languageCode = language.LanguageCode;
-
- if (string.Equals(languageCode, twoLetterCode, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(languageCode, threeLetterCode, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(languageCode, fullName, StringComparison.OrdinalIgnoreCase))
- {
- return languageCode;
- }
- }
-
- return DefaultLanguageCode;
- }
-
public string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
From fce3b3ae3d7ebb59747e3a94fb4011acce325141 Mon Sep 17 00:00:00 2001
From: Odotocodot <48138990+Odotocodot@users.noreply.github.com>
Date: Sat, 18 Jan 2025 13:18:48 +0000
Subject: [PATCH 0166/1335] Fix crash on theme search
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index ca19bd33d80..3ea90197d54 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -26,8 +26,7 @@ public List Query(Query query)
LoadThemes();
}
- int keywordIndex = query.Search.IndexOf(Keyword, StringComparison.Ordinal);
- string search = query.Search[(keywordIndex + Keyword.Length + 1)..];
+ string search = query.SecondToEndSearch;
if (string.IsNullOrWhiteSpace(search))
{
@@ -52,7 +51,7 @@ private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs args)
}
private void LoadThemes()
- => themes = ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension);
+ => themes = ThemeManager.Instance.LoadAvailableThemes().Select(x => x.FileNameWithoutExtension);
private static Result CreateThemeResult(string theme) => CreateThemeResult(theme, 0, null);
From 1bf045f3e729f39e835bc1a6b3e7f9416a9c5bda Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 19 Jan 2025 15:15:02 +0800
Subject: [PATCH 0167/1335] Make fileMode usage between progress and
non-progress paths consistent
---
Flow.Launcher.Infrastructure/Http/Http.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 0b5d1b05a1a..0b3f2be6557 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -97,7 +97,7 @@ public static async Task DownloadAsync([NotNull] string url, [NotNull] string fi
if (canReportProgress && reportProgress != null)
{
await using var contentStream = await response.Content.ReadAsStreamAsync(token);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
+ await using var fileStream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 8192, true);
var buffer = new byte[8192];
long totalRead = 0;
From c32435f2ed741249289d573c5092bbc0e8cb036a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 19 Jan 2025 15:44:26 +0800
Subject: [PATCH 0168/1335] Use api to call download function & Add message box
for all download operations
---
.../PluginsManager.cs | 129 ++++++++++--------
1 file changed, 71 insertions(+), 58 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index aee76e65ebf..ce51e8700af 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -142,37 +142,15 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- var exceptionHappened = false;
try
{
using var cts = new CancellationTokenSource();
if (!plugin.IsFromLocalInstallPath)
{
- if (File.Exists(filePath))
- File.Delete(filePath);
-
- var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- await Context.API.ShowProgressBoxAsync(prgBoxTitle,
- async (reportProgress) =>
- {
- if (reportProgress == null)
- {
- // when reportProgress is null, it means there is expcetion with the progress box
- // so we record it with exceptionHappened and return so that progress box will close instantly
- exceptionHappened = true;
- return;
- }
- else
- {
- await Http.DownloadAsync(plugin.UrlDownload, filePath, reportProgress, cts.Token).ConfigureAwait(false);
- }
- }, cts.Cancel);
-
- // if exception happened while downloading and user does not cancel downloading,
- // we need to redownload the plugin
- if (exceptionHappened && (!cts.IsCancellationRequested))
- await Http.DownloadAsync(plugin.UrlDownload, filePath, null, cts.Token).ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}",
+ plugin.UrlDownload, filePath, cts);
}
else
{
@@ -221,6 +199,34 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
}
}
+ private async Task DeleteFileAndDownloadMsgBoxAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts)
+ {
+ if (File.Exists(filePath))
+ File.Delete(filePath);
+
+ var exceptionHappened = false;
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
+ {
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
+ }
+ else
+ {
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ }
+ }, cts.Cancel);
+
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!cts.IsCancellationRequested))
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath).ConfigureAwait(false);
+ }
+
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
@@ -308,43 +314,48 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
_ = Task.Run(async delegate
{
+ using var cts = new CancellationTokenSource();
+
if (!x.PluginNewUserPlugin.IsFromLocalInstallPath)
{
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
-
- await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}",
+ x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
}
else
{
downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath;
}
-
- PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
- downloadToFilePath);
-
- if (Settings.AutoRestartAfterChanging)
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
{
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(
- Context.API.GetTranslation(
- "plugin_pluginsmanager_update_success_restart"),
- x.Name));
- Context.API.RestartApp();
+ return;
}
else
{
- Context.API.ShowMsg(
- Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
- string.Format(
- Context.API.GetTranslation(
- "plugin_pluginsmanager_update_success_no_restart"),
- x.Name));
+ PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ downloadToFilePath);
+
+ if (Settings.AutoRestartAfterChanging)
+ {
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(
+ Context.API.GetTranslation(
+ "plugin_pluginsmanager_update_success_restart"),
+ x.Name));
+ Context.API.RestartApp();
+ }
+ else
+ {
+ Context.API.ShowMsg(
+ Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
+ string.Format(
+ Context.API.GetTranslation(
+ "plugin_pluginsmanager_update_success_no_restart"),
+ x.Name));
+ }
}
}).ContinueWith(t =>
{
@@ -405,16 +416,18 @@ await Task.WhenAll(resultsForUpdate.Select(async plugin =>
try
{
- if (File.Exists(downloadToFilePath))
- {
- File.Delete(downloadToFilePath);
- }
+ using var cts = new CancellationTokenSource();
- await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath)
- .ConfigureAwait(false);
+ await DeleteFileAndDownloadMsgBoxAsync(
+ $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.PluginNewUserPlugin.Name}",
+ plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
- downloadToFilePath);
+ // check if user cancelled download before installing plugin
+ if (cts.IsCancellationRequested)
+ return;
+ else
+ PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
+ downloadToFilePath);
}
catch (Exception ex)
{
From d21b9362cf098c99030ba8a91fd545cf418c2991 Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Mon, 20 Jan 2025 09:14:28 -0600
Subject: [PATCH 0169/1335] do not try catch the error for jsonrpc v2
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 45 ++++++--------------
1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 5a6633525e7..305b2815034 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -26,54 +26,33 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I
protected override async Task ExecuteResultAsync(JsonRPCResult result)
{
- try
- {
- var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
- argument: result.JsonRPCAction.Parameters);
+ var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
+ argument: result.JsonRPCAction.Parameters);
- return res.Hide;
- }
- catch
- {
- return false;
- }
+ return res.Hide;
}
private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
public override List LoadContextMenus(Result selectedResult)
{
- try
- {
- var res = JTF.Run(() => RPC.InvokeWithCancellationAsync("context_menu",
- new object[] { selectedResult.ContextData }));
+ var res = JTF.Run(() => RPC.InvokeWithCancellationAsync("context_menu",
+ new object[] { selectedResult.ContextData }));
- var results = ParseResults(res);
+ var results = ParseResults(res);
- return results;
- }
- catch
- {
- return new List();
- }
+ return results;
}
public override async Task> QueryAsync(Query query, CancellationToken token)
{
- try
- {
- var res = await RPC.InvokeWithCancellationAsync("query",
- new object[] { query, Settings.Inner },
- token);
+ var res = await RPC.InvokeWithCancellationAsync("query",
+ new object[] { query, Settings.Inner },
+ token);
- var results = ParseResults(res);
+ var results = ParseResults(res);
- return results;
- }
- catch
- {
- return new List();
- }
+ return results;
}
From 5d164293b915d9c5d924b739ea3e0f13ad386542 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 20 Jan 2025 22:39:42 +0000
Subject: [PATCH 0170/1335] Bump FSharp.Core from 9.0.100 to 9.0.101
Bumps [FSharp.Core](https://github.com/dotnet/fsharp) from 9.0.100 to 9.0.101.
- [Release notes](https://github.com/dotnet/fsharp/releases)
- [Changelog](https://github.com/dotnet/fsharp/blob/main/release-notes.md)
- [Commits](https://github.com/dotnet/fsharp/commits)
---
updated-dependencies:
- dependency-name: FSharp.Core
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 8aeca4699ec..df2f4d2cbf0 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -54,7 +54,7 @@
-
+
From 198442621a94de8aabf26e56d58dec751080c294 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 21 Jan 2025 14:37:14 +0800
Subject: [PATCH 0171/1335] Add support for record key
---
Flow.Launcher.Plugin/Result.cs | 17 +++++++++++++++
Flow.Launcher/Storage/TopMostRecord.cs | 18 ++++++++++++----
Flow.Launcher/Storage/UserSelectedRecord.cs | 24 ++++++++++++++++-----
3 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index c6ca81cf31c..bb005752eba 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -185,6 +185,16 @@ public Result Clone()
TitleHighlightData = TitleHighlightData,
OriginQuery = OriginQuery,
PluginDirectory = PluginDirectory,
+ ContextData = ContextData,
+ PluginID = PluginID,
+ TitleToolTip = TitleToolTip,
+ SubTitleToolTip = SubTitleToolTip,
+ PreviewPanel = PreviewPanel,
+ ProgressBar = ProgressBar,
+ ProgressBarColor = ProgressBarColor,
+ Preview = Preview,
+ AddSelectedCount = AddSelectedCount,
+ RecordKey = RecordKey
};
}
@@ -252,6 +262,13 @@ public ValueTask ExecuteAsync(ActionContext context)
///
public const int MaxScore = int.MaxValue;
+ ///
+ /// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records.
+ /// This can be useful when your plugin will change the Title or SubTitle of the result dynamically.
+ /// If the plugin does not specific this, FL just uses Title and SubTitle to identify this result.
+ ///
+ public string RecordKey { get; set; } = string.Empty;
+
///
/// Info of the preview section of a
///
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index cbd0b88fc7e..05cf0140114 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -33,7 +33,8 @@ internal void AddOrUpdate(Result result)
{
PluginID = result.PluginID,
Title = result.Title,
- SubTitle = result.SubTitle
+ SubTitle = result.SubTitle,
+ RecordKey = result.RecordKey
};
records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
@@ -49,12 +50,21 @@ public class Record
public string Title { get; set; }
public string SubTitle { get; set; }
public string PluginID { get; set; }
+ public string RecordKey { get; set; }
public bool Equals(Result r)
{
- return Title == r.Title
- && SubTitle == r.SubTitle
- && PluginID == r.PluginID;
+ if (string.IsNullOrEmpty(RecordKey) || string.IsNullOrEmpty(r.RecordKey))
+ {
+ return Title == r.Title
+ && SubTitle == r.SubTitle
+ && PluginID == r.PluginID;
+ }
+ else
+ {
+ return RecordKey == r.RecordKey
+ && PluginID == r.PluginID;
+ }
}
}
}
diff --git a/Flow.Launcher/Storage/UserSelectedRecord.cs b/Flow.Launcher/Storage/UserSelectedRecord.cs
index d6405005dba..6da36747dcc 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -15,7 +15,6 @@ public class UserSelectedRecord
[JsonInclude, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Dictionary records { get; private set; }
-
public UserSelectedRecord()
{
recordsWithQuery = new Dictionary();
@@ -45,8 +44,15 @@ private static int GenerateStaticHashCode(string s, int start = HASH_INITIAL)
private static int GenerateResultHashCode(Result result)
{
- int hashcode = GenerateStaticHashCode(result.Title);
- return GenerateStaticHashCode(result.SubTitle, hashcode);
+ if (string.IsNullOrEmpty(result.RecordKey))
+ {
+ int hashcode = GenerateStaticHashCode(result.Title);
+ return GenerateStaticHashCode(result.SubTitle, hashcode);
+ }
+ else
+ {
+ return GenerateStaticHashCode(result.RecordKey);
+ }
}
private static int GenerateQueryAndResultHashCode(Query query, Result result)
@@ -58,8 +64,16 @@ private static int GenerateQueryAndResultHashCode(Query query, Result result)
int hashcode = GenerateStaticHashCode(query.ActionKeyword);
hashcode = GenerateStaticHashCode(query.Search, hashcode);
- hashcode = GenerateStaticHashCode(result.Title, hashcode);
- hashcode = GenerateStaticHashCode(result.SubTitle, hashcode);
+
+ if (string.IsNullOrEmpty(result.RecordKey))
+ {
+ hashcode = GenerateStaticHashCode(result.Title, hashcode);
+ hashcode = GenerateStaticHashCode(result.SubTitle, hashcode);
+ }
+ else
+ {
+ hashcode = GenerateStaticHashCode(result.RecordKey, hashcode);
+ }
return hashcode;
}
From ed399371976b60436eeb9042c59696859eed3caf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 21 Jan 2025 16:19:28 +0800
Subject: [PATCH 0172/1335] Initialize App.API earlier & Improve code quality
---
Flow.Launcher/App.xaml.cs | 5 ++---
Flow.Launcher/PublicAPIInstance.cs | 13 ++-----------
2 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9384aae3d3b..a64c9e7505d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -70,6 +70,8 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
).Build();
Ioc.Default.ConfigureServices(host.Services);
+ API = Ioc.Default.GetRequiredService();
+
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
@@ -93,9 +95,6 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
PluginManager.LoadPlugins(_settings.PluginSettings);
- API = Ioc.Default.GetRequiredService();
- ((PublicAPIInstance)API).Initialize();
-
Http.API = API;
Http.Proxy = _settings.Proxy;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 54e97f6c61e..0329d6973f9 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -35,9 +35,7 @@ public class PublicAPIInstance : IPublicAPI
private readonly SettingWindowViewModel _settingsVM;
private readonly MainViewModel _mainVM;
- private Updater _updater;
-
- #region Constructor & Initialization
+ #region Constructor
public PublicAPIInstance()
{
@@ -47,13 +45,6 @@ public PublicAPIInstance()
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
}
- public void Initialize()
- {
- // We need to initialize Updater not in the constructor because we want to avoid
- // recrusive dependency injection
- _updater = Ioc.Default.GetRequiredService();
- }
-
#endregion
#region Public API
@@ -86,7 +77,7 @@ public void RestartApp()
public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
- public void CheckForNewUpdate() => _ = _updater.UpdateAppAsync(false);
+ public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
public void SaveAppAllSettings()
{
From f9983b587712bdc439022f4ac19bda46133d9ab8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 22 Jan 2025 12:25:56 +0800
Subject: [PATCH 0173/1335] Move dependency injection codes to constructor
---
Flow.Launcher/App.xaml.cs | 47 +++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index a64c9e7505d..d983ab0005e 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -30,7 +30,31 @@ public partial class App : IDisposable, ISingleInstanceApp
public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
private static bool _disposed;
- private Settings _settings;
+ private readonly Settings _settings;
+
+ public App()
+ {
+ // Initialize settings
+ var storage = new FlowLauncherJsonStorage();
+ _settings = storage.Load();
+ _settings.Initialize(storage);
+ _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
+
+ // Configure the dependency injection container
+ var host = Host.CreateDefaultBuilder()
+ .UseContentRoot(AppContext.BaseDirectory)
+ .ConfigureServices(services => services
+ .AddSingleton(_ => _settings)
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ ).Build();
+ Ioc.Default.ConfigureServices(host.Services);
+ }
[STAThread]
public static void Main()
@@ -49,27 +73,6 @@ private async void OnStartupAsync(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- // Initialize settings
- var storage = new FlowLauncherJsonStorage();
- _settings = storage.Load();
- _settings.Initialize(storage);
- _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled();
-
- // Configure the dependency injection container
- var host = Host.CreateDefaultBuilder()
- .UseContentRoot(AppContext.BaseDirectory)
- .ConfigureServices(services => services
- .AddSingleton(_ => _settings)
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- ).Build();
- Ioc.Default.ConfigureServices(host.Services);
-
API = Ioc.Default.GetRequiredService();
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
From fec553c87ca451d2d5cac3e1e71998e702fe8b8c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 24 Jan 2025 12:11:48 +0800
Subject: [PATCH 0174/1335] Improve uninstaller check function
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 39 +++++++++++++++++---
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index e311a0b94e3..5ccccc24eeb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -41,9 +41,13 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
"uninst000.exe",
"uninstall.exe"
};
- // For cases when the uninstaller is named like "Uninstall Program Name.exe"
- private const string CommonUninstallerPrefix = "uninstall";
- private const string CommonUninstallerSuffix = ".exe";
+ private static readonly string[] commonUninstallerPrefixs =
+ {
+ "uninstall",
+ "卸载"
+ };
+ private const string ExeUninstallerSuffix = ".exe";
+ private const string InkUninstallerSuffix = ".lnk";
static Main()
{
@@ -96,10 +100,33 @@ private bool HideUninstallersFilter(IProgram program)
{
if (!_settings.HideUninstallers) return true;
if (program is not Win32 win32) return true;
+
+ // First check the executable path
var fileName = Path.GetFileName(win32.ExecutablePath);
- return !commonUninstallerNames.Contains(fileName, StringComparer.OrdinalIgnoreCase) &&
- !(fileName.StartsWith(CommonUninstallerPrefix, StringComparison.OrdinalIgnoreCase) &&
- fileName.EndsWith(CommonUninstallerSuffix, StringComparison.OrdinalIgnoreCase));
+ // For cases when the uninstaller is named like "uninst.exe"
+ if (commonUninstallerNames.Contains(fileName, StringComparer.OrdinalIgnoreCase)) return false;
+ // For cases when the uninstaller is named like "Uninstall Program Name.exe"
+ foreach (var prefix in commonUninstallerPrefixs)
+ {
+ if (fileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
+ fileName.EndsWith(ExeUninstallerSuffix, StringComparison.OrdinalIgnoreCase))
+ return false;
+ }
+
+ // Second check the ink path
+ if (!string.IsNullOrEmpty(win32.LnkResolvedPath))
+ {
+ var inkFileName = Path.GetFileName(win32.FullPath);
+ // For cases when the uninstaller is named like "Uninstall Program Name.ink"
+ foreach (var prefix in commonUninstallerPrefixs)
+ {
+ if (inkFileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
+ inkFileName.EndsWith(InkUninstallerSuffix, StringComparison.OrdinalIgnoreCase))
+ return false;
+ }
+ }
+
+ return true;
}
public async Task InitAsync(PluginInitContext context)
From 71dad9f35616b0d0f6f2a3df4c7dca5791ec17ba Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 24 Jan 2025 18:35:11 +0800
Subject: [PATCH 0175/1335] Add support for more uninstaller prefixs
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 27 ++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 5ccccc24eeb..511794f8936 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -43,8 +43,31 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
};
private static readonly string[] commonUninstallerPrefixs =
{
- "uninstall",
- "卸载"
+ "uninstall",//en
+ "卸载",//zh-cn
+ "卸載",//zh-tw
+ "видалити",//uk-UA
+ "удалить",//ru
+ "désinstaller",//fr
+ "アンインストール",//ja
+ "deïnstalleren",//nl
+ "odinstaluj",//pl
+ "afinstallere",//da
+ "deinstallieren",//de
+ "삭제",//ko
+ "деинсталирај",//sr
+ "desinstalar",//pt-pt
+ "desinstalar",//pt-br
+ "desinstalar",//es
+ "desinstalar",//es-419
+ "disinstallare",//it
+ "avinstallere",//nb-NO
+ "odinštalovať",//sk
+ "kaldır",//tr
+ "odinstalovat",//cs
+ "إلغاء التثبيت",//ar
+ "gỡ bỏ",//vi-vn
+ "הסרה"//he
};
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
From 0c7dc07c743df01bce72c001061ede34b9b0fc08 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 26 Jan 2025 09:34:07 +1100
Subject: [PATCH 0176/1335] fix typo
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 511794f8936..00b97e11435 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -136,7 +136,7 @@ private bool HideUninstallersFilter(IProgram program)
return false;
}
- // Second check the ink path
+ // Second check the lnk path
if (!string.IsNullOrEmpty(win32.LnkResolvedPath))
{
var inkFileName = Path.GetFileName(win32.FullPath);
From 0e700cdfcc5aced08e75e19c38f33836d7276628 Mon Sep 17 00:00:00 2001
From: Jeremy
Date: Sun, 26 Jan 2025 10:42:32 +1100
Subject: [PATCH 0177/1335] rename GetSystemLanguageCode method + add comment
---
Flow.Launcher.Core/Resource/Internationalization.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 13efdda56ec..ef38e8be097 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -28,7 +28,7 @@ public class Internationalization
public Internationalization()
{
AddFlowLauncherLanguageDirectory();
- SystemLanguageCode = GetSystemLanguageCode();
+ SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
private void AddFlowLauncherLanguageDirectory()
@@ -37,11 +37,13 @@ private void AddFlowLauncherLanguageDirectory()
_languageDirectories.Add(directory);
}
- private static string GetSystemLanguageCode()
+ private static string GetSystemLanguageCodeAtStartup()
{
var availableLanguages = AvailableLanguages.GetAvailableLanguages();
- // Retrieve the language identifiers for the current culture
+ // Retrieve the language identifiers for the current culture.
+ // ChangeLanguage method overrides the CultureInfo.CurrentCulture, so this needs to
+ // be called at startup in order to get the correct lang code of system.
var currentCulture = CultureInfo.CurrentCulture;
var twoLetterCode = currentCulture.TwoLetterISOLanguageName;
var threeLetterCode = currentCulture.ThreeLetterISOLanguageName;
From 1562c88ea71a0f56033553016682a51bc019d590 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:07:40 +0800
Subject: [PATCH 0178/1335] Improve context menu item action response
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++++
Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 1 +
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 ++
3 files changed, 7 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3f8..b12e97e0b3b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1273,6 +1273,8 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.Remove(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ App.API.BackToQueryResults();
+ App.API.ReQuery();
return false;
}
};
@@ -1289,6 +1291,8 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.AddOrUpdate(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ App.API.BackToQueryResults();
+ App.API.ReQuery();
return false;
}
};
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index feccc74c8e1..3f3b7cb5846 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -242,6 +242,7 @@ public List LoadContextMenus(Result selectedResult)
var name = "Plugin: Folder";
var message = $"File not found: {e.Message}";
Context.API.ShowMsgError(name, message);
+ return false;
}
return true;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 00b97e11435..6ba7047f23e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -264,6 +264,8 @@ public List LoadContextMenus(Result selectedResult)
Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_success"),
Context.API.GetTranslation(
"flowlauncher_plugin_program_disable_dlgtitle_success_message"));
+ Context.API.BackToQueryResults();
+ Context.API.ReQuery();
return false;
},
IcoPath = "Images/disable.png",
From ae5186dacfad5fd354867b1ec254edaa913e0a52 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:21:30 +0800
Subject: [PATCH 0179/1335] Remove context menu cache
---
Flow.Launcher/ViewModel/MainViewModel.cs | 15 +--------------
1 file changed, 1 insertion(+), 14 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index b12e97e0b3b..2d232ebdd01 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -34,8 +34,6 @@ public partial class MainViewModel : BaseModel, ISavable
private bool _isQueryRunning;
private Query _lastQuery;
- private Result lastContextMenuResult = new Result();
- private List lastContextMenuResults = new List();
private string _queryTextBeforeLeaveResults;
private readonly FlowLauncherJsonStorage _historyItemsStorage;
@@ -986,19 +984,10 @@ private void QueryContextMenu()
if (selected != null) // SelectedItem returns null if selection is empty.
{
List results;
- if (selected == lastContextMenuResult)
- {
- results = lastContextMenuResults;
- }
- else
- {
+
results = PluginManager.GetContextMenusForPlugin(selected);
- lastContextMenuResults = results;
- lastContextMenuResult = selected;
results.Add(ContextMenuTopMost(selected));
results.Add(ContextMenuPluginInfo(selected.PluginID));
- }
-
if (!string.IsNullOrEmpty(query))
{
@@ -1381,8 +1370,6 @@ public async void Hide()
lastHistoryIndex = 1;
// Trick for no delay
MainWindowOpacity = 0;
- lastContextMenuResult = new Result();
- lastContextMenuResults = new List();
if (ExternalPreviewVisible)
CloseExternalPreview();
From 00de8611e1996d724c48672b5712c4db8f071b63 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:37:41 +0800
Subject: [PATCH 0180/1335] Remove useless obsolete constructor
---
Flow.Launcher.Plugin/Query.cs | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index b41675a1aa4..e182491c2f0 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json.Serialization;
+using System.Text.Json.Serialization;
namespace Flow.Launcher.Plugin
{
@@ -9,15 +6,6 @@ public class Query
{
public Query() { }
- [Obsolete("Use the default Query constructor.")]
- public Query(string rawQuery, string search, string[] terms, string[] searchTerms, string actionKeyword = "")
- {
- Search = search;
- RawQuery = rawQuery;
- SearchTerms = searchTerms;
- ActionKeyword = actionKeyword;
- }
-
///
/// Raw query, this includes action keyword if it has
/// We didn't recommend use this property directly. You should always use Search property.
From 95c8475c436b687822ddee2b342da5e4945225b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:45:58 +0800
Subject: [PATCH 0181/1335] Fix null exception when result is from context menu
& Add documents
---
Flow.Launcher/Storage/TopMostRecord.cs | 2 ++
Flow.Launcher/Storage/UserSelectedRecord.cs | 2 ++
Flow.Launcher/ViewModel/MainViewModel.cs | 14 +++++++++-----
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index cbd0b88fc7e..e76c5749344 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,6 +12,8 @@ public class TopMostRecord
internal bool IsTopMost(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to check if the result is top most
if (records.IsEmpty || result.OriginQuery == null ||
!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
diff --git a/Flow.Launcher/Storage/UserSelectedRecord.cs b/Flow.Launcher/Storage/UserSelectedRecord.cs
index d6405005dba..4f62d2b08a9 100644
--- a/Flow.Launcher/Storage/UserSelectedRecord.cs
+++ b/Flow.Launcher/Storage/UserSelectedRecord.cs
@@ -51,6 +51,8 @@ private static int GenerateResultHashCode(Result result)
private static int GenerateQueryAndResultHashCode(Query query, Result result)
{
+ // query is null when user select the context menu item directly of one item from query list
+ // so we only need to consider the result
if (query == null)
{
return GenerateResultHashCode(result);
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2d232ebdd01..5c3251bfc7e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -396,11 +396,15 @@ private async Task OpenResultAsync(string index)
})
.ConfigureAwait(false);
-
if (SelectedIsFromQueryResults())
{
_userSelectedRecord.Add(result);
- _history.Add(result.OriginQuery.RawQuery);
+ // origin query is null when user select the context menu item directly of one item from query list
+ // so we don't want to add it to history
+ if (result.OriginQuery != null)
+ {
+ _history.Add(result.OriginQuery.RawQuery);
+ }
lastHistoryIndex = 1;
}
@@ -985,9 +989,9 @@ private void QueryContextMenu()
{
List results;
- results = PluginManager.GetContextMenusForPlugin(selected);
- results.Add(ContextMenuTopMost(selected));
- results.Add(ContextMenuPluginInfo(selected.PluginID));
+ results = PluginManager.GetContextMenusForPlugin(selected);
+ results.Add(ContextMenuTopMost(selected));
+ results.Add(ContextMenuPluginInfo(selected.PluginID));
if (!string.IsNullOrEmpty(query))
{
From 80f54ba0de3b55c6ef1cac360078dddd9a1e07a4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 26 Jan 2025 20:51:12 +0800
Subject: [PATCH 0182/1335] Fix more possible origin query null exception &
Remove useless load function
---
Flow.Launcher/Storage/TopMostRecord.cs | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index e76c5749344..a2af6fe92d8 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -26,11 +26,25 @@ internal bool IsTopMost(Result result)
internal void Remove(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to remove the record
+ if (result.OriginQuery == null)
+ {
+ return;
+ }
+
records.Remove(result.OriginQuery.RawQuery, out _);
}
internal void AddOrUpdate(Result result)
{
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to add or update the record
+ if (result.OriginQuery == null)
+ {
+ return;
+ }
+
var record = new Record
{
PluginID = result.PluginID,
@@ -39,11 +53,6 @@ internal void AddOrUpdate(Result result)
};
records.AddOrUpdate(result.OriginQuery.RawQuery, record, (key, oldValue) => record);
}
-
- public void Load(Dictionary dictionary)
- {
- records = new ConcurrentDictionary(dictionary);
- }
}
public class Record
From 1c7e29013e96efb1abecdb3bb9f1a2043017b49c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:11:27 +0800
Subject: [PATCH 0183/1335] Fix setting window freeze issue & Improve singleton
window opener
---
Flow.Launcher/Helper/SingletonWindowOpener.cs | 21 +++++++++++++++----
Flow.Launcher/SettingWindow.xaml.cs | 4 ++--
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Helper/SingletonWindowOpener.cs b/Flow.Launcher/Helper/SingletonWindowOpener.cs
index b5c2d8b55a7..5282b61f97e 100644
--- a/Flow.Launcher/Helper/SingletonWindowOpener.cs
+++ b/Flow.Launcher/Helper/SingletonWindowOpener.cs
@@ -10,16 +10,29 @@ public static T Open(params object[] args) where T : Window
{
var window = Application.Current.Windows.OfType().FirstOrDefault(x => x.GetType() == typeof(T))
?? (T)Activator.CreateInstance(typeof(T), args);
-
+
// Fix UI bug
// Add `window.WindowState = WindowState.Normal`
// If only use `window.Show()`, Settings-window doesn't show when minimized in taskbar
// Not sure why this works tho
// Probably because, when `.Show()` fails, `window.WindowState == Minimized` (not `Normal`)
// https://stackoverflow.com/a/59719760/4230390
- window.WindowState = WindowState.Normal;
- window.Show();
-
+ // Ensure the window is not minimized before showing it
+ if (window.WindowState == WindowState.Minimized)
+ {
+ window.WindowState = WindowState.Normal;
+ }
+
+ // Ensure the window is visible
+ if (!window.IsVisible)
+ {
+ window.Show();
+ }
+ else
+ {
+ window.Activate(); // Bring the window to the foreground if already open
+ }
+
window.Focus();
return (T)window;
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cb3f1e4a113..d5b30351617 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -34,11 +34,11 @@ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
private void OnLoaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
- // Fix (workaround) for the window freezes after lock screen (Win+L)
+ // Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
- hwndTarget.RenderMode = RenderMode.Default;
+ hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
InitializePosition();
}
From 23a1e5bc5853d2f6a4ba0e83c1c36ac960da40d9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:39:12 +0800
Subject: [PATCH 0184/1335] Initialize public api instance in constructor so
that we can use App.API all the time
---
Flow.Launcher/App.xaml.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index d983ab0005e..f800ccd5dc1 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -54,6 +54,9 @@ public App()
.AddSingleton()
).Build();
Ioc.Default.ConfigureServices(host.Services);
+
+ // Initialize the public API first
+ API = Ioc.Default.GetRequiredService();
}
[STAThread]
@@ -73,8 +76,6 @@ private async void OnStartupAsync(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- API = Ioc.Default.GetRequiredService();
-
Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
From ed16d340cb1c43464b9046a2672edc5d189c01bc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 09:40:24 +0800
Subject: [PATCH 0185/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 6 +++---
Flow.Launcher.Infrastructure/Http/Http.cs | 3 ++-
Flow.Launcher/App.xaml.cs | 3 +--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a776c10ab2f..0e8a4b7764b 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,6 +14,7 @@
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Plugin
{
@@ -28,7 +29,7 @@ public static class PluginManager
public static readonly HashSet GlobalPlugins = new();
public static readonly Dictionary NonGlobalPlugins = new();
- public static IPublicAPI API { private set; get; }
+ public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService();
private static PluginsSettings Settings;
private static List _metadatas;
@@ -158,9 +159,8 @@ public static void LoadPlugins(PluginsSettings settings)
/// Call initialize for all plugins
///
/// return the list of failed to init plugins or null for none
- public static async Task InitializePluginsAsync(IPublicAPI api)
+ public static async Task InitializePluginsAsync()
{
- API = api;
var failedPlugins = new ConcurrentQueue();
var InitTasks = AllPlugins.Select(pair => Task.Run(async delegate
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 14b8eef4e16..3711a6b0d20 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -8,6 +8,7 @@
using System;
using System.Threading;
using Flow.Launcher.Plugin;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Infrastructure.Http
{
@@ -17,7 +18,7 @@ public static class Http
private static HttpClient client = new HttpClient();
- public static IPublicAPI API { get; set; }
+ private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
static Http()
{
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index f800ccd5dc1..5f7f097e0dd 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -99,10 +99,9 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
PluginManager.LoadPlugins(_settings.PluginSettings);
- Http.API = API;
Http.Proxy = _settings.Proxy;
- await PluginManager.InitializePluginsAsync(API);
+ await PluginManager.InitializePluginsAsync();
await imageLoadertask;
var mainVM = Ioc.Default.GetRequiredService();
From 6a2389f4b8c95d87ee72041a0e78812333fe3fd3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 27 Jan 2025 10:45:05 +0800
Subject: [PATCH 0186/1335] Fix test project build issue
---
Flow.Launcher.Infrastructure/Http/Http.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 3711a6b0d20..78545a87b76 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -18,8 +18,6 @@ public static class Http
private static HttpClient client = new HttpClient();
- private static IPublicAPI API { get; set; } = Ioc.Default.GetRequiredService();
-
static Http()
{
// need to be added so it would work on a win10 machine
@@ -79,7 +77,7 @@ var userName when string.IsNullOrEmpty(userName) =>
}
catch (UriFormatException e)
{
- API.ShowMsg("Please try again", "Unable to parse Http Proxy");
+ Ioc.Default.GetRequiredService().ShowMsg("Please try again", "Unable to parse Http Proxy");
Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
}
}
From 9a8eabd5ee94366f3a90645bd45aa839f067afef Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 27 Jan 2025 22:56:19 +0000
Subject: [PATCH 0187/1335] Bump Microsoft.Data.Sqlite from 9.0.0 to 9.0.1
Bumps [Microsoft.Data.Sqlite](https://github.com/dotnet/efcore) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/dotnet/efcore/releases)
- [Commits](https://github.com/dotnet/efcore/compare/v9.0.0...v9.0.1)
---
updated-dependencies:
- dependency-name: Microsoft.Data.Sqlite
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index 03ac0491f96..d7a626e1d5d 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -95,7 +95,7 @@
-
+
From 208e4a8c204749ac9c78ab32ed0172c7c1075b77 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 27 Jan 2025 22:56:59 +0000
Subject: [PATCH 0188/1335] Bump VirtualizingWrapPanel from 2.1.0 to 2.1.1
Bumps [VirtualizingWrapPanel](https://github.com/sbaeumlisberger/VirtualizingWrapPanel) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/releases)
- [Commits](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/compare/v2.1.0...v2.1.1)
---
updated-dependencies:
- dependency-name: VirtualizingWrapPanel
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 788beddfb37..16228258f5f 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -100,7 +100,7 @@
-
+
From 3260faba985a595b2df48c0541ebb9bef6aea88e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 31 Jan 2025 22:01:29 +0800
Subject: [PATCH 0189/1335] Add support for changing startup to logon task for
faster startup experience
---
.../UserSettings/Settings.cs | 1 +
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/Helper/AutoStartup.cs | 115 +++++++++++++++++-
.../SettingsPaneGeneralViewModel.cs | 34 +++++-
.../Views/SettingsPaneGeneral.xaml | 7 ++
6 files changed, 151 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index c412fb32f5a..81895fdcc3c 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -238,6 +238,7 @@ public SearchPrecisionScore QuerySearchPrecision
public bool EnableUpdateLog { get; set; }
public bool StartFlowLauncherOnSystemStartup { get; set; } = false;
+ public bool UseLogonTaskForStartup { get; set; } = false;
public bool HideOnStartup { get; set; } = true;
bool _hideNotifyIcon { get; set; }
public bool HideNotifyIcon
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 4d1adc6cd51..38f846d92e9 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -119,7 +119,7 @@ private void AutoStartup()
{
try
{
- Helper.AutoStartup.Enable();
+ Helper.AutoStartup.Enable(_settings.UseLogonTaskForStartup);
}
catch (Exception e)
{
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 788beddfb37..570785be709 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -100,6 +100,7 @@
+
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 4bff30caf03..116520ecfb3 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -1,18 +1,31 @@
using System;
+using System.IO;
+using System.Linq;
+using System.Security.Principal;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Microsoft.Win32;
+using Microsoft.Win32.TaskScheduler;
namespace Flow.Launcher.Helper;
public class AutoStartup
{
private const string StartupPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
+ private const string LogonTaskName = $"{Constant.FlowLauncher} Startup";
+ private const string LogonTaskDesc = $"{Constant.FlowLauncher} Auto Startup";
public static bool IsEnabled
{
get
{
+ // Check if logon task is enabled
+ if (CheckLogonTask())
+ {
+ return true;
+ }
+
+ // Check if registry is enabled
try
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
@@ -28,12 +41,45 @@ public static bool IsEnabled
}
}
- public static void Disable()
+ private static bool CheckLogonTask()
+ {
+ using var taskService = new TaskService();
+ var task = taskService.RootFolder.AllTasks.FirstOrDefault(t => t.Name == LogonTaskName);
+ if (task != null)
+ {
+ try
+ {
+ // Check if the action is the same as the current executable path
+ var action = task.Definition.Actions.FirstOrDefault()!.ToString().Trim();
+ if (!Constant.ExecutablePath.Equals(action, StringComparison.OrdinalIgnoreCase) && !File.Exists(action))
+ {
+ UnscheduleLogonTask();
+ ScheduleLogonTask();
+ }
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to check logon task");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static void Disable(bool logonTask)
{
try
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.DeleteValue(Constant.FlowLauncher, false);
+ if (logonTask)
+ {
+ UnscheduleLogonTask();
+ }
+ else
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
+ key?.DeleteValue(Constant.FlowLauncher, false);
+ }
}
catch (Exception e)
{
@@ -42,12 +88,19 @@ public static void Disable()
}
}
- internal static void Enable()
+ internal static void Enable(bool logonTask)
{
try
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
+ if (logonTask)
+ {
+ ScheduleLogonTask();
+ }
+ else
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
+ key?.SetValue(Constant.FlowLauncher, $"\"{Constant.ExecutablePath}\"");
+ }
}
catch (Exception e)
{
@@ -55,4 +108,54 @@ internal static void Enable()
throw;
}
}
+
+ private static bool ScheduleLogonTask()
+ {
+ using var td = TaskService.Instance.NewTask();
+ td.RegistrationInfo.Description = LogonTaskDesc;
+ td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name, Delay = TimeSpan.FromSeconds(2) });
+ td.Actions.Add(Constant.ExecutablePath);
+
+ if (IsCurrentUserIsAdmin())
+ {
+ td.Principal.RunLevel = TaskRunLevel.Highest;
+ }
+
+ td.Settings.StopIfGoingOnBatteries = false;
+ td.Settings.DisallowStartIfOnBatteries = false;
+ td.Settings.ExecutionTimeLimit = TimeSpan.Zero;
+
+ try
+ {
+ TaskService.Instance.RootFolder.RegisterTaskDefinition(LogonTaskName, td);
+ return true;
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to schedule logon task");
+ return false;
+ }
+ }
+
+ private static bool UnscheduleLogonTask()
+ {
+ using var taskService = new TaskService();
+ try
+ {
+ taskService.RootFolder.DeleteTask(LogonTaskName);
+ return true;
+ }
+ catch (Exception)
+ {
+ Log.Error("AutoStartup", "Failed to unschedule logon task");
+ return false;
+ }
+ }
+
+ private static bool IsCurrentUserIsAdmin()
+ {
+ var identity = WindowsIdentity.GetCurrent();
+ var principal = new WindowsPrincipal(identity);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3d94355e687..0aca761a0fe 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -42,9 +42,16 @@ public bool StartFlowLauncherOnSystemStartup
try
{
if (value)
- AutoStartup.Enable();
+ {
+ // Enable either registry or task scheduler
+ AutoStartup.Enable(UseLogonTaskForStartup);
+ }
else
- AutoStartup.Disable();
+ {
+ // Disable both registry and task scheduler
+ AutoStartup.Disable(true);
+ AutoStartup.Disable(false);
+ }
}
catch (Exception e)
{
@@ -54,6 +61,29 @@ public bool StartFlowLauncherOnSystemStartup
}
}
+ public bool UseLogonTaskForStartup
+ {
+ get => Settings.UseLogonTaskForStartup;
+ set
+ {
+ Settings.UseLogonTaskForStartup = value;
+
+ if (StartFlowLauncherOnSystemStartup)
+ {
+ try
+ {
+ // Disable and enable to update the startup method
+ AutoStartup.Disable(!UseLogonTaskForStartup);
+ AutoStartup.Enable(UseLogonTaskForStartup);
+ }
+ catch (Exception e)
+ {
+ Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ e.Message);
+ }
+ }
+ }
+ }
public List SearchWindowScreens { get; } =
DropdownDataGeneric.GetValues("SearchWindowScreen");
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 30e065b1601..f57eba65416 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -36,6 +36,13 @@
OnContent="{DynamicResource enable}" />
+
+
+
+
Date: Fri, 31 Jan 2025 22:06:53 +0800
Subject: [PATCH 0190/1335] Move string to resources
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/Languages/zh-cn.xaml | 8 ++++++--
Flow.Launcher/Languages/zh-tw.xaml | 8 ++++++--
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 2 +-
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f52..8e8c9abefe6 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -46,6 +46,7 @@
Portable Mode
Store all settings and user data in one folder (Useful when used with removable drives or cloud services).
Start Flow Launcher on system startup
+ Use logon task instead of startup entry for faster startup experience
Error setting launch on startup
Hide Flow Launcher when focus is lost
Do not show new version notifications
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 681c715fb03..d2d1044af7e 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -1,5 +1,8 @@
-
-
+
+
Flow 检测到您已安装 {0} 个插件,需要 {1} 才能运行。是否要下载 {1}?
@@ -44,6 +47,7 @@
便携模式
将所有设置和用户数据存储在一个文件夹中 (可用于可移除驱动器或云服务)。
开机自启
+ 使用登录任务而非启动项以更快自启
设置开机自启时出错
失去焦点时自动隐藏 Flow Launcher
不显示新版本提示
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 44be5257bb2..b5aa5337781 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -1,5 +1,8 @@
-
-
+
+
Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
@@ -44,6 +47,7 @@
便攜模式
將所有設定和使用者資料存儲在一個資料夾中(當與可移動磁碟或雲服務一起使用時很有用)。
開機時啟動
+ 使用登錄任務而非啟動項以更快自啟
Error setting launch on startup
失去焦點時自動隱藏 Flow Launcher
不顯示新版本提示
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index f57eba65416..e52614e7478 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -36,7 +36,7 @@
OnContent="{DynamicResource enable}" />
-
+
Date: Fri, 31 Jan 2025 22:22:00 +0800
Subject: [PATCH 0191/1335] Fix issue when checking logon task
---
Flow.Launcher/Helper/AutoStartup.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 116520ecfb3..79466f1fb1b 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -56,15 +56,16 @@ private static bool CheckLogonTask()
UnscheduleLogonTask();
ScheduleLogonTask();
}
+
+ return true;
}
catch (Exception)
{
Log.Error("AutoStartup", "Failed to check logon task");
- return false;
}
}
- return true;
+ return false;
}
public static void Disable(bool logonTask)
From e320ca1d492594351d81f05ab3da8838c8672dd6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Feb 2025 13:10:32 +0800
Subject: [PATCH 0192/1335] Add support for deleting plugin settings when
uninstalling plugins
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 21 +++++++++++++++----
.../Languages/en.xaml | 6 ++++--
.../Languages/zh-cn.xaml | 6 ++++--
.../Languages/zh-tw.xaml | 6 ++++--
.../PluginsManager.cs | 6 +++++-
5 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1dadc..55bc0e2bddb 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,6 +14,7 @@
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Infrastructure.Storage;
namespace Flow.Launcher.Core.Plugin
{
@@ -439,7 +440,7 @@ public static bool PluginModified(string uuid)
public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
- UninstallPlugin(existingVersion, removeSettings:false, checkModified:false);
+ UninstallPlugin(existingVersion, removeSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}
@@ -454,9 +455,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath)
///
/// Uninstall a plugin.
///
- public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true)
+ public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true, bool removePluginSettings = false)
{
- UninstallPlugin(plugin, removeSettings, true);
+ UninstallPlugin(plugin, removeSettings, removePluginSettings, true);
}
#endregion
@@ -529,7 +530,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
}
}
- internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified)
+ internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
@@ -542,6 +543,18 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings,
AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
}
+ if (removePluginSettings)
+ {
+ var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
+ var assembly = assemblyLoader.LoadAssemblyAndDependencies();
+ var assemblyName = assembly.GetName().Name;
+ var directoryPath = Path.Combine(DataLocation.DataDirectory(), JsonStorage.DirectoryName, Constant.Plugins, assemblyName);
+ if (Directory.Exists(directoryPath))
+ {
+ Directory.Delete(directoryPath, true);
+ }
+ }
+
// Marked for deletion. Will be deleted on next start up
using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt"));
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index de6a3a2fb4c..573ca90519e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -15,6 +15,8 @@
Installing Plugin
Download and install {0}
Plugin Uninstall
+ Keep plugin settings
+ Do you want to keep the settings of the plugin for the next usage?
Plugin {0} successfully installed. Restarting Flow, please wait...
Unable to find the plugin.json metadata file from the extracted zip file.
Error: A plugin which has the same or greater version with {0} already exists.
@@ -37,13 +39,13 @@
Plugin {0} successfully updated. Restarting Flow, please wait...
Installing from an unknown source
You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
-
+
Plugin {0} successfully installed. Please restart Flow.
Plugin {0} successfully uninstalled. Please restart Flow.
Plugin {0} successfully updated. Please restart Flow.
{0} plugins successfully updated. Please restart Flow.
Plugin {0} has already been modified. Please restart Flow before making any further changes.
-
+
Plugins Manager
Management of installing, uninstalling or updating Flow Launcher plugins
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
index 676c20a734d..033bfed9489 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
@@ -13,6 +13,8 @@
正在安装插件
下载与安装 {0}
插件卸载
+ 保留插件设置
+ 你希望保留插件设置以便于下次使用吗?
插件安装成功。正在重新启动 Flow Launcher,请稍候...
安装失败:无法从新插件中找到plugin.json元数据文件
错误:具有相同或更高版本的 {0} 的插件已经存在。
@@ -35,13 +37,13 @@
插件{0}更新成功。正在重新启动 Flow Launcher,请稍候...
从未知源安装
您正在从未知源安装此插件,它可能包含潜在风险!{0}{0}请确保您了解来源以及安全性。{0}{0}您想要继续吗?{0}{0}(您可以通过设置关闭此警告)
-
+
成功安装插件{0}。请重新启动 Flow Launcher。
成功卸载插件{0}。请重新启动 Flow Launcher。
成功更新插件{0}。请重新启动 Flow Launcher。
插件 {0} 更新成功。请重新启动 Flow Launcher。
插件 {0} 已被修改。请在进行任何进一步更改之前重新启动Flow。
-
+
插件管理
安装,卸载或更新 Flow Launcher 插件
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
index ae37579dc32..c2497b70b1e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
@@ -13,6 +13,8 @@
Installing Plugin
下載並安裝 {0}
解除安裝擴充功能
+ 保留插件設置
+ 你希望保留插件設置以便於下次使用嗎?
外掛安裝成功。正在重啟 Flow,請稍後...
Unable to find the plugin.json metadata file from the extracted zip file.
Error: A plugin which has the same or greater version with {0} already exists.
@@ -35,13 +37,13 @@
Plugin {0} successfully updated. Restarting Flow, please wait...
Installing from an unknown source
You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
-
+
Plugin {0} successfully installed. Please restart Flow.
Plugin {0} successfully uninstalled. Please restart Flow.
Plugin {0} successfully updated. Please restart Flow.
{0} plugins successfully updated. Please restart Flow.
Plugin {0} has already been modified. Please restart Flow before making any further changes.
-
+
擴充功能管理
Management of installing, uninstalling or updating Flow Launcher plugins
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 305d248d3e8..fe3b9d3f238 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -682,7 +682,11 @@ private void Uninstall(PluginMetadata plugin)
{
try
{
- PluginManager.UninstallPlugin(plugin, removeSettings: true);
+ var removePluginSettings = Context.API.ShowMsgBox(
+ Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"),
+ Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"),
+ button: MessageBoxButton.YesNo) == MessageBoxResult.No;
+ PluginManager.UninstallPlugin(plugin, removeSettings: true, removePluginSettings: removePluginSettings);
}
catch (ArgumentException e)
{
From bb7900c0e0da0f9a3eefbaa953c19e98cb9c06f6 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Sun, 2 Feb 2025 15:27:02 +0600
Subject: [PATCH 0193/1335] Add PyWin32-related directories to path for Python
plugins
---
Flow.Launcher.Core/Plugin/PythonPlugin.cs | 4 ++++
Flow.Launcher.Core/Plugin/PythonPluginV2.cs | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/PythonPlugin.cs b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
index 7b670742ab4..e40b0330e78 100644
--- a/Flow.Launcher.Core/Plugin/PythonPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPlugin.cs
@@ -58,6 +58,8 @@ public override async Task InitAsync(PluginInitContext context)
{
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
var libDirectory = Path.Combine(rootDirectory, "lib");
+ var libPyWin32Directory = Path.Combine(libDirectory, "win32");
+ var libPyWin32LibDirectory = Path.Combine(libPyWin32Directory, "lib");
var pluginDirectory = Path.Combine(rootDirectory, "plugin");
// This makes it easier for plugin authors to import their own modules.
@@ -70,6 +72,8 @@ public override async Task InitAsync(PluginInitContext context)
import sys
sys.path.append(r'{rootDirectory}')
sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{libPyWin32LibDirectory}')
+ sys.path.append(r'{libPyWin32Directory}')
sys.path.append(r'{pluginDirectory}')
import runpy
diff --git a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
index 03ac0e66154..8a9e1ff44b8 100644
--- a/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/PythonPluginV2.cs
@@ -36,6 +36,8 @@ public override async Task InitAsync(PluginInitContext context)
{
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
var libDirectory = Path.Combine(rootDirectory, "lib");
+ var libPyWin32Directory = Path.Combine(libDirectory, "win32");
+ var libPyWin32LibDirectory = Path.Combine(libPyWin32Directory, "lib");
var pluginDirectory = Path.Combine(rootDirectory, "plugin");
var filePath = context.CurrentPluginMetadata.ExecuteFilePath;
@@ -49,6 +51,8 @@ public override async Task InitAsync(PluginInitContext context)
import sys
sys.path.append(r'{rootDirectory}')
sys.path.append(r'{libDirectory}')
+ sys.path.append(r'{libPyWin32LibDirectory}')
+ sys.path.append(r'{libPyWin32Directory}')
sys.path.append(r'{pluginDirectory}')
import runpy
From f708ad9ffdb823282e522b31608289e68beefcd2 Mon Sep 17 00:00:00 2001
From: Azakidev
Date: Tue, 4 Feb 2025 23:18:21 +0100
Subject: [PATCH 0194/1335] Add Windows Terminal to Shell Plugin
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 27 +++++++++++++++++++
.../Flow.Launcher.Plugin.Shell/Settings.cs | 2 ++
.../ShellSetting.xaml | 4 ++-
.../ShellSetting.xaml.cs | 4 +++
4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 921c6bc2169..a192b890046 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -279,6 +279,33 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
break;
}
+ case Shell.TerminalPWSH:
+ {
+ info.filename = "wt.exe"
+ info.ArgumentList.Add("pwsh");
+ if (_settings.LeaveShellOpen)
+ {
+ info.ArgumentList.Add("-NoExit");
+ }
+ info.ArgumentList.Add("-Command");
+ info.ArgumentList.Add(command);
+ break;
+ }
+ case Shell.TerminalCMD:
+ {
+ info.filename = "wt.exe"
+ info.ArgumentList.Add("cmd");
+ if (_settings.LeaveShellOpen)
+ {
+ info.ArgumentList.Add("/k");
+ }
+ else
+ {
+ info.ArgumentList.Add("/c");
+ }
+ info.ArgumentList.Add(command);
+ break;
+ }
default:
throw new NotImplementedException();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
index 6f47d5d17d9..75cc56618bb 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
@@ -39,5 +39,7 @@ public enum Shell
Powershell = 1,
RunCommand = 2,
Pwsh = 3,
+ TerminalPWSH = 4,
+ TerminalCMD = 5,
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 2f02ef7238a..22f4ff22dd9 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -43,12 +43,14 @@
Content="{DynamicResource flowlauncher_plugin_cmd_always_run_as_administrator}" />
CMD
PowerShell
Pwsh
+ Terminal (Pwsh)
+ Terminal (CMD)
RunCommand
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
index 24365f2aa71..e981f8b74e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
@@ -91,6 +91,8 @@ private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
Shell.Cmd => 0,
Shell.Powershell => 1,
Shell.Pwsh => 2,
+ Shell.TerminalPWSH = 3,
+ Shell.TerminalCMD = 4,
_ => ShellComboBox.Items.Count - 1
};
@@ -101,6 +103,8 @@ private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
0 => Shell.Cmd,
1 => Shell.Powershell,
2 => Shell.Pwsh,
+ 3 => Shell.TerminalPWSH,
+ 4 => Shell.TerminalCMD,
_ => Shell.RunCommand
};
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
From ff2f0c375cd90ff721739cdc68e406b4ecdae4d3 Mon Sep 17 00:00:00 2001
From: Azakidev
Date: Tue, 4 Feb 2025 23:39:29 +0100
Subject: [PATCH 0195/1335] Fix typos
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 4 ++--
Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index a192b890046..60c8ba1a822 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -281,7 +281,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
}
case Shell.TerminalPWSH:
{
- info.filename = "wt.exe"
+ info.filename = "wt.exe";
info.ArgumentList.Add("pwsh");
if (_settings.LeaveShellOpen)
{
@@ -293,7 +293,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
}
case Shell.TerminalCMD:
{
- info.filename = "wt.exe"
+ info.filename = "wt.exe";
info.ArgumentList.Add("cmd");
if (_settings.LeaveShellOpen)
{
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
index e981f8b74e1..eaac8731a79 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml.cs
@@ -91,8 +91,8 @@ private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
Shell.Cmd => 0,
Shell.Powershell => 1,
Shell.Pwsh => 2,
- Shell.TerminalPWSH = 3,
- Shell.TerminalCMD = 4,
+ Shell.TerminalPWSH => 3,
+ Shell.TerminalCMD => 4,
_ => ShellComboBox.Items.Count - 1
};
From 3596a77b343bd0a0332a7cde43228bb9affcaaa3 Mon Sep 17 00:00:00 2001
From: Azakidev
Date: Tue, 4 Feb 2025 23:54:04 +0100
Subject: [PATCH 0196/1335] Fix the rest of my mistakes
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 4 ++--
Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 60c8ba1a822..fc8746e41de 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -281,7 +281,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
}
case Shell.TerminalPWSH:
{
- info.filename = "wt.exe";
+ info.FileName = "wt.exe";
info.ArgumentList.Add("pwsh");
if (_settings.LeaveShellOpen)
{
@@ -293,7 +293,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
}
case Shell.TerminalCMD:
{
- info.filename = "wt.exe";
+ info.FileName = "wt.exe";
info.ArgumentList.Add("cmd");
if (_settings.LeaveShellOpen)
{
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 22f4ff22dd9..7e35a872f59 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -43,7 +43,7 @@
Content="{DynamicResource flowlauncher_plugin_cmd_always_run_as_administrator}" />
CMD
From 5bb3d724c026e7cc2bd8b22079cd4e94173f14e1 Mon Sep 17 00:00:00 2001
From: Azakidev
Date: Thu, 6 Feb 2025 00:22:41 +0100
Subject: [PATCH 0197/1335] Use a checkbox instead of separate entries
---
.../Languages/en.xaml | 3 +-
.../Languages/es-419.xaml | 1 +
.../Languages/es.xaml | 1 +
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 77 ++++++++-----------
.../Flow.Launcher.Plugin.Shell/Settings.cs | 4 +-
.../ShellSetting.xaml | 13 +++-
.../ShellSetting.xaml.cs | 16 +++-
7 files changed, 57 insertions(+), 58 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
index 52aaf3c27f9..645a0e14fd7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
@@ -7,6 +7,7 @@
Press any key to close this window...
Do not close Command Prompt after command execution
Always run as administrator
+ Use Windows Terminal
Run as different user
Shell
Allows to execute system commands from Flow Launcher
@@ -15,4 +16,4 @@
Run As Administrator
Copy the command
Only show number of most used commands:
-
\ No newline at end of file
+
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
index 5ee2c43b4f2..f3ef0df0ae3 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
@@ -6,6 +6,7 @@
Press any key to close this window...
No cerrar Símbolo del Sistema tras ejecutar el comando
Siempre ejecutar como administrador
+ Ejecutar en la Terminal de Windows
Ejecutar como otro usuario
Shell
Allows to execute system commands from Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
index a3ee35ef8c4..ee3193b16e4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
@@ -6,6 +6,7 @@
Pulsar cualquier tecla para cerrar esta ventana...
No cerrar el símbolo del sistema después de la ejecución del comando
Ejecutar siempre como administrador
+ Ejecutar en la Terminal de Windows
Ejecutar como usuario diferente
Terminal
Permite ejecutar comandos del sistema desde Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index fc8746e41de..7f1f4bd4da3 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -202,28 +202,31 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
{
case Shell.Cmd:
{
- info.FileName = "cmd.exe";
- info.Arguments = $"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}";
-
- //// Use info.Arguments instead of info.ArgumentList to enable users better control over the arguments they are writing.
- //// Previous code using ArgumentList, commands needed to be separated correctly:
- //// Incorrect:
- // info.ArgumentList.Add(_settings.LeaveShellOpen ? "/k" : "/c");
- // info.ArgumentList.Add(command); //<== info.ArgumentList.Add("mkdir \"c:\\test new\"");
-
- //// Correct version should be:
- //info.ArgumentList.Add(_settings.LeaveShellOpen ? "/k" : "/c");
- //info.ArgumentList.Add("mkdir");
- //info.ArgumentList.Add(@"c:\test new");
-
- //https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=net-6.0#remarks
+ if (_settings.UseWindowsTerminal)
+ {
+ info.FileName = "wt.exe";
+ info.ArgumentList.Add("cmd");
+ }
+ else
+ {
+ info.FileName = "cmd.exe";
+ }
+ info.ArgumentList.Add($"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}");
break;
}
case Shell.Powershell:
{
- info.FileName = "powershell.exe";
+ if (_settings.UseWindowsTerminal)
+ {
+ info.FileName = "wt.exe";
+ info.ArgumentList.Add("powershell");
+ }
+ else
+ {
+ info.FileName = "powershell.exe";
+ }
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
@@ -232,21 +235,28 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
else
{
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'; [System.Console]::ReadKey(); exit" : "")}");
+ info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
}
break;
}
case Shell.Pwsh:
{
- info.FileName = "pwsh.exe";
+ if (_settings.UseWindowsTerminal)
+ {
+ info.FileName = "wt.exe";
+ info.ArgumentList.Add("pwsh");
+ }
+ else
+ {
+ info.FileName = "pwsh.exe";
+ }
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'; [System.Console]::ReadKey(); exit" : "")}");
-
+ info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
break;
}
@@ -279,33 +289,6 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
break;
}
- case Shell.TerminalPWSH:
- {
- info.FileName = "wt.exe";
- info.ArgumentList.Add("pwsh");
- if (_settings.LeaveShellOpen)
- {
- info.ArgumentList.Add("-NoExit");
- }
- info.ArgumentList.Add("-Command");
- info.ArgumentList.Add(command);
- break;
- }
- case Shell.TerminalCMD:
- {
- info.FileName = "wt.exe";
- info.ArgumentList.Add("cmd");
- if (_settings.LeaveShellOpen)
- {
- info.ArgumentList.Add("/k");
- }
- else
- {
- info.ArgumentList.Add("/c");
- }
- info.ArgumentList.Add(command);
- break;
- }
default:
throw new NotImplementedException();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
index 75cc56618bb..9ce2293a200 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
@@ -14,6 +14,8 @@ public class Settings
public bool RunAsAdministrator { get; set; } = true;
+ public bool UseWindowsTerminal { get; set; } = false;
+
public bool ShowOnlyMostUsedCMDs { get; set; }
public int ShowOnlyMostUsedCMDsNumber { get; set; }
@@ -39,7 +41,5 @@ public enum Shell
Powershell = 1,
RunCommand = 2,
Pwsh = 3,
- TerminalPWSH = 4,
- TerminalCMD = 5,
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 7e35a872f59..8a3b7f11533 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -16,6 +16,7 @@
+
+
CMD
PowerShell
Pwsh
- Terminal (Pwsh)
- Terminal (CMD)
RunCommand
-
+
+ {
+ _settings.UseWindowsTerminal = true;
+ };
+
+ UseWindowsTerminal.Unchecked += (o, e) =>
+ {
+ _settings.UseWindowsTerminal = false;
+ };
+
ReplaceWinR.Checked += (o, e) =>
{
_settings.ReplaceWinR = true;
@@ -91,8 +103,6 @@ private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
Shell.Cmd => 0,
Shell.Powershell => 1,
Shell.Pwsh => 2,
- Shell.TerminalPWSH => 3,
- Shell.TerminalCMD => 4,
_ => ShellComboBox.Items.Count - 1
};
@@ -103,8 +113,6 @@ private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
0 => Shell.Cmd,
1 => Shell.Powershell,
2 => Shell.Pwsh,
- 3 => Shell.TerminalPWSH,
- 4 => Shell.TerminalCMD,
_ => Shell.RunCommand
};
LeaveShellOpen.IsEnabled = _settings.Shell != Shell.RunCommand;
From 0e02a6f9cff393b1cfa7bec5bb70e1f60e87127a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Feb 2025 07:51:44 +0800
Subject: [PATCH 0198/1335] Revert changes in non-English language files
---
.../Languages/zh-cn.xaml | 9 +++++----
.../Languages/zh-tw.xaml | 9 +++++----
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
index 033bfed9489..e6be9069d99 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
@@ -1,5 +1,8 @@
-
-
+
+
正在下载插件...
@@ -13,8 +16,6 @@
正在安装插件
下载与安装 {0}
插件卸载
- 保留插件设置
- 你希望保留插件设置以便于下次使用吗?
插件安装成功。正在重新启动 Flow Launcher,请稍候...
安装失败:无法从新插件中找到plugin.json元数据文件
错误:具有相同或更高版本的 {0} 的插件已经存在。
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
index c2497b70b1e..9736728a760 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
@@ -1,5 +1,8 @@
-
-
+
+
正在下載擴充功能
@@ -13,8 +16,6 @@
Installing Plugin
下載並安裝 {0}
解除安裝擴充功能
- 保留插件設置
- 你希望保留插件設置以便於下次使用嗎?
外掛安裝成功。正在重啟 Flow,請稍後...
Unable to find the plugin.json metadata file from the extracted zip file.
Error: A plugin which has the same or greater version with {0} already exists.
From 71b79da5d433c10de38241682245add9b6858359 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Feb 2025 07:53:40 +0800
Subject: [PATCH 0199/1335] Revert auto format
---
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 5 +----
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 5 +----
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
index e6be9069d99..f73516a56c3 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
@@ -1,8 +1,5 @@
-
+
正在下载插件...
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
index 9736728a760..f1b044d2515 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
@@ -1,8 +1,5 @@
-
+
正在下載擴充功能
From 1ff8c3620a030294a6d30d9ae2e93ac14438457a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Feb 2025 07:56:24 +0800
Subject: [PATCH 0200/1335] Revert changes in non-English language files
---
Flow.Launcher/Languages/zh-cn.xaml | 8 ++------
Flow.Launcher/Languages/zh-tw.xaml | 8 ++------
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index d2d1044af7e..681c715fb03 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -1,8 +1,5 @@
-
-
+
+
Flow 检测到您已安装 {0} 个插件,需要 {1} 才能运行。是否要下载 {1}?
@@ -47,7 +44,6 @@
便携模式
将所有设置和用户数据存储在一个文件夹中 (可用于可移除驱动器或云服务)。
开机自启
- 使用登录任务而非启动项以更快自启
设置开机自启时出错
失去焦点时自动隐藏 Flow Launcher
不显示新版本提示
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index b5aa5337781..44be5257bb2 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -1,8 +1,5 @@
-
-
+
+
Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
@@ -47,7 +44,6 @@
便攜模式
將所有設定和使用者資料存儲在一個資料夾中(當與可移動磁碟或雲服務一起使用時很有用)。
開機時啟動
- 使用登錄任務而非啟動項以更快自啟
Error setting launch on startup
失去焦點時自動隱藏 Flow Launcher
不顯示新版本提示
From 7598a6aff507cfff363d94b9f225fa7f6955039e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Feb 2025 08:08:45 +0800
Subject: [PATCH 0201/1335] Revert auto format
---
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 2 +-
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
index f73516a56c3..28196e55f72 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
@@ -1,4 +1,4 @@
-
+
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
index f1b044d2515..96155f440a1 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
@@ -1,4 +1,4 @@
-
+
From 1f1b31994da4ab774e9c0964de342e7129c958d8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Feb 2025 09:35:21 +0800
Subject: [PATCH 0202/1335] Improve argument name to avoid possible confusion
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 10 +++++-----
.../PluginsManager.cs | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 55bc0e2bddb..fc915bcb306 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -440,7 +440,7 @@ public static bool PluginModified(string uuid)
public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
- UninstallPlugin(existingVersion, removeSettings:false, removePluginSettings:false, checkModified: false);
+ UninstallPlugin(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}
@@ -455,9 +455,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath)
///
/// Uninstall a plugin.
///
- public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true, bool removePluginSettings = false)
+ public static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false)
{
- UninstallPlugin(plugin, removeSettings, removePluginSettings, true);
+ UninstallPlugin(plugin, removePluginFromSettings, removePluginSettings, true);
}
#endregion
@@ -530,14 +530,14 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
}
}
- internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool removePluginSettings, bool checkModified)
+ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}
- if (removeSettings)
+ if (removePluginFromSettings)
{
Settings.Plugins.Remove(plugin.ID);
AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index fe3b9d3f238..ac4f90d9218 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -686,7 +686,7 @@ private void Uninstall(PluginMetadata plugin)
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"),
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"),
button: MessageBoxButton.YesNo) == MessageBoxResult.No;
- PluginManager.UninstallPlugin(plugin, removeSettings: true, removePluginSettings: removePluginSettings);
+ PluginManager.UninstallPlugin(plugin, removePluginFromSettings: true, removePluginSettings: removePluginSettings);
}
catch (ArgumentException e)
{
From 69bf7c6b63ff3988e583508583e7543ed1956b2e Mon Sep 17 00:00:00 2001
From: cibere <71997063+cibere@users.noreply.github.com>
Date: Thu, 6 Feb 2025 18:34:44 -0800
Subject: [PATCH 0203/1335] add BackToQueryResults to JsonRPCPublicAPI
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index b8bfee591e6..2d49e48407d 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -173,5 +173,10 @@ public void OpenAppUri(string appUri)
{
_api.OpenAppUri(appUri);
}
+
+ public void BackToQueryResults()
+ {
+ _api.BackToQueryResults();
+ }
}
}
From 646bad6deba7d2c7ac671c21d8f85330e78b8911 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 7 Feb 2025 14:15:01 +0800
Subject: [PATCH 0204/1335] Use parameter for function for readability
---
.../PluginsManager.cs | 55 +++++++++++--------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index ce51e8700af..67148984624 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -148,7 +148,7 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
if (!plugin.IsFromLocalInstallPath)
{
- await DeleteFileAndDownloadMsgBoxAsync(
+ await DownloadFileAsync(
$"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}",
plugin.UrlDownload, filePath, cts);
}
@@ -199,32 +199,39 @@ await DeleteFileAndDownloadMsgBoxAsync(
}
}
- private async Task DeleteFileAndDownloadMsgBoxAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts)
+ private async Task DownloadFileAsync(string prgBoxTitle, string downloadUrl, string filePath, CancellationTokenSource cts, bool deleteFile = true, bool showProgress = true)
{
- if (File.Exists(filePath))
+ if (deleteFile && File.Exists(filePath))
File.Delete(filePath);
- var exceptionHappened = false;
- await Context.API.ShowProgressBoxAsync(prgBoxTitle,
- async (reportProgress) =>
- {
- if (reportProgress == null)
- {
- // when reportProgress is null, it means there is expcetion with the progress box
- // so we record it with exceptionHappened and return so that progress box will close instantly
- exceptionHappened = true;
- return;
- }
- else
+ if (showProgress)
+ {
+ var exceptionHappened = false;
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
{
- await Context.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false);
- }
- }, cts.Cancel);
+ if (reportProgress == null)
+ {
+ // when reportProgress is null, it means there is expcetion with the progress box
+ // so we record it with exceptionHappened and return so that progress box will close instantly
+ exceptionHappened = true;
+ return;
+ }
+ else
+ {
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath, reportProgress, cts.Token).ConfigureAwait(false);
+ }
+ }, cts.Cancel);
- // if exception happened while downloading and user does not cancel downloading,
- // we need to redownload the plugin
- if (exceptionHappened && (!cts.IsCancellationRequested))
- await Context.API.HttpDownloadAsync(downloadUrl, filePath).ConfigureAwait(false);
+ // if exception happened while downloading and user does not cancel downloading,
+ // we need to redownload the plugin
+ if (exceptionHappened && (!cts.IsCancellationRequested))
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
+ else
+ {
+ await Context.API.HttpDownloadAsync(downloadUrl, filePath, token: cts.Token).ConfigureAwait(false);
+ }
}
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
@@ -318,7 +325,7 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
if (!x.PluginNewUserPlugin.IsFromLocalInstallPath)
{
- await DeleteFileAndDownloadMsgBoxAsync(
+ await DownloadFileAsync(
$"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}",
x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
}
@@ -418,7 +425,7 @@ await Task.WhenAll(resultsForUpdate.Select(async plugin =>
{
using var cts = new CancellationTokenSource();
- await DeleteFileAndDownloadMsgBoxAsync(
+ await DownloadFileAsync(
$"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.PluginNewUserPlugin.Name}",
plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
From a3cc5e25f9e8cad6cde6a7360a10da2400589f10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 7 Feb 2025 16:05:35 +0800
Subject: [PATCH 0205/1335] Fix unix directory seperator issue
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs | 2 ++
.../Search/DirectoryInfo/DirectoryInfoSearch.cs | 5 ++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
index e7b43c555f6..bc1fb8e7a91 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
@@ -31,6 +31,8 @@ internal static class Constants
internal const string DefaultContentSearchActionKeyword = "doc:";
+ internal const char UnixDirectorySeparator = '/';
+
internal const char DirectorySeparator = '\\';
internal const string WindowsIndexingOptions = "srchadmin.dll";
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
index 9fd495f4910..e3e1c62e698 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
@@ -12,6 +12,9 @@ public static class DirectoryInfoSearch
{
internal static IEnumerable TopLevelDirectorySearch(Query query, string search, CancellationToken token)
{
+ // if user uses the unix directory separator, we need to convert it to windows directory separator
+ search = search.Replace(Constants.UnixDirectorySeparator, Constants.DirectorySeparator);
+
var criteria = ConstructSearchCriteria(search);
if (search.LastIndexOf(Constants.AllFilesFolderSearchWildcard) >
From 3ee3528e5433c6da1f6f1c37095e92c8ec9153ba Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 7 Feb 2025 16:40:45 +0800
Subject: [PATCH 0206/1335] Revert "Fix unix directory seperator issue"
This reverts commit a3cc5e25f9e8cad6cde6a7360a10da2400589f10.
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs | 2 --
.../Search/DirectoryInfo/DirectoryInfoSearch.cs | 5 +----
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
index bc1fb8e7a91..e7b43c555f6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
@@ -31,8 +31,6 @@ internal static class Constants
internal const string DefaultContentSearchActionKeyword = "doc:";
- internal const char UnixDirectorySeparator = '/';
-
internal const char DirectorySeparator = '\\';
internal const string WindowsIndexingOptions = "srchadmin.dll";
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
index e3e1c62e698..9fd495f4910 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
@@ -12,9 +12,6 @@ public static class DirectoryInfoSearch
{
internal static IEnumerable TopLevelDirectorySearch(Query query, string search, CancellationToken token)
{
- // if user uses the unix directory separator, we need to convert it to windows directory separator
- search = search.Replace(Constants.UnixDirectorySeparator, Constants.DirectorySeparator);
-
var criteria = ConstructSearchCriteria(search);
if (search.LastIndexOf(Constants.AllFilesFolderSearchWildcard) >
From 5ee110b3b741b310bfebffc4edbf5b371c0f5db4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 7 Feb 2025 16:42:01 +0800
Subject: [PATCH 0207/1335] Fix unix directory seperator issue
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs | 3 ++-
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs | 3 +++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
index e7b43c555f6..4bddfd9b27d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs
@@ -22,7 +22,6 @@ internal static class Constants
internal const string WindowsIndexErrorImagePath = "Images\\index_error2.png";
internal const string GeneralSearchErrorImagePath = "Images\\robot_error.png";
-
internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory";
internal const string ToolTipOpenContainingFolder = "Ctrl + Enter to open the containing folder";
@@ -31,6 +30,8 @@ internal static class Constants
internal const string DefaultContentSearchActionKeyword = "doc:";
+ internal const char UnixDirectorySeparator = '/';
+
internal const char DirectorySeparator = '\\';
internal const string WindowsIndexingOptions = "srchadmin.dll";
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
index 8fd1674765f..12df6c1458e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
@@ -187,6 +187,9 @@ private async Task> PathSearchAsync(Query query, CancellationToken
var needToExpand = EnvironmentVariables.HasEnvironmentVar(querySearch);
var path = needToExpand ? Environment.ExpandEnvironmentVariables(querySearch) : querySearch;
+ // if user uses the unix directory separator, we need to convert it to windows directory separator
+ path = path.Replace(Constants.UnixDirectorySeparator, Constants.DirectorySeparator);
+
// Check that actual location exists, otherwise directory search will throw directory not found exception
if (!FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path).LocationExists())
return results.ToList();
From 1a39af35e20730667960f7af5422ae877de0d679 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 7 Feb 2025 20:23:53 +0800
Subject: [PATCH 0208/1335] Fix main window resize boarder thickness issue
---
Flow.Launcher.Core/Resource/Theme.cs | 35 +++++++++++++++++++++++++++-
Flow.Launcher/MainWindow.xaml | 2 +-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 1d840930663..2c2feeae171 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -11,6 +11,7 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using System.Windows.Shell;
namespace Flow.Launcher.Core.Resource
{
@@ -306,12 +307,15 @@ public void AddDropShadowEffectToCurrentTheme()
var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
if (marginSetter == null)
{
+ var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
marginSetter = new Setter()
{
Property = Border.MarginProperty,
- Value = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin),
+ Value = margin,
};
windowBorderStyle.Setters.Add(marginSetter);
+
+ SetResizeBoarderThickness(margin);
}
else
{
@@ -322,6 +326,8 @@ public void AddDropShadowEffectToCurrentTheme()
baseMargin.Right + ShadowExtraMargin,
baseMargin.Bottom + ShadowExtraMargin);
marginSetter.Value = newMargin;
+
+ SetResizeBoarderThickness(newMargin);
}
windowBorderStyle.Setters.Add(effectSetter);
@@ -352,9 +358,36 @@ public void RemoveDropShadowEffectFromCurrentTheme()
marginSetter.Value = newMargin;
}
+ SetResizeBoarderThickness(null);
+
UpdateResourceDictionary(dict);
}
+ // because adding drop shadow effect will change the margin of the window,
+ // we need to update the window chrome thickness to correct set the resize border
+ private static void SetResizeBoarderThickness(Thickness? effectMargin)
+ {
+ var window = Application.Current.MainWindow;
+ if (WindowChrome.GetWindowChrome(window) is WindowChrome windowChrome)
+ {
+ Thickness thickness;
+ if (effectMargin == null)
+ {
+ thickness = SystemParameters.WindowResizeBorderThickness;
+ }
+ else
+ {
+ thickness = new Thickness(
+ effectMargin.Value.Left + SystemParameters.WindowResizeBorderThickness.Left,
+ effectMargin.Value.Top + SystemParameters.WindowResizeBorderThickness.Top,
+ effectMargin.Value.Right + SystemParameters.WindowResizeBorderThickness.Right,
+ effectMargin.Value.Bottom + SystemParameters.WindowResizeBorderThickness.Bottom);
+ }
+
+ windowChrome.ResizeBorderThickness = thickness;
+ }
+ }
+
public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null);
}
}
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index f5fd729d45b..4cc887c411a 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -37,7 +37,7 @@
mc:Ignorable="d">
-
+
From 0e4cf57e9e29c401a4ff82052b128f5ebe7865b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 8 Feb 2025 11:57:29 +0800
Subject: [PATCH 0209/1335] Revert blank lines
---
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml | 4 ++--
.../Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
index 28196e55f72..676c20a734d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-cn.xaml
@@ -35,13 +35,13 @@
插件{0}更新成功。正在重新启动 Flow Launcher,请稍候...
从未知源安装
您正在从未知源安装此插件,它可能包含潜在风险!{0}{0}请确保您了解来源以及安全性。{0}{0}您想要继续吗?{0}{0}(您可以通过设置关闭此警告)
-
+
成功安装插件{0}。请重新启动 Flow Launcher。
成功卸载插件{0}。请重新启动 Flow Launcher。
成功更新插件{0}。请重新启动 Flow Launcher。
插件 {0} 更新成功。请重新启动 Flow Launcher。
插件 {0} 已被修改。请在进行任何进一步更改之前重新启动Flow。
-
+
插件管理
安装,卸载或更新 Flow Launcher 插件
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
index 96155f440a1..ae37579dc32 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/zh-tw.xaml
@@ -35,13 +35,13 @@
Plugin {0} successfully updated. Restarting Flow, please wait...
Installing from an unknown source
You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
-
+
Plugin {0} successfully installed. Please restart Flow.
Plugin {0} successfully uninstalled. Please restart Flow.
Plugin {0} successfully updated. Please restart Flow.
{0} plugins successfully updated. Please restart Flow.
Plugin {0} has already been modified. Please restart Flow before making any further changes.
-
+
擴充功能管理
Management of installing, uninstalling or updating Flow Launcher plugins
From f0e74a2aa545a74591c62fcd3e67c45faeff4a75 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 8 Feb 2025 19:12:53 +0800
Subject: [PATCH 0210/1335] Fix issue that plugin manager will save settings
for the uninstalled and settings-removed plugins
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 14 ++++++++++----
.../Storage/PluginJsonStorage.cs | 18 ++++++++++++++----
Flow.Launcher/PublicAPIInstance.cs | 17 +++++++++++++++++
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index fc915bcb306..146718b93ac 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -14,7 +14,6 @@
using Flow.Launcher.Plugin.SharedCommands;
using System.Text.Json;
using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure.Storage;
namespace Flow.Launcher.Core.Plugin
{
@@ -548,10 +547,17 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro
var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
var assembly = assemblyLoader.LoadAssemblyAndDependencies();
var assemblyName = assembly.GetName().Name;
- var directoryPath = Path.Combine(DataLocation.DataDirectory(), JsonStorage.DirectoryName, Constant.Plugins, assemblyName);
- if (Directory.Exists(directoryPath))
+
+ // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin
+ // so we need to remove it from the api instance
+ var method = API.GetType().GetMethod("RemovePluginSettings");
+ var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName });
+
+ // if there exists a json storage for current plugin, we need to delete the directory path
+ if (pluginJsonStorage != null)
{
- Directory.Delete(directoryPath, true);
+ var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory");
+ deleteMethod?.Invoke(pluginJsonStorage, null);
}
}
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index abe3f55b5ad..bc3900da802 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -3,14 +3,17 @@
namespace Flow.Launcher.Infrastructure.Storage
{
- public class PluginJsonStorage :JsonStorage where T : new()
+ public class PluginJsonStorage : JsonStorage where T : new()
{
+ // Use assembly name to check which plugin is using this storage
+ public readonly string AssemblyName;
+
public PluginJsonStorage()
{
// C# related, add python related below
var dataType = typeof(T);
- var assemblyName = dataType.Assembly.GetName().Name;
- DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, assemblyName);
+ AssemblyName = dataType.Assembly.GetName().Name;
+ DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, AssemblyName);
Helper.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
@@ -20,6 +23,13 @@ public PluginJsonStorage(T data) : this()
{
Data = data;
}
+
+ public void DeleteDirectory()
+ {
+ if (Directory.Exists(DirectoryPath))
+ {
+ Directory.Delete(DirectoryPath, true);
+ }
+ }
}
}
-
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf244a..12c65018c75 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -189,6 +189,23 @@ public void LogException(string className, string message, Exception e,
private readonly ConcurrentDictionary _pluginJsonStorages = new();
+ public object RemovePluginSettings(string assemblyName)
+ {
+ foreach (var keyValuePair in _pluginJsonStorages)
+ {
+ var key = keyValuePair.Key;
+ var value = keyValuePair.Value;
+ var name = value.GetType().GetField("AssemblyName")?.GetValue(value)?.ToString();
+ if (name == assemblyName)
+ {
+ _pluginJsonStorages.Remove(key, out var pluginJsonStorage);
+ return pluginJsonStorage;
+ }
+ }
+
+ return null;
+ }
+
///
/// Save plugin settings.
///
From 37837e7002307443e7b50ee7db01c0a5878c468d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 8 Feb 2025 22:59:36 +0800
Subject: [PATCH 0211/1335] Fix possible exception when deleting local folder
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 146718b93ac..50150a0694e 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -521,7 +521,15 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
- Directory.Delete(tempFolderPluginPath, true);
+ try
+ {
+ if (Directory.Exists(tempFolderPluginPath))
+ Directory.Delete(tempFolderPluginPath, true);
+ }
+ catch (Exception e)
+ {
+ Log.Exception($"|PluginManager.InstallPlugin|Failed to delete temp folder {tempFolderPluginPath}", e);
+ }
if (checkModified)
{
@@ -557,7 +565,14 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro
if (pluginJsonStorage != null)
{
var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory");
- deleteMethod?.Invoke(pluginJsonStorage, null);
+ try
+ {
+ deleteMethod?.Invoke(pluginJsonStorage, null);
+ }
+ catch (Exception e)
+ {
+ Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {assemblyName}", e);
+ }
}
}
From 6c081e12a4c97e432dc69d5a262f97d3010f7a14 Mon Sep 17 00:00:00 2001
From: Azakidev
Date: Sat, 8 Feb 2025 19:26:36 +0100
Subject: [PATCH 0212/1335] Revert the translation files
---
Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml | 1 -
2 files changed, 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
index f3ef0df0ae3..5ee2c43b4f2 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es-419.xaml
@@ -6,7 +6,6 @@
Press any key to close this window...
No cerrar Símbolo del Sistema tras ejecutar el comando
Siempre ejecutar como administrador
- Ejecutar en la Terminal de Windows
Ejecutar como otro usuario
Shell
Allows to execute system commands from Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
index ee3193b16e4..a3ee35ef8c4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/es.xaml
@@ -6,7 +6,6 @@
Pulsar cualquier tecla para cerrar esta ventana...
No cerrar el símbolo del sistema después de la ejecución del comando
Ejecutar siempre como administrador
- Ejecutar en la Terminal de Windows
Ejecutar como usuario diferente
Terminal
Permite ejecutar comandos del sistema desde Flow Launcher
From 54a0f3d16523ecaa32408277dc30800537094e89 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 9 Feb 2025 10:58:09 +0800
Subject: [PATCH 0213/1335] Add support for delete plugin directory for
non-dotnet plugins
---
.../Plugin/JsonRPCPluginBase.cs | 14 ++++-
Flow.Launcher.Core/Plugin/PluginManager.cs | 60 ++++++++++++-------
2 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
index f6e5e5879a0..ed8f94bcf25 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
@@ -44,8 +44,10 @@ internal abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISetting
private string SettingConfigurationPath =>
Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");
- private string SettingPath => Path.Combine(DataLocation.PluginSettingsDirectory,
- Context.CurrentPluginMetadata.Name, "Settings.json");
+ private string SettingDirectory => Path.Combine(DataLocation.PluginSettingsDirectory,
+ Context.CurrentPluginMetadata.Name);
+
+ private string SettingPath => Path.Combine(SettingDirectory, "Settings.json");
public abstract List LoadContextMenus(Result selectedResult);
@@ -159,5 +161,13 @@ public Control CreateSettingPanel()
{
return Settings.CreateSettingPanel();
}
+
+ public void DeletePluginSettingsDirectory()
+ {
+ if (Directory.Exists(SettingDirectory))
+ {
+ Directory.Delete(SettingDirectory, true);
+ }
+ }
}
}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 50150a0694e..2bce2ba7931 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -544,38 +544,56 @@ internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFro
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}
- if (removePluginFromSettings)
- {
- Settings.Plugins.Remove(plugin.ID);
- AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
- }
-
if (removePluginSettings)
{
- var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
- var assembly = assemblyLoader.LoadAssemblyAndDependencies();
- var assemblyName = assembly.GetName().Name;
+ if (AllowedLanguage.IsDotNet(plugin.Language)) // for the plugin in .NET, we can use assembly loader
+ {
+ var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
+ var assembly = assemblyLoader.LoadAssemblyAndDependencies();
+ var assemblyName = assembly.GetName().Name;
- // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin
- // so we need to remove it from the api instance
- var method = API.GetType().GetMethod("RemovePluginSettings");
- var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName });
+ // if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin
+ // so we need to remove it from the api instance
+ var method = API.GetType().GetMethod("RemovePluginSettings");
+ var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName });
- // if there exists a json storage for current plugin, we need to delete the directory path
- if (pluginJsonStorage != null)
- {
- var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory");
- try
+ // if there exists a json storage for current plugin, we need to delete the directory path
+ if (pluginJsonStorage != null)
{
- deleteMethod?.Invoke(pluginJsonStorage, null);
+ var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory");
+ try
+ {
+ deleteMethod?.Invoke(pluginJsonStorage, null);
+ }
+ catch (Exception e)
+ {
+ Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e);
+ }
}
- catch (Exception e)
+ }
+ else // the plugin with json prc interface
+ {
+ var pluginPair = AllPlugins.FirstOrDefault(p => p.Metadata.ID == plugin.ID);
+ if (pluginPair != null && pluginPair.Plugin is JsonRPCPlugin jsonRpcPlugin)
{
- Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {assemblyName}", e);
+ try
+ {
+ jsonRpcPlugin.DeletePluginSettingsDirectory();
+ }
+ catch (Exception e)
+ {
+ Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e);
+ }
}
}
}
+ if (removePluginFromSettings)
+ {
+ Settings.Plugins.Remove(plugin.ID);
+ AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
+ }
+
// Marked for deletion. Will be deleted on next start up
using var _ = File.CreateText(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt"));
From 864402704d2fb81ccc69820dbae0a0ee671bd02f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 9 Feb 2025 21:54:02 +0800
Subject: [PATCH 0214/1335] Fix an issue that user plugins cannot be updated
when reupdating the plugins manifest
---
Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index 63f21c1d62b..233612f50b8 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.Logger;
using System;
using System.Collections.Generic;
using System.Threading;
@@ -27,7 +27,7 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
{
await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false);
- if (UserPlugins == null || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout)
+ if (UserPlugins == null || UserPlugins.Count == 0 || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout)
{
var results = await mainPluginStore.FetchAsync(token, usePrimaryUrlOnly).ConfigureAwait(false);
From d8f32806324872b8977aab5cdc05230b82ee4bb0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 10 Feb 2025 11:54:09 +0800
Subject: [PATCH 0215/1335] Fix unneccessary plugin result update
---
Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs | 10 +++++++---
.../ViewModels/SettingsPanePluginStoreViewModel.cs | 4 ++--
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index 233612f50b8..54080e15020 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -27,12 +27,16 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
{
await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false);
- if (UserPlugins == null || UserPlugins.Count == 0 || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout)
+ if (UserPlugins == null || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout)
{
var results = await mainPluginStore.FetchAsync(token, usePrimaryUrlOnly).ConfigureAwait(false);
- UserPlugins = results;
- lastFetchedAt = DateTime.Now;
+ // If the results are empty, we shouldn't update the manifest because the results are invalid.
+ if (results.Count != 0)
+ {
+ UserPlugins = results;
+ lastFetchedAt = DateTime.Now;
+ }
}
}
catch (Exception e)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index e069310119b..a6cc3c535ec 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -13,8 +13,8 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
{
public string FilterText { get; set; } = string.Empty;
- public IList ExternalPlugins => PluginsManifest.UserPlugins
- .Select(p => new PluginStoreItemViewModel(p))
+ public IList ExternalPlugins =>
+ PluginsManifest.UserPlugins?.Select(p => new PluginStoreItemViewModel(p))
.OrderByDescending(p => p.Category == PluginStoreItemViewModel.NewRelease)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.RecentlyUpdated)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.None)
From 319f016ced396ee6dd961096140e8b9ca25a1b52 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 10 Feb 2025 12:01:21 +0800
Subject: [PATCH 0216/1335] Remove unnessary list refresh
---
Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs | 6 +++++-
.../ViewModels/SettingsPanePluginStoreViewModel.cs | 6 ++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index 54080e15020..ac8abcdcce8 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -21,7 +21,7 @@ public static class PluginsManifest
public static List UserPlugins { get; private set; }
- public static async Task UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false)
+ public static async Task UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false)
{
try
{
@@ -36,6 +36,8 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
{
UserPlugins = results;
lastFetchedAt = DateTime.Now;
+
+ return true;
}
}
}
@@ -47,6 +49,8 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
{
manifestUpdateLock.Release();
}
+
+ return false;
}
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index a6cc3c535ec..15579a61da0 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -24,8 +24,10 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
[RelayCommand]
private async Task RefreshExternalPluginsAsync()
{
- await PluginsManifest.UpdateManifestAsync();
- OnPropertyChanged(nameof(ExternalPlugins));
+ if (await PluginsManifest.UpdateManifestAsync())
+ {
+ OnPropertyChanged(nameof(ExternalPlugins));
+ }
}
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
From 585b7015b6236ea7fdbe156c39d468a3ca579ed5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 10 Feb 2025 18:20:50 +0800
Subject: [PATCH 0217/1335] Add uninstallation tooltip for logon task settings
item
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 8e8c9abefe6..cd9d0b02adb 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -47,6 +47,7 @@
Store all settings and user data in one folder (Useful when used with removable drives or cloud services).
Start Flow Launcher on system startup
Use logon task instead of startup entry for faster startup experience
+ After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler
Error setting launch on startup
Hide Flow Launcher when focus is lost
Do not show new version notifications
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index e52614e7478..a80e618e8b4 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -36,7 +36,7 @@
OnContent="{DynamicResource enable}" />
-
+
Date: Wed, 12 Feb 2025 10:21:14 +0800
Subject: [PATCH 0218/1335] Improve explorer path parse when path ends with
backslash
---
.../FileExplorerHelper.cs | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index d908b0fde0a..b97c096c363 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -15,7 +15,20 @@ public static string GetActiveExplorerPath()
{
var explorerWindow = GetActiveExplorer();
string locationUrl = explorerWindow?.LocationURL;
- return !string.IsNullOrEmpty(locationUrl) ? new Uri(locationUrl).LocalPath + "\\" : null;
+ return !string.IsNullOrEmpty(locationUrl) ? GetDirectoryPath(new Uri(locationUrl).LocalPath) : null;
+ }
+
+ ///
+ /// Get directory path from a file path
+ ///
+ private static string GetDirectoryPath(string path)
+ {
+ if (!path.EndsWith("\\"))
+ {
+ return path + "\\";
+ }
+
+ return path;
}
///
From ddbbd693e8992c8c8f18d21f71f3dff2a01e02d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 12 Feb 2025 15:06:15 +0800
Subject: [PATCH 0219/1335] Make sure back to query results from context menu
before changing query
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 1 +
Flow.Launcher/CustomShortcutSetting.xaml.cs | 1 +
Flow.Launcher/ResultListBox.xaml.cs | 3 +++
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 1 +
Flow.Launcher/ViewModel/PluginViewModel.cs | 1 +
5 files changed, 7 insertions(+)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8fa..3db49b381e0 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,6 +76,7 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
+ App.API.BackToQueryResults();
App.API.ChangeQuery(tbAction.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb35..10452726dce 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,6 +64,7 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
+ App.API.BackToQueryResults();
App.API.ChangeQuery(tbExpand.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/ResultListBox.xaml.cs b/Flow.Launcher/ResultListBox.xaml.cs
index ac51b195c7b..cc003457fe4 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -149,7 +149,10 @@ private void ResultList_MouseMove(object sender, MouseEventArgs e)
var rawQuery = query;
var effect = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move | DragDropEffects.Copy);
if (effect == DragDropEffects.Move)
+ {
+ App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery, true);
+ }
}
private void ResultListBox_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 38b5bec6561..97c938e78ff 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,6 +64,7 @@ public string Category
private void ShowCommandQuery(string action)
{
var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
+ App.API.BackToQueryResults();
App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
App.API.ShowMainWindow();
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 4ce8bd4706f..e56e8e9e5bc 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,6 +146,7 @@ private void OpenSourceCodeLink()
[RelayCommand]
private void OpenDeletePluginWindow()
{
+ PluginManager.API.BackToQueryResults();
PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
PluginManager.API.ShowMainWindow();
}
From 5313229fb918b19e99eddfd5023c41fed9724e66 Mon Sep 17 00:00:00 2001
From: zggsong
Date: Fri, 14 Feb 2025 13:22:27 +0800
Subject: [PATCH 0220/1335] perf: hide main window from alt tab program
switcher #2356
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 75 ++++++++++++++++++++
Flow.Launcher/MainWindow.xaml | 1 +
Flow.Launcher/MainWindow.xaml.cs | 5 ++
3 files changed, 81 insertions(+)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index caf3f0a7f60..eeb24af2ea9 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -148,4 +148,79 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
+
+ #region Alt Tab
+
+ private const int GWL_EXSTYLE = -20;
+ private const int WS_EX_TOOLWINDOW = 0x00000080;
+ private const int WS_EX_APPWINDOW = 0x00040000;
+
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
+ private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)]
+ private static extern int IntSetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
+
+ [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
+ private static extern void SetLastError(int dwErrorCode);
+
+ private static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
+ {
+ SetLastError(0); // Clear any existing error
+
+ if (IntPtr.Size == 4) return new IntPtr(IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)));
+
+ return IntSetWindowLongPtr(hWnd, nIndex, dwNewLong);
+ }
+
+ private static int IntPtrToInt32(IntPtr intPtr)
+ {
+ return unchecked((int)intPtr.ToInt64());
+ }
+
+ ///
+ /// Hide windows in the Alt+Tab window list
+ ///
+ /// To hide a window
+ public static void HideFromAltTab(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+
+ // Add TOOLWINDOW style, remove APPWINDOW style
+ exStyle = (exStyle | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW;
+
+ SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ }
+
+ ///
+ /// Restore window display in the Alt+Tab window list.
+ ///
+ /// To restore the displayed window
+ public static void ShowInAltTab(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+
+ // Remove the TOOLWINDOW style and add the APPWINDOW style.
+ exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+
+ SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ }
+
+ ///
+ /// To obtain the current overridden style of a window.
+ ///
+ /// To obtain the style dialog window
+ /// current extension style value
+ public static int GetCurrentWindowStyle(Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ return GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ }
+
+ #endregion
}
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index f5fd729d45b..da9e1a5b5ac 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -20,6 +20,7 @@
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
+ SourceInitialized="OnSourceInitialized"
Initialized="OnInitialized"
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 8ca153afc34..41dc68fd924 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -171,6 +171,11 @@ private async void OnClosing(object sender, CancelEventArgs e)
Environment.Exit(0);
}
+ private void OnSourceInitialized(object sender, EventArgs e)
+ {
+ WindowsInteropHelper.HideFromAltTab(this);
+ }
+
private void OnInitialized(object sender, EventArgs e)
{
}
From 829dbaafe7fae537d487f4b67cfe593c01ac5081 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 14 Feb 2025 16:12:15 +0800
Subject: [PATCH 0221/1335] Use CSWin32 for code quality
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 44 ++++++--------------
Flow.Launcher/NativeMethods.txt | 5 ++-
2 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index eeb24af2ea9..4891bf41ad5 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -151,29 +151,11 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
#region Alt Tab
- private const int GWL_EXSTYLE = -20;
- private const int WS_EX_TOOLWINDOW = 0x00000080;
- private const int WS_EX_APPWINDOW = 0x00040000;
-
- [DllImport("user32.dll")]
- private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
- private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
-
- [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)]
- private static extern int IntSetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
- private static extern void SetLastError(int dwErrorCode);
-
- private static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
+ private static IntPtr SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
- SetLastError(0); // Clear any existing error
-
- if (IntPtr.Size == 4) return new IntPtr(IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)));
+ PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
- return IntSetWindowLongPtr(hWnd, nIndex, dwNewLong);
+ return PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
}
private static int IntPtrToInt32(IntPtr intPtr)
@@ -182,44 +164,44 @@ private static int IntPtrToInt32(IntPtr intPtr)
}
///
- /// Hide windows in the Alt+Tab window list
+ /// Hide windows in the Alt+Tab window list
///
/// To hide a window
public static void HideFromAltTab(Window window)
{
var helper = new WindowInteropHelper(window);
- var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Add TOOLWINDOW style, remove APPWINDOW style
- exStyle = (exStyle | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW;
+ var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
- /// Restore window display in the Alt+Tab window list.
+ /// Restore window display in the Alt+Tab window list.
///
/// To restore the displayed window
public static void ShowInAltTab(Window window)
{
var helper = new WindowInteropHelper(window);
- var exStyle = GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
- exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+ var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(helper.Handle, GWL_EXSTYLE, new IntPtr(exStyle));
+ SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
- /// To obtain the current overridden style of a window.
+ /// To obtain the current overridden style of a window.
///
/// To obtain the style dialog window
/// current extension style value
public static int GetCurrentWindowStyle(Window window)
{
var helper = new WindowInteropHelper(window);
- return GetWindowLong(helper.Handle, GWL_EXSTYLE).ToInt32();
+ return PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
}
#endregion
diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt
index 2b147c05f52..88eeeca6e5d 100644
--- a/Flow.Launcher/NativeMethods.txt
+++ b/Flow.Launcher/NativeMethods.txt
@@ -14,4 +14,7 @@ FindWindowEx
WINDOW_STYLE
WM_ENTERSIZEMOVE
-WM_EXITSIZEMOVE
\ No newline at end of file
+WM_EXITSIZEMOVE
+
+SetLastError
+WINDOW_EX_STYLE
\ No newline at end of file
From dc07e762fe0abc147a71ea5e8cd8b156e3ad611e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 14 Feb 2025 16:25:51 +0800
Subject: [PATCH 0222/1335] Add error handling for Get & SetWindowLong failure
& Combine get style function
---
Flow.Launcher/Helper/WindowsInteropHelper.cs | 33 +++++++++++---------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index 4891bf41ad5..3e57948a5f4 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -151,16 +151,17 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
#region Alt Tab
- private static IntPtr SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
+ private static int SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
- return PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
- }
+ var result = PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
+ if (result == 0 && Marshal.GetLastPInvokeError() != 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
- private static int IntPtrToInt32(IntPtr intPtr)
- {
- return unchecked((int)intPtr.ToInt64());
+ return result;
}
///
@@ -169,13 +170,12 @@ private static int IntPtrToInt32(IntPtr intPtr)
/// To hide a window
public static void HideFromAltTab(Window window)
{
- var helper = new WindowInteropHelper(window);
- var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var exStyle = GetCurrentWindowStyle(window);
// Add TOOLWINDOW style, remove APPWINDOW style
var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
+ SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
@@ -184,13 +184,12 @@ public static void HideFromAltTab(Window window)
/// To restore the displayed window
public static void ShowInAltTab(Window window)
{
- var helper = new WindowInteropHelper(window);
- var exStyle = PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var exStyle = GetCurrentWindowStyle(window);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
- SetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
+ SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
///
@@ -198,10 +197,14 @@ public static void ShowInAltTab(Window window)
///
/// To obtain the style dialog window
/// current extension style value
- public static int GetCurrentWindowStyle(Window window)
+ private static int GetCurrentWindowStyle(Window window)
{
- var helper = new WindowInteropHelper(window);
- return PInvoke.GetWindowLong(new(helper.Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ var style = PInvoke.GetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
+ if (style == 0 && Marshal.GetLastPInvokeError() != 0)
+ {
+ throw new Win32Exception(Marshal.GetLastPInvokeError());
+ }
+ return style;
}
#endregion
From cc570274ffb4ad678d4fba75914c4c40e515d53a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 16 Feb 2025 22:47:10 +0800
Subject: [PATCH 0223/1335] Fix get thumbnail exception
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index 2fb8cf3632d..a8d1d78edfc 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,8 +31,6 @@ public class WindowsThumbnailProvider
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
- private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
-
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
@@ -79,7 +77,12 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
- catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
+ catch (COMException)
+ {
+ // Fallback to IconOnly if ThumbnailOnly fails
+ imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
+ }
+ catch (FileNotFoundException)
{
// Fallback to IconOnly if ThumbnailOnly fails
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
From 38b285067d1874ce1952db25a2529502a53cbe4f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 16 Feb 2025 22:50:43 +0800
Subject: [PATCH 0224/1335] Improve documents
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index a8d1d78edfc..bd34bdd2a83 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -79,12 +79,12 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
}
catch (COMException)
{
- // Fallback to IconOnly if ThumbnailOnly fails
+ // Fallback to IconOnly for COM exceptions
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
catch (FileNotFoundException)
{
- // Fallback to IconOnly if ThumbnailOnly fails
+ // Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
}
From d73f3a165b9d3faa8b9cf35f0bd714b286bd5af9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 00:00:18 +0800
Subject: [PATCH 0225/1335] Fix custom hotkey preview issue
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 18 ++++++++++--------
Flow.Launcher/CustomShortcutSetting.xaml.cs | 8 +++++---
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 11 +++++++----
.../Views/SettingsPaneHotkey.xaml.cs | 4 ++--
Flow.Launcher/SettingWindow.xaml.cs | 8 +++++---
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +++--
7 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 81e7600b8fa..db1df0cf27a 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -7,20 +7,23 @@
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
private SettingWindow _settingWidow;
+ private readonly Settings _settings;
+ private readonly MainViewModel _mainViewModel;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
- public Settings Settings { get; }
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
+ public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings, MainViewModel mainVM)
{
_settingWidow = settingWidow;
- Settings = settings;
+ _settings = settings;
+ _mainViewModel = mainVM;
InitializeComponent();
}
@@ -33,13 +36,13 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
if (!update)
{
- Settings.CustomPluginHotkeys ??= new ObservableCollection();
+ _settings.CustomPluginHotkeys ??= new ObservableCollection();
var pluginHotkey = new CustomPluginHotkey
{
Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
};
- Settings.CustomPluginHotkeys.Add(pluginHotkey);
+ _settings.CustomPluginHotkeys.Add(pluginHotkey);
HotKeyMapper.SetCustomQueryHotkey(pluginHotkey);
}
@@ -59,7 +62,7 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
public void UpdateItem(CustomPluginHotkey item)
{
- updateCustomHotkey = Settings.CustomPluginHotkeys.FirstOrDefault(o =>
+ updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
@@ -77,8 +80,7 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- Application.Current.MainWindow.Show();
- Application.Current.MainWindow.Opacity = 1;
+ _mainViewModel.Show(false);
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dec3506eb35..cb2cfcb29ad 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -4,21 +4,24 @@
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
+ private readonly MainViewModel _mainViewModel;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
+ public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm, MainViewModel mainVM)
{
_hotkeyVm = vm;
+ _mainViewModel = mainVM;
InitializeComponent();
}
@@ -65,8 +68,7 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- Application.Current.MainWindow.Show();
- Application.Current.MainWindow.Opacity = 1;
+ _mainViewModel.Show(false);
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index f0295cf244a..2d812603333 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -105,7 +105,7 @@ public void OpenSettingDialog()
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
+ SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM, _mainVM);
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 6d8af9a3f62..5aedd3be7b1 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -8,12 +8,14 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Core;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneHotkeyViewModel : BaseModel
{
public Settings Settings { get; }
+ private MainViewModel MainVM { get; }
public CustomPluginHotkey SelectedCustomPluginHotkey { get; set; }
public CustomShortcutModel SelectedCustomShortcut { get; set; }
@@ -25,9 +27,10 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
$"{KeyConstant.Ctrl}+{KeyConstant.Alt}"
};
- public SettingsPaneHotkeyViewModel(Settings settings)
+ public SettingsPaneHotkeyViewModel(Settings settings, MainViewModel mainVM)
{
Settings = settings;
+ MainVM = mainVM;
}
[RelayCommand]
@@ -71,7 +74,7 @@ private void CustomHotkeyEdit()
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings);
+ var window = new CustomQueryHotkeySetting(null, Settings, MainVM);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -79,7 +82,7 @@ private void CustomHotkeyEdit()
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings).ShowDialog();
+ new CustomQueryHotkeySetting(null, Settings, MainVM).ShowDialog();
}
[RelayCommand]
@@ -126,7 +129,7 @@ private void CustomShortcutEdit()
[RelayCommand]
private void CustomShortcutAdd()
{
- var window = new CustomShortcutSetting(this);
+ var window = new CustomShortcutSetting(this, MainVM);
if (window.ShowDialog() is true)
{
var shortcut = new CustomShortcutModel(window.Key, window.Value);
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 061eabf515d..26939c9f930 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -12,9 +12,9 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
+ if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, MainViewModel: { } mainVM })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
- _viewModel = new SettingsPaneHotkeyViewModel(settings);
+ _viewModel = new SettingsPaneHotkeyViewModel(settings, mainVM);
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index d5b30351617..ae481b65b19 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -20,12 +20,14 @@ public partial class SettingWindow
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
+ private readonly MainViewModel _mainVM;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
+ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel, MainViewModel mainVM)
{
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
+ _mainVM = mainVM;
_api = api;
InitializePosition();
InitializeComponent();
@@ -160,7 +162,7 @@ private double WindowTop()
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
+ var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable, _mainVM);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
@@ -206,5 +208,5 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
- public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
+ public record PaneData(Settings Settings, Updater Updater, IPortable Portable, MainViewModel MainViewModel);
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55bc8d1b3f8..7c2abb07843 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1359,7 +1359,7 @@ public void ToggleFlowLauncher()
}
}
- public void Show()
+ public void Show(bool invokeEvent = true)
{
Application.Current.Dispatcher.Invoke(() =>
{
@@ -1368,7 +1368,8 @@ public void Show()
MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
- VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
+ if (invokeEvent)
+ VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
From 0611340d7159d050bc3a8a9dac7d4df852a568f1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 16:10:07 +0800
Subject: [PATCH 0226/1335] Invoke visibility changed event when previewing
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 5 ++---
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index db1df0cf27a..d33794d611f 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -80,7 +80,7 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- _mainViewModel.Show(false);
+ _mainViewModel.Show();
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index cb2cfcb29ad..4cc30c8f54b 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -68,7 +68,7 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- _mainViewModel.Show(false);
+ _mainViewModel.Show();
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 7c2abb07843..55bc8d1b3f8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1359,7 +1359,7 @@ public void ToggleFlowLauncher()
}
}
- public void Show(bool invokeEvent = true)
+ public void Show()
{
Application.Current.Dispatcher.Invoke(() =>
{
@@ -1368,8 +1368,7 @@ public void Show(bool invokeEvent = true)
MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
- if (invokeEvent)
- VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
+ VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
From 71f1acd9ec148ea82055644b7498e2c956b6f623 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 19:07:01 +0800
Subject: [PATCH 0227/1335] Revert com expcetion & Add thumbnail only check
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index bd34bdd2a83..b98ea50fe48 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,6 +31,8 @@ public class WindowsThumbnailProvider
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
+ private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
+
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
@@ -77,12 +79,12 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
- catch (COMException)
+ catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
{
- // Fallback to IconOnly for COM exceptions
+ // Fallback to IconOnly if ThumbnailOnly fails
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
- catch (FileNotFoundException)
+ catch (FileNotFoundException) when (options == ThumbnailOptions.ThumbnailOnly)
{
// Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
From 827b6edb38f58c5d7f94a19b0c690a1b9c1ce3f4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:12:46 +0800
Subject: [PATCH 0228/1335] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 5bfc68ea613..374caa5111e 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -120,10 +120,9 @@ private List Commands()
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+
if (result == MessageBoxResult.Yes)
- {
Process.Start("shutdown", "/s /t 0");
- }
return true;
}
@@ -140,10 +139,9 @@ private List Commands()
context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+
if (result == MessageBoxResult.Yes)
- {
Process.Start("shutdown", "/r /t 0");
- }
return true;
}
@@ -204,7 +202,11 @@ private List Commands()
SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
- Action = c => PInvoke.SetSuspendState(false, false, false)
+ Action = c =>
+ {
+ PInvoke.SetSuspendState(false, false, false);
+ return true;
+ }
},
new Result
{
@@ -231,10 +233,7 @@ private List Commands()
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
Action = c =>
{
- {
- System.Diagnostics.Process.Start("control.exe", "srchadmin.dll");
- }
-
+ Process.Start("control.exe", "srchadmin.dll");
return true;
}
},
@@ -272,10 +271,7 @@ private List Commands()
CopyText = recycleBinFolder,
Action = c =>
{
- {
- System.Diagnostics.Process.Start("explorer", recycleBinFolder);
- }
-
+ Process.Start("explorer", recycleBinFolder);
return true;
}
},
From ffa303825ef2a1523751f4aedc6a309726796b24 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:22:06 +0800
Subject: [PATCH 0229/1335] Replace process commands with PInvoke
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 374caa5111e..16c1b7f9124 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -122,7 +122,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/s /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -141,7 +141,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/r /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -160,7 +160,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- Process.Start("shutdown", "/r /o /t 0");
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
@@ -179,7 +179,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, 0);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
return true;
}
From e93699b37daaa1bedefd5e442413ea79dbe3204e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 17 Feb 2025 23:37:20 +0800
Subject: [PATCH 0230/1335] Add shutdown reason
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 16c1b7f9124..3199f50a242 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -121,8 +121,12 @@ private List Commands()
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
+ // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure,
+ // software updates, or other predefined reasons.
+ // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -141,7 +145,8 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -160,7 +165,8 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
@@ -179,7 +185,8 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, SHUTDOWN_REASON.SHTDN_REASON_NONE);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
return true;
}
From 18093148429abfaa94db92607984a53d97cde8cf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 00:08:15 +0800
Subject: [PATCH 0231/1335] Enable shutdown privilege before calling PInvoke
for shutdown and start
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 63 +++++++++++++++++--
.../NativeMethods.txt | 7 ++-
2 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 3199f50a242..7d3f66746da 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Runtime.InteropServices;
using System.Windows;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
@@ -9,6 +10,7 @@
using Flow.Launcher.Plugin.SharedCommands;
using Windows.Win32;
using Windows.Win32.Foundation;
+using Windows.Win32.Security;
using Windows.Win32.System.Shutdown;
using Application = System.Windows.Application;
using Control = System.Windows.Controls.Control;
@@ -20,6 +22,8 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
private PluginInitContext context;
private Dictionary KeywordTitleMappings = new Dictionary();
+ private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
+
public Control CreateSettingPanel()
{
var results = Commands();
@@ -100,6 +104,44 @@ public void Init(PluginInitContext context)
};
}
+ private static unsafe bool EnableShutdownPrivilege()
+ {
+ try
+ {
+ if (!PInvoke.OpenProcessToken(Process.GetCurrentProcess().SafeHandle, TOKEN_ACCESS_MASK.TOKEN_ADJUST_PRIVILEGES | TOKEN_ACCESS_MASK.TOKEN_QUERY, out var tokenHandle))
+ {
+ return false;
+ }
+
+ if (!PInvoke.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out var luid))
+ {
+ return false;
+ }
+
+ var privileges = new TOKEN_PRIVILEGES
+ {
+ PrivilegeCount = 1,
+ Privileges = new() { e0 = new LUID_AND_ATTRIBUTES { Luid = luid, Attributes = TOKEN_PRIVILEGES_ATTRIBUTES.SE_PRIVILEGE_ENABLED } }
+ };
+
+ if (!PInvoke.AdjustTokenPrivileges(tokenHandle, false, &privileges, 0, null, null))
+ {
+ return false;
+ }
+
+ if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.NO_ERROR)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
private List Commands()
{
var results = new List();
@@ -125,8 +167,11 @@ private List Commands()
// software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/s /t 0");
return true;
}
@@ -145,8 +190,11 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/r /t 0");
return true;
}
@@ -165,8 +213,11 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ if (EnableShutdownPrivilege())
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
+ SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ else
+ Process.Start("shutdown", "/r /o /t 0");
return true;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
index 8fcb6cae91e..6159c725b2c 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
+++ b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
@@ -3,4 +3,9 @@ LockWorkStation
SHEmptyRecycleBin
S_OK
E_UNEXPECTED
-SetSuspendState
\ No newline at end of file
+SetSuspendState
+OpenProcessToken
+WIN32_ERROR
+LookupPrivilegeValue
+AdjustTokenPrivileges
+TOKEN_PRIVILEGES
\ No newline at end of file
From 648e3f268990c6da85eef377d5d1b5bc97dc438b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:07:18 +0800
Subject: [PATCH 0232/1335] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 7d3f66746da..f6117aab912 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -23,6 +23,9 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
private Dictionary KeywordTitleMappings = new Dictionary();
private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
+ // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
+ // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
+ private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
public Control CreateSettingPanel()
{
@@ -163,13 +166,9 @@ private List Commands()
context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
- // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure,
- // software updates, or other predefined reasons.
- // SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, REASON);
else
Process.Start("shutdown", "/s /t 0");
@@ -191,8 +190,7 @@ private List Commands()
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, REASON);
else
Process.Start("shutdown", "/r /t 0");
@@ -214,8 +212,7 @@ private List Commands()
if (result == MessageBoxResult.Yes)
if (EnableShutdownPrivilege())
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, REASON);
else
Process.Start("shutdown", "/r /o /t 0");
@@ -236,8 +233,7 @@ private List Commands()
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
- PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF,
- SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED);
+ PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, REASON);
return true;
}
From a065179d53aee2146e633e0bf2db2ad3ccd066f6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:12:33 +0800
Subject: [PATCH 0233/1335] Use PInvoke for const
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 3 +--
Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt | 3 ++-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index f6117aab912..3bda99e7125 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -22,7 +22,6 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
private PluginInitContext context;
private Dictionary KeywordTitleMappings = new Dictionary();
- private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
// SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
@@ -116,7 +115,7 @@ private static unsafe bool EnableShutdownPrivilege()
return false;
}
- if (!PInvoke.LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out var luid))
+ if (!PInvoke.LookupPrivilegeValue(null, PInvoke.SE_SHUTDOWN_NAME, out var luid))
{
return false;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
index 6159c725b2c..4567e46a384 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
+++ b/Plugins/Flow.Launcher.Plugin.Sys/NativeMethods.txt
@@ -8,4 +8,5 @@ OpenProcessToken
WIN32_ERROR
LookupPrivilegeValue
AdjustTokenPrivileges
-TOKEN_PRIVILEGES
\ No newline at end of file
+TOKEN_PRIVILEGES
+SE_SHUTDOWN_NAME
\ No newline at end of file
From 3bd4ca4105840ab4a679a21817148ade91660263 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:17:45 +0800
Subject: [PATCH 0234/1335] Replace hiberate with PInvoke
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 3bda99e7125..e81d70c5246 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -269,12 +269,7 @@ private List Commands()
IcoPath = "Images\\hibernate.png",
Action= c =>
{
- var info = ShellCommand.SetProcessStartInfo("shutdown", arguments:"/h");
- info.WindowStyle = ProcessWindowStyle.Hidden;
- info.UseShellExecute = true;
-
- ShellCommand.Execute(info);
-
+ PInvoke.SetSuspendState(true, false, false);
return true;
}
},
From 6b032b33520a272f8d9a239253272aa0fa234f68 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:32:47 +0800
Subject: [PATCH 0235/1335] Revert changes and use api function instead
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 7 ++-----
Flow.Launcher/CustomShortcutSetting.xaml.cs | 7 ++-----
Flow.Launcher/PublicAPIInstance.cs | 2 +-
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 11 ++++-------
.../SettingPages/Views/SettingsPaneHotkey.xaml.cs | 4 ++--
Flow.Launcher/SettingWindow.xaml.cs | 8 +++-----
6 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index d33794d611f..1bd6ee95b83 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -7,7 +7,6 @@
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
@@ -15,15 +14,13 @@ public partial class CustomQueryHotkeySetting : Window
{
private SettingWindow _settingWidow;
private readonly Settings _settings;
- private readonly MainViewModel _mainViewModel;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
- public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings, MainViewModel mainVM)
+ public CustomQueryHotkeySetting(SettingWindow settingWidow, Settings settings)
{
_settingWidow = settingWidow;
_settings = settings;
- _mainViewModel = mainVM;
InitializeComponent();
}
@@ -80,7 +77,7 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbAction.Text);
- _mainViewModel.Show();
+ App.API.ShowMainWindow();
Application.Current.MainWindow.Focus();
}
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 4cc30c8f54b..05d4d3d8396 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -4,24 +4,21 @@
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
- private readonly MainViewModel _mainViewModel;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm, MainViewModel mainVM)
+ public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
{
_hotkeyVm = vm;
- _mainViewModel = mainVM;
InitializeComponent();
}
@@ -68,7 +65,7 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
App.API.ChangeQuery(tbExpand.Text);
- _mainViewModel.Show();
+ App.API.ShowMainWindow();
Application.Current.MainWindow.Focus();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 2d812603333..f0295cf244a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -105,7 +105,7 @@ public void OpenSettingDialog()
{
Application.Current.Dispatcher.Invoke(() =>
{
- SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM, _mainVM);
+ SettingWindow sw = SingletonWindowOpener.Open(this, _settingsVM);
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index 5aedd3be7b1..6d8af9a3f62 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -8,14 +8,12 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Core;
-using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneHotkeyViewModel : BaseModel
{
public Settings Settings { get; }
- private MainViewModel MainVM { get; }
public CustomPluginHotkey SelectedCustomPluginHotkey { get; set; }
public CustomShortcutModel SelectedCustomShortcut { get; set; }
@@ -27,10 +25,9 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel
$"{KeyConstant.Ctrl}+{KeyConstant.Alt}"
};
- public SettingsPaneHotkeyViewModel(Settings settings, MainViewModel mainVM)
+ public SettingsPaneHotkeyViewModel(Settings settings)
{
Settings = settings;
- MainVM = mainVM;
}
[RelayCommand]
@@ -74,7 +71,7 @@ private void CustomHotkeyEdit()
return;
}
- var window = new CustomQueryHotkeySetting(null, Settings, MainVM);
+ var window = new CustomQueryHotkeySetting(null, Settings);
window.UpdateItem(item);
window.ShowDialog();
}
@@ -82,7 +79,7 @@ private void CustomHotkeyEdit()
[RelayCommand]
private void CustomHotkeyAdd()
{
- new CustomQueryHotkeySetting(null, Settings, MainVM).ShowDialog();
+ new CustomQueryHotkeySetting(null, Settings).ShowDialog();
}
[RelayCommand]
@@ -129,7 +126,7 @@ private void CustomShortcutEdit()
[RelayCommand]
private void CustomShortcutAdd()
{
- var window = new CustomShortcutSetting(this, MainVM);
+ var window = new CustomShortcutSetting(this);
if (window.ShowDialog() is true)
{
var shortcut = new CustomShortcutModel(window.Key, window.Value);
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 26939c9f930..061eabf515d 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -12,9 +12,9 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, MainViewModel: { } mainVM })
+ if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
- _viewModel = new SettingsPaneHotkeyViewModel(settings, mainVM);
+ _viewModel = new SettingsPaneHotkeyViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index ae481b65b19..d5b30351617 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -20,14 +20,12 @@ public partial class SettingWindow
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
- private readonly MainViewModel _mainVM;
- public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel, MainViewModel mainVM)
+ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
{
_settings = viewModel.Settings;
DataContext = viewModel;
_viewModel = viewModel;
- _mainVM = mainVM;
_api = api;
InitializePosition();
InitializeComponent();
@@ -162,7 +160,7 @@ private double WindowTop()
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable, _mainVM);
+ var paneData = new PaneData(_settings, _viewModel.Updater, _viewModel.Portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
@@ -208,5 +206,5 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
- public record PaneData(Settings Settings, Updater Updater, IPortable Portable, MainViewModel MainViewModel);
+ public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
}
From 9284c559f68cc8418af9cea727c8954b01153e6c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 18 Feb 2025 11:41:26 +0800
Subject: [PATCH 0236/1335] Use api function to hide window
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 8 ++++----
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 67148984624..c1ed904b337 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -534,7 +534,7 @@ internal List InstallFromWeb(string url)
return false;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(plugin);
return ShouldHideWindow;
@@ -572,7 +572,7 @@ internal List InstallFromLocalPath(string localPath)
return false;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(plugin);
return ShouldHideWindow;
@@ -626,7 +626,7 @@ internal async ValueTask> RequestInstallOrUpdateAsync(string search
return ShouldHideWindow;
}
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
_ = InstallOrUpdateAsync(x); // No need to wait
return ShouldHideWindow;
},
@@ -703,7 +703,7 @@ internal List RequestUninstall(string search)
Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"),
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
- Application.Current.MainWindow.Hide();
+ Context.API.HideMainWindow();
Uninstall(x.Metadata);
if (Settings.AutoRestartAfterChanging)
{
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 5bfc68ea613..edf9c82e47a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -333,7 +333,7 @@ private List Commands()
Action = c =>
{
// Hide the window first then show msg after done because sometimes the reload could take a while, so not to make user think it's frozen.
- Application.Current.MainWindow.Hide();
+ context.API.HideMainWindow();
_ = context.API.ReloadAllPluginData().ContinueWith(_ =>
context.API.ShowMsg(
@@ -352,7 +352,7 @@ private List Commands()
IcoPath = "Images\\checkupdate.png",
Action = c =>
{
- Application.Current.MainWindow.Hide();
+ context.API.HideMainWindow();
context.API.CheckForNewUpdate();
return true;
}
From 3dade8bbfcf5c556e5b08caab23b38aabc55f9b1 Mon Sep 17 00:00:00 2001
From: Kevin Zhang <45326534+taooceros@users.noreply.github.com>
Date: Wed, 19 Feb 2025 00:03:46 -0800
Subject: [PATCH 0237/1335] Don't restart the jsonrpc process when reloading
data.
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index f95266c7fe0..19d7edb310a 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -135,10 +135,9 @@ private void SetupJsonRPC()
public virtual async Task ReloadDataAsync()
{
- SetupJsonRPC();
try
{
- await RPC.InvokeAsync("reload", Context);
+ await RPC.InvokeAsync("reload_data", Context);
}
catch (RemoteMethodNotFoundException e)
{
From 2843236214981585fb2316ea25e675cf56bc21f3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 19 Feb 2025 17:09:09 +0800
Subject: [PATCH 0238/1335] Improve documents & Improve code quality
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 1 +
Flow.Launcher/CustomShortcutSetting.xaml.cs | 1 +
Flow.Launcher/ResultListBox.xaml.cs | 1 +
Flow.Launcher/ViewModel/MainViewModel.cs | 2 ++
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs | 1 +
Flow.Launcher/ViewModel/PluginViewModel.cs | 1 +
Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 5 +++--
8 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 3db49b381e0..fd829afe2df 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,6 +76,7 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(tbAction.Text);
Application.Current.MainWindow.Show();
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 10452726dce..d05a5c15cf5 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,6 +64,7 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(tbExpand.Text);
Application.Current.MainWindow.Show();
diff --git a/Flow.Launcher/ResultListBox.xaml.cs b/Flow.Launcher/ResultListBox.xaml.cs
index cc003457fe4..83469253633 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -150,6 +150,7 @@ private void ResultList_MouseMove(object sender, MouseEventArgs e)
var effect = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move | DragDropEffects.Copy);
if (effect == DragDropEffects.Move)
{
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery, true);
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5c3251bfc7e..4af93daf9c2 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1266,6 +1266,7 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.Remove(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ReQuery();
return false;
@@ -1284,6 +1285,7 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.AddOrUpdate(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ReQuery();
return false;
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 97c938e78ff..7675ecb1678 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,6 +64,7 @@ public string Category
private void ShowCommandQuery(string action)
{
var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
+ // if user happens to open context menu, we need to return back to query results before changing query
App.API.BackToQueryResults();
App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
App.API.ShowMainWindow();
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index e56e8e9e5bc..c8601c43138 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,6 +146,7 @@ private void OpenSourceCodeLink()
[RelayCommand]
private void OpenDeletePluginWindow()
{
+ // if user happens to open context menu, we need to return back to query results before changing query
PluginManager.API.BackToQueryResults();
PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
PluginManager.API.ShowMainWindow();
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
index 17e9fe2bca7..482e821dc4c 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
@@ -59,7 +59,6 @@ public List LoadContextMenus(Result selectedResult)
var link = pluginManifestInfo.UrlSourceCode.StartsWith("https://github.com")
? Regex.Replace(pluginManifestInfo.UrlSourceCode, @"\/tree\/\w+$", "") + "/issues"
: pluginManifestInfo.UrlSourceCode;
-
Context.API.OpenUrl(link);
return true;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 7f1f4bd4da3..86808cfbc2a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -5,7 +5,6 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows;
using WindowsInput;
using WindowsInput.Native;
using Flow.Launcher.Infrastructure.Hotkey;
@@ -379,9 +378,11 @@ bool API_GlobalKeyboardEvent(int keyevent, int vkcode, SpecialKeyState state)
private void OnWinRPressed()
{
// show the main window and set focus to the query box
- Task.Run(() =>
+ _ = Task.Run(() =>
{
context.API.ShowMainWindow();
+ // if user happens to open context menu, we need to return back to query results before changing query
+ context.API.BackToQueryResults();
context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
From 9880c362fd7196b2fc7792f82b533fc80a945eed Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 19 Feb 2025 23:31:26 +0800
Subject: [PATCH 0239/1335] Remove useless settings control & project reference
---
.../Flow.Launcher.Plugin.Url.csproj | 1 -
Plugins/Flow.Launcher.Plugin.Url/Main.cs | 10 +---------
.../SettingsControl.xaml | 17 -----------------
.../SettingsControl.xaml.cs | 18 ------------------
4 files changed, 1 insertion(+), 45 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
index 3db0cd0cb61..6d338733e31 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
@@ -42,7 +42,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Main.cs b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
index 80425a8ff94..03516636d43 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
-using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Url
{
- public class Main : ISettingProvider,IPlugin, IPluginI18n
+ public class Main : IPlugin, IPluginI18n
{
//based on https://gist.github.com/dperini/729294
private const string urlPattern = "^" +
@@ -43,7 +42,6 @@ public class Main : ISettingProvider,IPlugin, IPluginI18n
Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
private PluginInitContext context;
private Settings _settings;
-
public List Query(Query query)
{
@@ -82,12 +80,6 @@ public List Query(Query query)
return new List(0);
}
-
- public Control CreateSettingPanel()
- {
- return new SettingsControl(context.API,_settings);
- }
-
public bool IsURL(string raw)
{
raw = raw.ToLower();
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
deleted file mode 100644
index 8ff7b5ab53b..00000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
deleted file mode 100644
index f68d1bb2db0..00000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Windows.Controls;
-
-namespace Flow.Launcher.Plugin.Url
-{
- public partial class SettingsControl : UserControl
- {
- private Settings _settings;
- private IPublicAPI _flowlauncherAPI;
-
- public SettingsControl(IPublicAPI flowlauncherAPI,Settings settings)
- {
- InitializeComponent();
- _settings = settings;
- _flowlauncherAPI = flowlauncherAPI;
-
- }
- }
-}
From 6e84326f57c45cc44e6ab6a756244d277c9ef884 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 19 Feb 2025 23:43:17 +0800
Subject: [PATCH 0240/1335] Reassign margins
---
.../Resources/Controls/InstalledPluginDisplayKeyword.xaml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index ff2f14c4b2d..a88b1a7316f 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -18,9 +18,9 @@
CornerRadius="0"
Style="{DynamicResource SettingGroupBox}"
Visibility="{Binding ActionKeywordsVisibility}">
-
+
@@ -34,7 +34,6 @@
Date: Thu, 20 Feb 2025 14:59:16 +0800
Subject: [PATCH 0241/1335] Add support for hiding dulplicated windows apps
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 28 +++++++++++++++++++
.../Flow.Launcher.Plugin.Program/Settings.cs | 1 +
2 files changed, 29 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 6ba7047f23e..00fb1d344c6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -72,6 +72,8 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
+ private const string WindowsAppPath = "c:\\program files\\windowsapps";
+
static Main()
{
}
@@ -90,11 +92,20 @@ public async Task> QueryAsync(Query query, CancellationToken token)
{
try
{
+ // Collect all UWP Windows app directories
+ var uwpsDirectories = _settings.HideDulplicatedWindowsApp ? _uwps
+ .Where(uwp => !string.IsNullOrEmpty(uwp.Location)) // Exclude invalid paths
+ .Where(uwp => uwp.Location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase)) // Keep system apps
+ .Select(uwp => uwp.Location.TrimEnd('\\')) // Remove trailing slash
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToArray() : null;
+
return _win32s.Cast()
.Concat(_uwps)
.AsParallel()
.WithCancellation(token)
.Where(HideUninstallersFilter)
+ .Where(p => HideDulplicatedWindowsAppFilter(p, uwpsDirectories))
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, Context.API))
.Where(r => r?.Score > 0)
@@ -152,6 +163,23 @@ private bool HideUninstallersFilter(IProgram program)
return true;
}
+ private static bool HideDulplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
+ {
+ if (uwpsDirectories == null || uwpsDirectories.Length == 0) return true;
+ if (program is UWPApp) return true;
+
+ var location = program.Location.TrimEnd('\\'); // Ensure trailing slash
+ if (string.IsNullOrEmpty(location))
+ return true; // Keep if location is invalid
+
+ if (!location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase))
+ return true; // Keep if not a Windows app
+
+ // Check if the any Win32 executable directory contains UWP Windows app location matches
+ return !uwpsDirectories.Any(uwpDirectory =>
+ location.StartsWith(uwpDirectory, StringComparison.OrdinalIgnoreCase));
+ }
+
public async Task InitAsync(PluginInitContext context)
{
Context = context;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index fb24f64d7d6..664277e02d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,6 +121,7 @@ private void RemoveRedundantSuffixes()
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
+ public bool HideDulplicatedWindowsApp { get; set; } = true;
internal const char SuffixSeparator = ';';
}
From b4bffb1cf54bb0a050ea2277ffa1893b1df05c39 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 17:17:53 +0800
Subject: [PATCH 0242/1335] Use null as default value for record key
---
Flow.Launcher.Plugin/Result.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index bb005752eba..9b16cc1cbf0 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -266,8 +266,9 @@ public ValueTask ExecuteAsync(ActionContext context)
/// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records.
/// This can be useful when your plugin will change the Title or SubTitle of the result dynamically.
/// If the plugin does not specific this, FL just uses Title and SubTitle to identify this result.
+ /// Note: Because old data does not have this key, we should use null as the default value for consistency.
///
- public string RecordKey { get; set; } = string.Empty;
+ public string RecordKey { get; set; } = null;
///
/// Info of the preview section of a
From 4f41be67ac5135158d22d6f99859cda1a2f84f57 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:02:59 +0800
Subject: [PATCH 0243/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1dadc..8f2d78d760b 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -281,7 +281,7 @@ public static async Task> QueryForPluginAsync(PluginPair pair, Quer
return results;
}
- public static void UpdatePluginMetadata(List results, PluginMetadata metadata, Query query)
+ public static void UpdatePluginMetadata(IReadOnlyList results, PluginMetadata metadata, Query query)
{
foreach (var r in results)
{
From 2ffe170407b0ca012b267051569e29de43c77c46 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:06:15 +0800
Subject: [PATCH 0244/1335] Use deep clone for result updating
---
Flow.Launcher/ViewModel/MainViewModel.cs | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5c3251bfc7e..b498f4001be 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -231,8 +231,8 @@ private void RegisterResultsUpdatedEvent()
var token = e.Token == default ? _updateToken : e.Token;
- // make a copy of results to avoid plugin change the result when updating view model
- var resultsCopy = e.Results.ToList();
+ // make a clone to avoid possible issue that plugin will also change the list and items when updating view model
+ var resultsCopy = DeepCloneResults(e.Results, token);
PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query);
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
@@ -414,6 +414,22 @@ private async Task OpenResultAsync(string index)
}
}
+ private static IReadOnlyList DeepCloneResults(IReadOnlyList results, CancellationToken token = default)
+ {
+ var resultsCopy = new List();
+ foreach (var result in results.ToList())
+ {
+ if (token.IsCancellationRequested)
+ {
+ break;
+ }
+
+ var resultCopy = result.Clone();
+ resultsCopy.Add(resultCopy);
+ }
+ return resultsCopy;
+ }
+
#endregion
#region BasicCommands
@@ -1469,9 +1485,9 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
if (_topMostRecord.IsTopMost(result))
{
- result.Score = Result.MaxScore;
+ result.Score = 100000; //Result.MaxScore;
}
- else if (result.Score != Result.MaxScore)
+ else
{
var priorityScore = metaResults.Metadata.Priority * 150;
result.Score += result.AddSelectedCount ?
From 9850e9d3eb6af9c78003738e23dd819336446ba4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 18:17:29 +0800
Subject: [PATCH 0245/1335] Fix issue that plugin will cannot cache records
---
Flow.Launcher/ViewModel/MainViewModel.cs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index b498f4001be..e030d8eaef0 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1196,9 +1196,18 @@ async Task QueryTask(PluginPair plugin, bool reSelect = true)
currentCancellationToken.ThrowIfCancellationRequested();
- results ??= _emptyResult;
+ IReadOnlyList resultsCopy;
+ if (results == null)
+ {
+ resultsCopy = _emptyResult;
+ }
+ else
+ {
+ // make a copy of results to avoid possible issue that FL changes some properties of the records, like score, etc.
+ resultsCopy = DeepCloneResults(results);
+ }
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query,
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
currentCancellationToken, reSelect)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
From 7ccfbcae7f2cef218357abd1aa842592e88a4b9f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 20 Feb 2025 23:15:12 +0800
Subject: [PATCH 0246/1335] Add hide dulplicated windows apps into settings
panel
---
.../Languages/en.xaml | 2 +
.../Flow.Launcher.Plugin.Program/Settings.cs | 2 +-
.../Views/ProgramSetting.xaml | 53 ++++++++++---------
.../Views/ProgramSetting.xaml.cs | 10 ++++
4 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 7ed711e172e..640b082e769 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -36,6 +36,8 @@
Hides programs with common uninstaller names, such as unins000.exe
Search in Program Description
Flow will search program's description
+ Hide dulplicated apps
+ Hide dulplicated Win32 programs that are already in the UWP list
Suffixes
Max Depth
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index 664277e02d7..53cb1755d45 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,7 +121,7 @@ private void RemoveRedundantSuffixes()
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
- public bool HideDulplicatedWindowsApp { get; set; } = true;
+ public bool HideDulplicatedWindowsApp { get; set; } = false;
internal const char SuffixSeparator = ';';
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index e5ca6967e73..0482099ad70 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -8,7 +8,7 @@
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
-
+
@@ -18,40 +18,40 @@
+ ToolTip="{DynamicResource flowlauncher_plugin_program_index_uwp_tooltip}"
+ Visibility="{Binding ShowUWPCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}" />
@@ -67,21 +67,20 @@
BorderBrush="{DynamicResource Color03B}"
BorderThickness="1" />
@@ -91,11 +90,15 @@
IsChecked="{Binding HideUninstallers}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers_tooltip}" />
+
@@ -142,7 +145,7 @@
Minimum="0" />
@@ -151,7 +154,7 @@
+ Margin="0 0 20 0">
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 36b5acc8acb..0c62655944e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -57,6 +57,16 @@ public bool HideUninstallers
}
}
+ public bool HideDulplicatedWindowsApp
+ {
+ get => _settings.HideDulplicatedWindowsApp;
+ set
+ {
+ Main.ResetCache();
+ _settings.HideDulplicatedWindowsApp = value;
+ }
+ }
+
public bool EnableRegistrySource
{
get => _settings.EnableRegistrySource;
From 097633e9e0a4d504cda69caf86bdc40ca71706a8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 09:29:43 +0800
Subject: [PATCH 0247/1335] Fix typos
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 4 ++--
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 6 +++---
Plugins/Flow.Launcher.Plugin.Program/Settings.cs | 2 +-
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml | 6 +++---
.../Views/ProgramSetting.xaml.cs | 6 +++---
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 640b082e769..790c9d2c621 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -36,8 +36,8 @@
Hides programs with common uninstaller names, such as unins000.exe
Search in Program Description
Flow will search program's description
- Hide dulplicated apps
- Hide dulplicated Win32 programs that are already in the UWP list
+ Hide duplicated apps
+ Hide duplicated Win32 programs that are already in the UWP list
Suffixes
Max Depth
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 00fb1d344c6..dd2a874fa5c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -93,7 +93,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
try
{
// Collect all UWP Windows app directories
- var uwpsDirectories = _settings.HideDulplicatedWindowsApp ? _uwps
+ var uwpsDirectories = _settings.HideDuplicatedWindowsApp ? _uwps
.Where(uwp => !string.IsNullOrEmpty(uwp.Location)) // Exclude invalid paths
.Where(uwp => uwp.Location.StartsWith(WindowsAppPath, StringComparison.OrdinalIgnoreCase)) // Keep system apps
.Select(uwp => uwp.Location.TrimEnd('\\')) // Remove trailing slash
@@ -105,7 +105,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
.AsParallel()
.WithCancellation(token)
.Where(HideUninstallersFilter)
- .Where(p => HideDulplicatedWindowsAppFilter(p, uwpsDirectories))
+ .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, Context.API))
.Where(r => r?.Score > 0)
@@ -163,7 +163,7 @@ private bool HideUninstallersFilter(IProgram program)
return true;
}
- private static bool HideDulplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
+ private static bool HideDuplicatedWindowsAppFilter(IProgram program, string[] uwpsDirectories)
{
if (uwpsDirectories == null || uwpsDirectories.Length == 0) return true;
if (program is UWPApp) return true;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
index 53cb1755d45..b2aad63b325 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Settings.cs
@@ -121,7 +121,7 @@ private void RemoveRedundantSuffixes()
public bool EnableRegistrySource { get; set; } = true;
public bool EnablePathSource { get; set; } = false;
public bool EnableUWP { get; set; } = true;
- public bool HideDulplicatedWindowsApp { get; set; } = false;
+ public bool HideDuplicatedWindowsApp { get; set; } = false;
internal const char SuffixSeparator = ';';
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index 0482099ad70..973ac9f60af 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -96,9 +96,9 @@
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_description_tooltip}" />
+ Content="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp}"
+ IsChecked="{Binding HideDuplicatedWindowsApp}"
+ ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip}" />
_settings.HideDulplicatedWindowsApp;
+ get => _settings.HideDuplicatedWindowsApp;
set
{
Main.ResetCache();
- _settings.HideDulplicatedWindowsApp = value;
+ _settings.HideDuplicatedWindowsApp = value;
}
}
From 79bcf8be18beb61d7072bd092ef1e2c67fb0ef7f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 09:32:58 +0800
Subject: [PATCH 0248/1335] Use system environment for Windows app path
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index dd2a874fa5c..65af0b56c35 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -72,7 +72,7 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
private const string ExeUninstallerSuffix = ".exe";
private const string InkUninstallerSuffix = ".lnk";
- private const string WindowsAppPath = "c:\\program files\\windowsapps";
+ private static readonly string WindowsAppPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsApps");
static Main()
{
From 6e4d9a5e61c577ae684c29f6513e22b2bb339a1a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 11:10:16 +0800
Subject: [PATCH 0249/1335] Remove useless blank lines
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 1 -
Flow.Launcher.Plugin/Query.cs | 1 -
Flow.Launcher/ViewModel/MainViewModel.cs | 2 --
3 files changed, 4 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 5c4eaa1dadc..b1f397ea2d1 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -229,7 +229,6 @@ public static ICollection ValidPluginsForQuery(Query query)
if (!NonGlobalPlugins.ContainsKey(query.ActionKeyword))
return GlobalPlugins;
-
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List
{
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index e182491c2f0..ab3c8cfeb09 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -43,7 +43,6 @@ public Query() { }
///
public const string ActionKeywordSeparator = ";";
-
///
/// Wildcard action keyword. Plugins using this value will be queried on every search.
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5c3251bfc7e..07547136792 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1118,7 +1118,6 @@ private async void QueryResults(bool isReQuery = false, bool reSelect = true)
SearchIconVisibility = Visibility.Visible;
}
-
if (query.ActionKeyword == Plugin.Query.GlobalPluginWildcardSign)
{
// Wait 45 millisecond for query change in global query
@@ -1145,7 +1144,6 @@ private async void QueryResults(bool isReQuery = false, bool reSelect = true)
true => Task.CompletedTask
}).ToArray();
-
try
{
// Check the code, WhenAll will translate all type of IEnumerable or Collection to Array, so make an array at first
From 5fc8ed1824d55b48e9b2db056688afd490f99e0f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 11:11:44 +0800
Subject: [PATCH 0250/1335] Remove useless settings control & project reference
---
.../Flow.Launcher.Plugin.Url.csproj | 1 -
Plugins/Flow.Launcher.Plugin.Url/Main.cs | 10 +---------
.../SettingsControl.xaml | 17 -----------------
.../SettingsControl.xaml.cs | 18 ------------------
4 files changed, 1 insertion(+), 45 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
delete mode 100644 Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
index 3db0cd0cb61..6d338733e31 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj
@@ -42,7 +42,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/Main.cs b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
index 80425a8ff94..03516636d43 100644
--- a/Plugins/Flow.Launcher.Plugin.Url/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Url/Main.cs
@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
-using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Url
{
- public class Main : ISettingProvider,IPlugin, IPluginI18n
+ public class Main : IPlugin, IPluginI18n
{
//based on https://gist.github.com/dperini/729294
private const string urlPattern = "^" +
@@ -43,7 +42,6 @@ public class Main : ISettingProvider,IPlugin, IPluginI18n
Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
private PluginInitContext context;
private Settings _settings;
-
public List Query(Query query)
{
@@ -82,12 +80,6 @@ public List Query(Query query)
return new List(0);
}
-
- public Control CreateSettingPanel()
- {
- return new SettingsControl(context.API,_settings);
- }
-
public bool IsURL(string raw)
{
raw = raw.ToLower();
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
deleted file mode 100644
index 8ff7b5ab53b..00000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
deleted file mode 100644
index f68d1bb2db0..00000000000
--- a/Plugins/Flow.Launcher.Plugin.Url/SettingsControl.xaml.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Windows.Controls;
-
-namespace Flow.Launcher.Plugin.Url
-{
- public partial class SettingsControl : UserControl
- {
- private Settings _settings;
- private IPublicAPI _flowlauncherAPI;
-
- public SettingsControl(IPublicAPI flowlauncherAPI,Settings settings)
- {
- InitializeComponent();
- _settings = settings;
- _flowlauncherAPI = flowlauncherAPI;
-
- }
- }
-}
From c472239ea9e2e8a814ed85330d4a66308a9bf956 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 11:20:00 +0800
Subject: [PATCH 0251/1335] Fix unneccessary black lines when settings control
is null
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 50eb30998d3..2a4b22bf395 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -112,7 +112,7 @@ public void Save()
public Control CreateSettingPanel()
{
if (Settings == null || Settings.Count == 0)
- return new();
+ return null;
var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 4ce8bd4706f..a46b98d64b6 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -90,7 +90,7 @@ public bool IsExpanded
private Control _bottomPart2;
public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginDisplayBottomData() : null;
- public bool HasSettingControl => PluginPair.Plugin is ISettingProvider;
+ public bool HasSettingControl => PluginPair.Plugin is ISettingProvider settingProvider && settingProvider.CreateSettingPanel() != null;
public Control SettingControl
=> IsExpanded
? _settingControl
From 8f6bed45e4f9305110f2ffc9aac47f827c7d84b4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 12:23:31 +0800
Subject: [PATCH 0252/1335] Remove useless * keywords
---
Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
index 4eb6bb83bda..89eaa657db4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
@@ -2,10 +2,7 @@
"ID": "572be03c74c642baae319fc283e561a8",
"ActionKeywords": [
"*",
- "doc:",
- "*",
- "*",
- "*"
+ "doc:"
],
"Name": "Explorer",
"Description": "Find and manage files and folders via Windows Search or Everything",
From e1f1b97b7e158d015f122e02f393e6d72ae08697 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 12:27:38 +0800
Subject: [PATCH 0253/1335] Support allow modify action keywords & WebSearch
does not let user change its keywords
---
Flow.Launcher.Plugin/PluginMetadata.cs | 2 ++
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/PluginMetadata.cs b/Flow.Launcher.Plugin/PluginMetadata.cs
index b4e06913e32..14a7202038b 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -34,6 +34,8 @@ internal set
public List ActionKeywords { get; set; }
+ public bool AllowModifyActionKeywords { get; set; } = true;
+
public string IcoPath { get; set;}
public override string ToString()
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index a46b98d64b6..4b628f96e6c 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -100,7 +100,7 @@ public Control SettingControl
: null;
private ImageSource _image = ImageLoader.MissingImage;
- public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed;
+ public Visibility ActionKeywordsVisibility => PluginPair.Metadata.AllowModifyActionKeywords ? Visibility.Visible : Visibility.Collapsed;
public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index 6b6792ad399..1fc9967fcdb 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -23,6 +23,7 @@
"yahoo",
"bd"
],
+ "AllowModifyActionKeywords": false,
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
From abfeee1423a011229ec6cd9dd7e85dddc2a90ac6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 12:59:56 +0800
Subject: [PATCH 0254/1335] Support multiple action keywords
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 29 +++++++++++++++++-----
Flow.Launcher.Plugin/Query.cs | 4 +--
Flow.Launcher/ActionKeywords.xaml.cs | 15 +++++++----
Flow.Launcher/ViewModel/PluginViewModel.cs | 7 +++---
4 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index b1f397ea2d1..8c62c2f02ac 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -340,7 +340,12 @@ public static List GetContextMenusForPlugin(Result result)
return results;
}
- public static bool ActionKeywordRegistered(string actionKeyword)
+ public static bool ActionKeywordRegistered(IReadOnlyList actionKeywords)
+ {
+ return actionKeywords.Any(ActionKeywordRegistered);
+ }
+
+ private static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
// hence the actionKeyword != Query.GlobalPluginWildcardSign logic
@@ -385,19 +390,31 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
NonGlobalPlugins.Remove(oldActionkeyword);
-
plugin.Metadata.ActionKeywords.Remove(oldActionkeyword);
}
- public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword)
+ public static void ReplaceActionKeyword(string id, IReadOnlyList oldActionKeyword, IReadOnlyList newActionKeyword)
{
- if (oldActionKeyword != newActionKeyword)
+ if (CheckActionKeywordChanged(oldActionKeyword, newActionKeyword))
{
- AddActionKeyword(id, newActionKeyword);
- RemoveActionKeyword(id, oldActionKeyword);
+ foreach (var actionKeyword in newActionKeyword)
+ {
+ AddActionKeyword(id, actionKeyword);
+ }
+ foreach (var actionKeyword in oldActionKeyword)
+ {
+ RemoveActionKeyword(id, actionKeyword);
+ }
}
}
+ private static bool CheckActionKeywordChanged(IReadOnlyList oldActionKeyword, IReadOnlyList newActionKeyword)
+ {
+ if (oldActionKeyword.Count != newActionKeyword.Count)
+ return true;
+ return oldActionKeyword.Where((t, i) => t != newActionKeyword[i]).Any();
+ }
+
private static string GetContainingFolderPathAfterUnzip(string unzippedParentFolderPath)
{
var unzippedFolderCount = Directory.GetDirectories(unzippedParentFolderPath).Length;
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index ab3c8cfeb09..15b2dd171f5 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -39,9 +39,9 @@ public Query() { }
public const string TermSeparator = " ";
///
- /// User can set multiple action keywords seperated by ';'
+ /// User can set multiple action keywords seperated by whitespace
///
- public const string ActionKeywordSeparator = ";";
+ public const string ActionKeywordSeparator = TermSeparator;
///
/// Wildcard action keyword. Plugins using this value will be queried on every search.
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index ba47a4ded22..4a6bd10a85f 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -3,6 +3,7 @@
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
+using System.Linq;
namespace Flow.Launcher
{
@@ -32,13 +33,17 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
- var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
- var newActionKeyword = tbAction.Text.Trim();
- newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
+ var oldActionKeywords = plugin.Metadata.ActionKeywords;
+
+ var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator).ToList();
+ newActionKeywords.RemoveAll(string.IsNullOrEmpty);
+ newActionKeywords = newActionKeywords.Distinct().ToList();
+
+ newActionKeywords = newActionKeywords.Count > 0 ? newActionKeywords : new() { Query.GlobalPluginWildcardSign };
- if (!PluginViewModel.IsActionKeywordRegistered(newActionKeyword))
+ if (!PluginViewModel.IsActionKeywordRegistered(newActionKeywords))
{
- pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
+ pluginViewModel.ChangeActionKeyword(newActionKeywords, oldActionKeywords);
Close();
}
else
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 4b628f96e6c..748490c4727 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -8,6 +8,7 @@
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Resources.Controls;
+using System.Collections.Generic;
namespace Flow.Launcher.ViewModel
{
@@ -109,9 +110,9 @@ public Control SettingControl
public int Priority => PluginPair.Metadata.Priority;
public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; }
- public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword)
+ public void ChangeActionKeyword(IReadOnlyList newActionKeywords, IReadOnlyList oldActionKeywords)
{
- PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeyword, newActionKeyword);
+ PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeywords, newActionKeywords);
OnPropertyChanged(nameof(ActionKeywordsText));
}
@@ -150,7 +151,7 @@ private void OpenDeletePluginWindow()
PluginManager.API.ShowMainWindow();
}
- public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
+ public static bool IsActionKeywordRegistered(IReadOnlyList newActionKeywords) => PluginManager.ActionKeywordRegistered(newActionKeywords);
[RelayCommand]
private void SetActionKeywords()
From d9ba38b3221174996201f8df2b1a93a9000e00e5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:09:19 +0800
Subject: [PATCH 0255/1335] Fix issue that plugin cannot update ActionKeyword
after changing its action keywords
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 8c62c2f02ac..e4ecf0f40e4 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -405,6 +405,17 @@ public static void ReplaceActionKeyword(string id, IReadOnlyList oldActi
{
RemoveActionKeyword(id, actionKeyword);
}
+
+ // Update action keyword in plugin metadata
+ var plugin = GetPluginForId(id);
+ if (newActionKeyword.Count > 0)
+ {
+ plugin.Metadata.ActionKeyword = newActionKeyword[0];
+ }
+ else
+ {
+ plugin.Metadata.ActionKeyword = string.Empty;
+ }
}
}
From f999b97de1e2a57dd11a7b8fe1ab39194936b865 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:25:31 +0800
Subject: [PATCH 0256/1335] Fix build issue
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 46 +++++++++++++++----
.../SearchSourceSetting.xaml.cs | 4 +-
2 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index e4ecf0f40e4..c8f78767c4d 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -342,10 +342,17 @@ public static List GetContextMenusForPlugin(Result result)
public static bool ActionKeywordRegistered(IReadOnlyList actionKeywords)
{
- return actionKeywords.Any(ActionKeywordRegistered);
+ foreach (var actionKeyword in actionKeywords)
+ {
+ if (ActionKeywordRegistered(actionKeyword))
+ {
+ return true;
+ }
+ }
+ return false;
}
- private static bool ActionKeywordRegistered(string actionKeyword)
+ public static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
// hence the actionKeyword != Query.GlobalPluginWildcardSign logic
@@ -369,6 +376,7 @@ public static void AddActionKeyword(string id, string newActionKeyword)
NonGlobalPlugins[newActionKeyword] = plugin;
}
+ // Update action keywords in plugin metadata
plugin.Metadata.ActionKeywords.Add(newActionKeyword);
}
@@ -390,27 +398,28 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
NonGlobalPlugins.Remove(oldActionkeyword);
+ // Update action keywords in plugin metadata
plugin.Metadata.ActionKeywords.Remove(oldActionkeyword);
}
- public static void ReplaceActionKeyword(string id, IReadOnlyList oldActionKeyword, IReadOnlyList newActionKeyword)
+ public static void ReplaceActionKeyword(string id, IReadOnlyList oldActionKeywords, IReadOnlyList newActionKeywords)
{
- if (CheckActionKeywordChanged(oldActionKeyword, newActionKeyword))
+ if (CheckActionKeywordChanged(oldActionKeywords, newActionKeywords))
{
- foreach (var actionKeyword in newActionKeyword)
+ foreach (var actionKeyword in newActionKeywords)
{
AddActionKeyword(id, actionKeyword);
}
- foreach (var actionKeyword in oldActionKeyword)
+ foreach (var actionKeyword in oldActionKeywords)
{
RemoveActionKeyword(id, actionKeyword);
}
// Update action keyword in plugin metadata
var plugin = GetPluginForId(id);
- if (newActionKeyword.Count > 0)
+ if (newActionKeywords.Count > 0)
{
- plugin.Metadata.ActionKeyword = newActionKeyword[0];
+ plugin.Metadata.ActionKeyword = newActionKeywords[0];
}
else
{
@@ -426,6 +435,27 @@ private static bool CheckActionKeywordChanged(IReadOnlyList oldActionKey
return oldActionKeyword.Where((t, i) => t != newActionKeyword[i]).Any();
}
+ public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword)
+ {
+ if (oldActionKeyword != newActionKeyword)
+ {
+ AddActionKeyword(id, newActionKeyword);
+ RemoveActionKeyword(id, oldActionKeyword);
+
+ // Update action keyword in plugin metadata
+ var plugin = GetPluginForId(id);
+ var newActionKeywords = plugin.Metadata.ActionKeywords;
+ if (newActionKeywords.Count > 0)
+ {
+ plugin.Metadata.ActionKeyword = newActionKeywords[0];
+ }
+ else
+ {
+ plugin.Metadata.ActionKeyword = string.Empty;
+ }
+ }
+ }
+
private static string GetContainingFolderPathAfterUnzip(string unzippedParentFolderPath)
{
var unzippedFolderCount = Directory.GetDirectories(unzippedParentFolderPath).Length;
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index a3e5630c22e..f79176f991b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -80,7 +80,7 @@ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
private void AddSearchSource()
{
var keyword = _searchSource.ActionKeyword;
- if (!PluginManager.ActionKeywordRegistered(keyword))
+ if (!_context.API.ActionKeywordAssigned(keyword))
{
var id = _context.CurrentPluginMetadata.ID;
PluginManager.AddActionKeyword(id, keyword);
@@ -100,7 +100,7 @@ private void EditSearchSource()
{
var newKeyword = _searchSource.ActionKeyword;
var oldKeyword = _oldSearchSource.ActionKeyword;
- if (!PluginManager.ActionKeywordRegistered(newKeyword) || oldKeyword == newKeyword)
+ if (!_context.API.ActionKeywordAssigned(newKeyword) || oldKeyword == newKeyword)
{
var id = _context.CurrentPluginMetadata.ID;
PluginManager.ReplaceActionKeyword(id, oldKeyword, newKeyword);
From 37ad5aa09bb1336ee3db27a913e6d2a51cc314c4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:31:46 +0800
Subject: [PATCH 0257/1335] Fix issue that ActionKeywordRegistered will not
exclude old action key
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 12 +++++++++---
Flow.Launcher/ActionKeywords.xaml.cs | 3 ++-
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 --
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index c8f78767c4d..d0e6fcab02f 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -340,11 +340,11 @@ public static List GetContextMenusForPlugin(Result result)
return results;
}
- public static bool ActionKeywordRegistered(IReadOnlyList actionKeywords)
+ public static bool ActionKeywordRegistered(IReadOnlyList newActionKeywords, IReadOnlyList oldActionKeywords)
{
- foreach (var actionKeyword in actionKeywords)
+ foreach (var actionKeyword in newActionKeywords)
{
- if (ActionKeywordRegistered(actionKeyword))
+ if (ActionKeywordRegistered(actionKeyword, oldActionKeywords))
{
return true;
}
@@ -352,6 +352,12 @@ public static bool ActionKeywordRegistered(IReadOnlyList actionKeywords)
return false;
}
+ private static bool ActionKeywordRegistered(string actionKeyword, IReadOnlyList oldActionKeywords)
+ {
+ if (oldActionKeywords.Contains(actionKeyword)) return false;
+ return ActionKeywordRegistered(actionKeyword);
+ }
+
public static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index 4a6bd10a85f..af6dcfe90d7 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -4,6 +4,7 @@
using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
using System.Linq;
+using Flow.Launcher.Core.Plugin;
namespace Flow.Launcher
{
@@ -41,7 +42,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
newActionKeywords = newActionKeywords.Count > 0 ? newActionKeywords : new() { Query.GlobalPluginWildcardSign };
- if (!PluginViewModel.IsActionKeywordRegistered(newActionKeywords))
+ if (!PluginManager.ActionKeywordRegistered(newActionKeywords, oldActionKeywords))
{
pluginViewModel.ChangeActionKeyword(newActionKeywords, oldActionKeywords);
Close();
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 748490c4727..63263c768a8 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -151,8 +151,6 @@ private void OpenDeletePluginWindow()
PluginManager.API.ShowMainWindow();
}
- public static bool IsActionKeywordRegistered(IReadOnlyList newActionKeywords) => PluginManager.ActionKeywordRegistered(newActionKeywords);
-
[RelayCommand]
private void SetActionKeywords()
{
From 300d64d66165e4cc302dcf58ce8fe908323135be Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:43:53 +0800
Subject: [PATCH 0258/1335] Remove action keyword first
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index d0e6fcab02f..18519c85d14 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -412,13 +412,15 @@ public static void ReplaceActionKeyword(string id, IReadOnlyList oldActi
{
if (CheckActionKeywordChanged(oldActionKeywords, newActionKeywords))
{
- foreach (var actionKeyword in newActionKeywords)
+ // Fix collection modified while iterating exception
+ var oldActionKeywordsClone = oldActionKeywords.ToList();
+ foreach (var actionKeyword in oldActionKeywordsClone)
{
- AddActionKeyword(id, actionKeyword);
+ RemoveActionKeyword(id, actionKeyword);
}
- foreach (var actionKeyword in oldActionKeywords)
+ foreach (var actionKeyword in newActionKeywords)
{
- RemoveActionKeyword(id, actionKeyword);
+ AddActionKeyword(id, actionKeyword);
}
// Update action keyword in plugin metadata
@@ -445,8 +447,8 @@ public static void ReplaceActionKeyword(string id, string oldActionKeyword, stri
{
if (oldActionKeyword != newActionKeyword)
{
- AddActionKeyword(id, newActionKeyword);
RemoveActionKeyword(id, oldActionKeyword);
+ AddActionKeyword(id, newActionKeyword);
// Update action keyword in plugin metadata
var plugin = GetPluginForId(id);
From cab3eb78fd827283e7511511fba1bce1e8bf58cd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:45:02 +0800
Subject: [PATCH 0259/1335] Update string resource
---
Flow.Launcher/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f52..282d0fb4723 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -335,7 +335,7 @@
This new Action Keyword is already assigned to another plugin, please choose a different one
Success
Completed successfully
- Enter the action keyword you like to use to start the plugin. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Custom Query Hotkey
From 414684ce43b78452a544dcb12cef8abd1af9e5ee Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 13:50:44 +0800
Subject: [PATCH 0260/1335] Replace action keyword function with api
---
.../Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs | 2 +-
Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index f79176f991b..fa53e5f5a05 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -83,7 +83,7 @@ private void AddSearchSource()
if (!_context.API.ActionKeywordAssigned(keyword))
{
var id = _context.CurrentPluginMetadata.ID;
- PluginManager.AddActionKeyword(id, keyword);
+ _context.API.AddActionKeyword(id, keyword);
_searchSources.Add(_searchSource);
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
index 739bc9d6be6..5efe46a9d43 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs
@@ -40,7 +40,7 @@ private void OnDeleteSearchSearchClick(object sender, RoutedEventArgs e)
if (result == MessageBoxResult.Yes)
{
var id = _context.CurrentPluginMetadata.ID;
- PluginManager.RemoveActionKeyword(id, selected.ActionKeyword);
+ _context.API.RemoveActionKeyword(id, selected.ActionKeyword);
_settings.SearchSources.Remove(selected);
}
}
From 54a49d68f3a7f6ea6488b47d0e5ed83edab67d44 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Fri, 21 Feb 2025 20:55:32 +1100
Subject: [PATCH 0261/1335] Enable the use of Win hotkey to trigger flow
(#3262)
---
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/Helper/HotKeyMapper.cs | 39 +++++++++++++++++++++++
Flow.Launcher/HotkeyControl.xaml.cs | 11 ++++++-
Flow.Launcher/HotkeyControlDialog.xaml.cs | 29 +++++++++++++++--
4 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 16228258f5f..2f26017a674 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -83,6 +83,7 @@
+
all
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 8b30b8be1f5..64434b49c08 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -6,6 +6,8 @@
using Flow.Launcher.Core.Resource;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
+using ChefKeys;
+using System.Globalization;
namespace Flow.Launcher.Helper;
@@ -29,15 +31,40 @@ internal static void OnToggleHotkey(object sender, HotkeyEventArgs args)
_mainViewModel.ToggleFlowLauncher();
}
+ internal static void OnToggleHotkeyWithChefKeys()
+ {
+ if (!_mainViewModel.ShouldIgnoreHotkeys())
+ _mainViewModel.ToggleFlowLauncher();
+ }
+
private static void SetHotkey(string hotkeyStr, EventHandler action)
{
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ SetWithChefKeys(hotkeyStr);
+ return;
+ }
+
var hotkey = new HotkeyModel(hotkeyStr);
SetHotkey(hotkey, action);
}
+ private static void SetWithChefKeys(string hotkeyStr)
+ {
+ ChefKeysManager.RegisterHotkey(hotkeyStr, hotkeyStr, OnToggleHotkeyWithChefKeys);
+ ChefKeysManager.Start();
+ }
+
internal static void SetHotkey(HotkeyModel hotkey, EventHandler action)
{
string hotkeyStr = hotkey.ToString();
+
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ SetWithChefKeys(hotkeyStr);
+ return;
+ }
+
try
{
HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action);
@@ -52,12 +79,24 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
internal static void RemoveHotkey(string hotkeyStr)
{
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ RemoveWithChefKeys(hotkeyStr);
+ return;
+ }
+
if (!string.IsNullOrEmpty(hotkeyStr))
{
HotkeyManager.Current.Remove(hotkeyStr);
}
}
+ private static void RemoveWithChefKeys(string hotkeyStr)
+ {
+ ChefKeysManager.UnregisterHotkey(hotkeyStr);
+ ChefKeysManager.Stop();
+ }
+
internal static void LoadCustomPluginHotkey()
{
if (_settings.CustomPluginHotkeys == null)
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index a42bde7c9cd..e1dfc1108ef 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -154,7 +154,16 @@ private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
{
if (triggerValidate)
{
- bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
+ bool hotkeyAvailable = false;
+ // TODO: This is a temporary way to enforce changing only the open flow hotkey to Win, and will be removed by PR #3157
+ if (keyModel.ToString() == "LWin" || keyModel.ToString() == "RWin")
+ {
+ hotkeyAvailable = true;
+ }
+ else
+ {
+ hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
+ }
if (!hotkeyAvailable)
{
diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs
index a7b99f6704b..a4d21a7827b 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Windows;
using System.Windows.Input;
+using ChefKeys;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
@@ -33,6 +34,8 @@ public enum EResultType
public string ResultValue { get; private set; } = string.Empty;
public static string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
+ private static bool isOpenFlowHotkey;
+
public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings hotkeySettings, string windowTitle = "")
{
WindowTitle = windowTitle switch
@@ -46,6 +49,14 @@ public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings
SetKeysToDisplay(CurrentHotkey);
InitializeComponent();
+
+ // TODO: This is a temporary way to enforce changing only the open flow hotkey to Win, and will be removed by PR #3157
+ isOpenFlowHotkey = _hotkeySettings.RegisteredHotkeys
+ .Any(x => x.DescriptionResourceKey == "flowlauncherHotkey"
+ && x.Hotkey.ToString() == hotkey);
+
+ ChefKeysManager.StartMenuEnableBlocking = true;
+ ChefKeysManager.Start();
}
private void Reset(object sender, RoutedEventArgs routedEventArgs)
@@ -61,12 +72,18 @@ private void Delete(object sender, RoutedEventArgs routedEventArgs)
private void Cancel(object sender, RoutedEventArgs routedEventArgs)
{
+ ChefKeysManager.StartMenuEnableBlocking = false;
+ ChefKeysManager.Stop();
+
ResultType = EResultType.Cancel;
Hide();
}
private void Save(object sender, RoutedEventArgs routedEventArgs)
{
+ ChefKeysManager.StartMenuEnableBlocking = false;
+ ChefKeysManager.Stop();
+
if (KeysToDisplay.Count == 1 && KeysToDisplay[0] == EmptyHotkey)
{
ResultType = EResultType.Delete;
@@ -85,6 +102,9 @@ private void OnPreviewKeyDown(object sender, KeyEventArgs e)
//when alt is pressed, the real key should be e.SystemKey
Key key = e.Key == Key.System ? e.SystemKey : e.Key;
+ if (ChefKeysManager.StartMenuBlocked && key.ToString() == ChefKeysManager.StartMenuSimulatedKey)
+ return;
+
SpecialKeyState specialKeyState = GlobalHotkey.CheckModifiers();
var hotkeyModel = new HotkeyModel(
@@ -168,8 +188,13 @@ private void SetKeysToDisplay(HotkeyModel? hotkey)
}
}
- private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
- hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
+ private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture)
+ {
+ if (isOpenFlowHotkey && (hotkey.ToString() == "LWin" || hotkey.ToString() == "RWin"))
+ return true;
+
+ return hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
+ }
private void Overwrite(object sender, RoutedEventArgs e)
{
From 41733615fd75cd35bf3933a90e92b93ae217e09a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 21 Feb 2025 20:45:42 +0800
Subject: [PATCH 0262/1335] Improve code quality
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 5 +----
Flow.Launcher/CustomShortcutSetting.xaml | 5 +----
Flow.Launcher/PriorityChangeWindow.xaml | 5 +----
Flow.Launcher/SelectBrowserWindow.xaml | 5 +----
Flow.Launcher/SelectFileManagerWindow.xaml | 5 +----
Flow.Launcher/WelcomeWindow.xaml | 5 +----
6 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 068afda15b4..70ebb404b91 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -32,14 +32,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Date: Fri, 21 Feb 2025 21:17:00 +0800
Subject: [PATCH 0263/1335] Improve report window with dark theme &
localization support
---
Flow.Launcher/Languages/en.xaml | 6 ++
Flow.Launcher/ReportWindow.xaml | 101 +++++++++++++++++++++++------
Flow.Launcher/ReportWindow.xaml.cs | 64 +++++++++++++-----
3 files changed, 134 insertions(+), 37 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f52..493528a8980 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -383,6 +383,12 @@
Report sent successfully
Failed to send report
Flow Launcher got an error
+ Please open new issue in
+ 1. Upload log file: {0}
+ 2. Copy below exception message
+ Date: {0}
+ Exception:
+ Length
Please wait...
diff --git a/Flow.Launcher/ReportWindow.xaml b/Flow.Launcher/ReportWindow.xaml
index 50dace0753d..5e799e2a339 100644
--- a/Flow.Launcher/ReportWindow.xaml
+++ b/Flow.Launcher/ReportWindow.xaml
@@ -1,23 +1,82 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ReportWindow.xaml.cs b/Flow.Launcher/ReportWindow.xaml.cs
index a535dfb3eb0..12ffe3ffc5e 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -6,10 +6,10 @@
using System.Linq;
using System.Windows;
using System.Windows.Documents;
-using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
+using Flow.Launcher.Infrastructure.Exception;
namespace Flow.Launcher
{
@@ -43,32 +43,36 @@ private void SetException(Exception exception)
var log = directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
var websiteUrl = exception switch
- {
- FlowPluginException pluginException =>GetIssuesUrl(pluginException.Metadata.Website),
- _ => Constant.IssuesUrl
- };
-
+ {
+ FlowPluginException pluginException =>GetIssuesUrl(pluginException.Metadata.Website),
+ _ => Constant.IssuesUrl
+ };
- var paragraph = Hyperlink("Please open new issue in: ", websiteUrl);
- paragraph.Inlines.Add($"1. upload log file: {log.FullName}\n");
- paragraph.Inlines.Add($"2. copy below exception message");
+ var paragraph = Hyperlink(App.API.GetTranslation("reportWindow_please_open_issue"), websiteUrl);
+ paragraph.Inlines.Add(string.Format(App.API.GetTranslation("reportWindow_upload_log"), log.FullName));
+ paragraph.Inlines.Add("\n");
+ paragraph.Inlines.Add(App.API.GetTranslation("reportWindow_copy_below"));
ErrorTextbox.Document.Blocks.Add(paragraph);
StringBuilder content = new StringBuilder();
- content.AppendLine(ErrorReporting.RuntimeInfo());
- content.AppendLine(ErrorReporting.DependenciesInfo());
- content.AppendLine($"Date: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}");
- content.AppendLine("Exception:");
+ content.AppendLine(RuntimeInfo());
+ content.AppendLine();
+ content.AppendLine(DependenciesInfo());
+ content.AppendLine();
+ content.AppendLine(string.Format(App.API.GetTranslation("reportWindow_date"), DateTime.Now.ToString(CultureInfo.InvariantCulture)));
+ content.AppendLine(App.API.GetTranslation("reportWindow_exception"));
content.AppendLine(exception.ToString());
paragraph = new Paragraph();
paragraph.Inlines.Add(content.ToString());
ErrorTextbox.Document.Blocks.Add(paragraph);
}
- private Paragraph Hyperlink(string textBeforeUrl, string url)
+ private static Paragraph Hyperlink(string textBeforeUrl, string url)
{
- var paragraph = new Paragraph();
- paragraph.Margin = new Thickness(0);
+ var paragraph = new Paragraph
+ {
+ Margin = new Thickness(0)
+ };
var link = new Hyperlink
{
@@ -79,10 +83,38 @@ private Paragraph Hyperlink(string textBeforeUrl, string url)
link.Click += (s, e) => SearchWeb.OpenInBrowserTab(url);
paragraph.Inlines.Add(textBeforeUrl);
+ paragraph.Inlines.Add(" ");
paragraph.Inlines.Add(link);
paragraph.Inlines.Add("\n");
return paragraph;
}
+
+ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private static string RuntimeInfo()
+ {
+ var info =
+ $"""
+ Flow Launcher {App.API.GetTranslation("reportWindow_version")}: {Constant.Version}
+ OS {App.API.GetTranslation("reportWindow_version")}: {ExceptionFormatter.GetWindowsFullVersionFromRegistry()}
+ IntPtr {App.API.GetTranslation("reportWindow_length")}: {IntPtr.Size}
+ x64: {Environment.Is64BitOperatingSystem}
+ """;
+ return info;
+ }
+
+ private static string DependenciesInfo()
+ {
+ var info =
+ $"""
+ {App.API.GetTranslation("pythonFilePath")}: {Constant.PythonPath}
+ {App.API.GetTranslation("nodeFilePath")}: {Constant.NodePath}
+ """;
+ return info;
+ }
}
}
From 2b9716aa379c3878bd5ef42bb355e4af6f9a5577 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 13:16:09 +0800
Subject: [PATCH 0264/1335] Fix message box window topmost issue when disabling
hide FL when loss focus
---
Flow.Launcher.Core/MessageBoxEx.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/MessageBoxEx.xaml b/Flow.Launcher.Core/MessageBoxEx.xaml
index fff107a68a4..28cc0228331 100644
--- a/Flow.Launcher.Core/MessageBoxEx.xaml
+++ b/Flow.Launcher.Core/MessageBoxEx.xaml
@@ -12,6 +12,7 @@
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
+ Topmost="True"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
From dd73e4b4b3962f46ada29f5a273fa5a21c17cc65 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 15:51:36 +0800
Subject: [PATCH 0265/1335] Fix topmost score issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index e030d8eaef0..9bab4a3a16a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1494,7 +1494,7 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
if (_topMostRecord.IsTopMost(result))
{
- result.Score = 100000; //Result.MaxScore;
+ result.Score = Result.MaxScore;
}
else
{
From b46922885c2480b1b6dac5185c658e9e7c8c8aea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 15:59:38 +0800
Subject: [PATCH 0266/1335] Add max value check
---
Flow.Launcher/ViewModel/MainViewModel.cs | 25 +++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 9bab4a3a16a..a9809a49a79 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1499,9 +1499,28 @@ public void UpdateResultView(ICollection resultsForUpdates)
else
{
var priorityScore = metaResults.Metadata.Priority * 150;
- result.Score += result.AddSelectedCount ?
- _userSelectedRecord.GetSelectedCount(result) + priorityScore :
- priorityScore;
+ if (result.AddSelectedCount)
+ {
+ if ((long)result.Score + _userSelectedRecord.GetSelectedCount(result) + priorityScore > Result.MaxScore)
+ {
+ result.Score = Result.MaxScore;
+ }
+ else
+ {
+ result.Score += _userSelectedRecord.GetSelectedCount(result) + priorityScore;
+ }
+ }
+ else
+ {
+ if ((long)result.Score + priorityScore > Result.MaxScore)
+ {
+ result.Score = Result.MaxScore;
+ }
+ else
+ {
+ result.Score += priorityScore;
+ }
+ }
}
}
}
From 156668e1098287328c691ed2fcb76dcc62490d10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 16:12:41 +0800
Subject: [PATCH 0267/1335] Add minimize & background option for progress box
ex
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/ProgressBoxEx.xaml | 31 ++++++++++++++++++++++++++++-
Flow.Launcher/ProgressBoxEx.xaml.cs | 11 +++++++---
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f52..d36fd2e90a3 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -367,6 +367,7 @@
OK
Yes
No
+ Background
Version
diff --git a/Flow.Launcher/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
index 3102cfb7255..32b0f64b4f0 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml
+++ b/Flow.Launcher/ProgressBoxEx.xaml
@@ -35,9 +35,32 @@
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 7c55d62c0e5..755fc4a1fa1 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -95,14 +95,19 @@ private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
ForceClose();
}
- private void Button_Click(object sender, RoutedEventArgs e)
+ private void Button_Cancel(object sender, RoutedEventArgs e)
{
ForceClose();
}
- private void Button_Cancel(object sender, RoutedEventArgs e)
+ private void Button_Minimize(object sender, RoutedEventArgs e)
{
- ForceClose();
+ WindowState = WindowState.Minimized;
+ }
+
+ private void Button_Background(object sender, RoutedEventArgs e)
+ {
+ Hide();
}
private void ForceClose()
From 70396bccd912bad6fe5444e0b42e456448405b60 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 22 Feb 2025 20:18:00 +1100
Subject: [PATCH 0268/1335] add exception handling for register & unregister
hotkey (#3263)
---
Flow.Launcher/Helper/HotKeyMapper.cs | 67 +++++++++++++++++++---------
Flow.Launcher/Languages/en.xaml | 1 +
2 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 64434b49c08..9e0777a9800 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -8,6 +8,7 @@
using Flow.Launcher.Core;
using ChefKeys;
using System.Globalization;
+using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Helper;
@@ -39,38 +40,49 @@ internal static void OnToggleHotkeyWithChefKeys()
private static void SetHotkey(string hotkeyStr, EventHandler action)
{
- if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
- {
- SetWithChefKeys(hotkeyStr);
- return;
- }
-
var hotkey = new HotkeyModel(hotkeyStr);
SetHotkey(hotkey, action);
}
private static void SetWithChefKeys(string hotkeyStr)
{
- ChefKeysManager.RegisterHotkey(hotkeyStr, hotkeyStr, OnToggleHotkeyWithChefKeys);
- ChefKeysManager.Start();
+ try
+ {
+ ChefKeysManager.RegisterHotkey(hotkeyStr, hotkeyStr, OnToggleHotkeyWithChefKeys);
+ ChefKeysManager.Start();
+ }
+ catch (Exception e)
+ {
+ Log.Error(
+ string.Format("|HotkeyMapper.SetWithChefKeys|Error registering hotkey: {0} \nStackTrace:{1}",
+ e.Message,
+ e.StackTrace));
+ string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
+ string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
+ MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ }
}
internal static void SetHotkey(HotkeyModel hotkey, EventHandler action)
{
string hotkeyStr = hotkey.ToString();
-
- if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
- {
- SetWithChefKeys(hotkeyStr);
- return;
- }
-
try
{
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ SetWithChefKeys(hotkeyStr);
+ return;
+ }
+
HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action);
}
- catch (Exception)
+ catch (Exception e)
{
+ Log.Error(
+ string.Format("|HotkeyMapper.SetHotkey|Error registering hotkey {2}: {0} \nStackTrace:{1}",
+ e.Message,
+ e.StackTrace,
+ hotkeyStr));
string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
MessageBoxEx.Show(errorMsg, errorMsgTitle);
@@ -79,15 +91,26 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
internal static void RemoveHotkey(string hotkeyStr)
{
- if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ try
{
- RemoveWithChefKeys(hotkeyStr);
- return;
- }
+ if (hotkeyStr == "LWin" || hotkeyStr == "RWin")
+ {
+ RemoveWithChefKeys(hotkeyStr);
+ return;
+ }
- if (!string.IsNullOrEmpty(hotkeyStr))
+ if (!string.IsNullOrEmpty(hotkeyStr))
+ HotkeyManager.Current.Remove(hotkeyStr);
+ }
+ catch (Exception e)
{
- HotkeyManager.Current.Remove(hotkeyStr);
+ Log.Error(
+ string.Format("|HotkeyMapper.RemoveHotkey|Error removing hotkey: {0} \nStackTrace:{1}",
+ e.Message,
+ e.StackTrace));
+ string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("unregisterHotkeyFailed"), hotkeyStr);
+ string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
+ MessageBoxEx.Show(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 4c465d61f52..00523d03de3 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -15,6 +15,7 @@
Failed to register hotkey "{0}". The hotkey may be in use by another program. Change to a different hotkey, or exit another program.
+ Failed to unregister hotkey "{0}". Please try again or see log for details
Flow Launcher
Could not start {0}
Invalid Flow Launcher plugin file format
From abc13b7d670011d39f24ed719354dea746a9cddb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 19:04:56 +0800
Subject: [PATCH 0269/1335] Adjust minimize button style
---
Flow.Launcher/ProgressBoxEx.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
index 32b0f64b4f0..d201e50bdb5 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml
+++ b/Flow.Launcher/ProgressBoxEx.xaml
@@ -41,7 +41,7 @@
Grid.Column="1"
Click="Button_Minimize"
RenderOptions.EdgeMode="Aliased"
- Style="{DynamicResource TitleBarCloseButtonStyle}">
+ Style="{DynamicResource TitleBarButtonStyle}">
Date: Sat, 22 Feb 2025 19:14:12 +0800
Subject: [PATCH 0270/1335] Set progress box topmost
---
Flow.Launcher/ProgressBoxEx.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/ProgressBoxEx.xaml b/Flow.Launcher/ProgressBoxEx.xaml
index d201e50bdb5..c17f8b61d4e 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml
+++ b/Flow.Launcher/ProgressBoxEx.xaml
@@ -12,6 +12,7 @@
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
+ Topmost="True"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
From aee585620a62a5054428d0a338e84a25af58bb9f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 19:32:08 +0800
Subject: [PATCH 0271/1335] Remove back to query result and call this function
in ChangeQuery & ReQuery
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 5 -----
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 11 +++--------
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 --
Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 --
Flow.Launcher/PublicAPIInstance.cs | 2 --
Flow.Launcher/ResultListBox.xaml.cs | 4 ----
Flow.Launcher/ViewModel/MainViewModel.cs | 14 +++++---------
.../ViewModel/PluginStoreItemViewModel.cs | 2 --
Flow.Launcher/ViewModel/PluginViewModel.cs | 3 ---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 1 -
11 files changed, 8 insertions(+), 39 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index e0a0434a203..a82cae5d254 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -170,10 +170,5 @@ public void OpenAppUri(string appUri)
{
_api.OpenAppUri(appUri);
}
-
- public void BackToQueryResults()
- {
- _api.BackToQueryResults();
- }
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 8376fd07ba7..1a8da381b48 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -17,7 +17,8 @@ namespace Flow.Launcher.Plugin
public interface IPublicAPI
{
///
- /// Change Flow.Launcher query
+ /// Change Flow.Launcher query.
+ /// When current results is from context menu or history, we will back to query results before changing query.
///
/// query text
///
@@ -299,17 +300,11 @@ public interface IPublicAPI
///
/// Reloads the query.
- /// This method should run when selected item is from query results.
+ /// When current results is from context menu or history, we will back to query results before changing query.
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
- ///
- /// Back to the query results.
- /// This method should run when selected item is from context menu or history.
- ///
- public void BackToQueryResults();
-
///
/// Displays a standardised Flow message box.
///
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index fd829afe2df..81e7600b8fa 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -76,8 +76,6 @@ public void UpdateItem(CustomPluginHotkey item)
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
{
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ChangeQuery(tbAction.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index d05a5c15cf5..dec3506eb35 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -64,8 +64,6 @@ private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
private void BtnTestShortcut_OnClick(object sender, RoutedEventArgs e)
{
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ChangeQuery(tbExpand.Text);
Application.Current.MainWindow.Show();
Application.Current.MainWindow.Opacity = 1;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7706a64ba9d..d7f052af342 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -319,8 +319,6 @@ public bool IsGameModeOn()
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
- public void BackToQueryResults() => _mainVM.BackToQueryResults();
-
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
diff --git a/Flow.Launcher/ResultListBox.xaml.cs b/Flow.Launcher/ResultListBox.xaml.cs
index 83469253633..ac51b195c7b 100644
--- a/Flow.Launcher/ResultListBox.xaml.cs
+++ b/Flow.Launcher/ResultListBox.xaml.cs
@@ -149,11 +149,7 @@ private void ResultList_MouseMove(object sender, MouseEventArgs e)
var rawQuery = query;
var effect = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move | DragDropEffects.Copy);
if (effect == DragDropEffects.Move)
- {
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ChangeQuery(rawQuery, true);
- }
}
private void ResultListBox_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 4af93daf9c2..d8e33ad14aa 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -279,10 +279,8 @@ public void ReQuery()
public void ReQuery(bool reselect)
{
- if (SelectedIsFromQueryResults())
- {
- QueryResults(isReQuery: true, reSelect: reselect);
- }
+ BackToQueryResults();
+ QueryResults(isReQuery: true, reSelect: reselect);
}
[RelayCommand]
@@ -491,7 +489,7 @@ private void Esc()
}
}
- public void BackToQueryResults()
+ private void BackToQueryResults()
{
if (!SelectedIsFromQueryResults())
{
@@ -610,6 +608,8 @@ public void ChangeQueryText(string queryText, bool isReQuery = false)
{
Application.Current.Dispatcher.Invoke(() =>
{
+ BackToQueryResults();
+
if (QueryText != queryText)
{
// re-query is done in QueryText's setter method
@@ -1266,8 +1266,6 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.Remove(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ReQuery();
return false;
}
@@ -1285,8 +1283,6 @@ private Result ContextMenuTopMost(Result result)
{
_topMostRecord.AddOrUpdate(result);
App.API.ShowMsg(InternationalizationManager.Instance.GetTranslation("success"));
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ReQuery();
return false;
}
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 7675ecb1678..38b5bec6561 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -64,8 +64,6 @@ public string Category
private void ShowCommandQuery(string action)
{
var actionKeyword = PluginManagerData.Metadata.ActionKeywords.Any() ? PluginManagerData.Metadata.ActionKeywords[0] + " " : String.Empty;
- // if user happens to open context menu, we need to return back to query results before changing query
- App.API.BackToQueryResults();
App.API.ChangeQuery($"{actionKeyword}{action} {_plugin.Name}");
App.API.ShowMainWindow();
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index c8601c43138..447f06860d7 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -146,8 +146,6 @@ private void OpenSourceCodeLink()
[RelayCommand]
private void OpenDeletePluginWindow()
{
- // if user happens to open context menu, we need to return back to query results before changing query
- PluginManager.API.BackToQueryResults();
PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
PluginManager.API.ShowMainWindow();
}
@@ -161,5 +159,4 @@ private void SetActionKeywords()
changeKeywordsWindow.ShowDialog();
}
}
-
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 6ba7047f23e..c08853df83d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -264,7 +264,6 @@ public List LoadContextMenus(Result selectedResult)
Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_success"),
Context.API.GetTranslation(
"flowlauncher_plugin_program_disable_dlgtitle_success_message"));
- Context.API.BackToQueryResults();
Context.API.ReQuery();
return false;
},
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 86808cfbc2a..62076b49404 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -382,7 +382,6 @@ private void OnWinRPressed()
{
context.API.ShowMainWindow();
// if user happens to open context menu, we need to return back to query results before changing query
- context.API.BackToQueryResults();
context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
From 6f55e8a35dbaf087a265dd2ff772a46d07b42996 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 19:44:21 +0800
Subject: [PATCH 0272/1335] Add BackToQueryResults api function back
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 ++++++
Flow.Launcher/PublicAPIInstance.cs | 2 ++
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 1a8da381b48..28cc1fc9126 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -305,6 +305,12 @@ public interface IPublicAPI
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
+ ///
+ /// Back to the query results.
+ /// This method should run when selected item is from context menu or history.
+ ///
+ public void BackToQueryResults();
+
///
/// Displays a standardised Flow message box.
///
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index d7f052af342..7706a64ba9d 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -319,6 +319,8 @@ public bool IsGameModeOn()
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
+ public void BackToQueryResults() => _mainVM.BackToQueryResults();
+
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index d8e33ad14aa..0d1f5655b71 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -489,7 +489,7 @@ private void Esc()
}
}
- private void BackToQueryResults()
+ public void BackToQueryResults()
{
if (!SelectedIsFromQueryResults())
{
From a6f33401a36eac22a94e77604285259296853eb5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 19:45:43 +0800
Subject: [PATCH 0273/1335] Add BackToQueryResults in json prc api
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index a82cae5d254..e0a0434a203 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -170,5 +170,10 @@ public void OpenAppUri(string appUri)
{
_api.OpenAppUri(appUri);
}
+
+ public void BackToQueryResults()
+ {
+ _api.BackToQueryResults();
+ }
}
}
From 64eb4a7bea6b10467d17fb5e4b623b9ba43dbfd7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 19:48:25 +0800
Subject: [PATCH 0274/1335] Improve documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 4 ++--
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 28cc1fc9126..9b608d14f11 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -18,7 +18,7 @@ public interface IPublicAPI
{
///
/// Change Flow.Launcher query.
- /// When current results is from context menu or history, we will back to query results before changing query.
+ /// When current results are from context menu or history, we will back to query results before changing query.
///
/// query text
///
@@ -300,7 +300,7 @@ public interface IPublicAPI
///
/// Reloads the query.
- /// When current results is from context menu or history, we will back to query results before changing query.
+ /// When current results are from context menu or history, we will back to query results before requerying.
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 62076b49404..53479b81fc3 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -381,7 +381,6 @@ private void OnWinRPressed()
_ = Task.Run(() =>
{
context.API.ShowMainWindow();
- // if user happens to open context menu, we need to return back to query results before changing query
context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
From 61cd5360283b2bcd3e4029d13a5c2d5eac4a00b8 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 22 Feb 2025 23:16:20 +1100
Subject: [PATCH 0275/1335] Apply suggestions from code review
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 9b608d14f11..bf8bbf44a39 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -300,7 +300,7 @@ public interface IPublicAPI
///
/// Reloads the query.
- /// When current results are from context menu or history, we will back to query results before requerying.
+ /// When current results are from context menu or history, it will go back to query results before requerying.
///
/// Choose the first result after reload if true; keep the last selected result if false. Default is true.
public void ReQuery(bool reselect = true);
From 0f82246683e30e62c3b6281da9f5ddf189e30103 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sat, 22 Feb 2025 20:16:36 +0800
Subject: [PATCH 0276/1335] Update
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
Co-authored-by: Jeremy Wu
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index bf8bbf44a39..07fc378c3c4 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -18,7 +18,7 @@ public interface IPublicAPI
{
///
/// Change Flow.Launcher query.
- /// When current results are from context menu or history, we will back to query results before changing query.
+ /// When current results are from context menu or history, it will go back to query results before changing query.
///
/// query text
///
From 81d479c3a3c2177b8f0dc53a5ef7cd485ce99e75 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 22 Feb 2025 22:32:26 +0800
Subject: [PATCH 0277/1335] Fix build issue for nunit 4.3.2 & Improve code
quality
---
Flow.Launcher.Test/FilesFoldersTest.cs | 5 +-
Flow.Launcher.Test/FuzzyMatcherTest.cs | 37 +++++-----
Flow.Launcher.Test/HttpTest.cs | 15 ++--
Flow.Launcher.Test/PluginLoadTest.cs | 31 ++++----
Flow.Launcher.Test/Plugins/ExplorerTest.cs | 70 ++++++-------------
.../Plugins/JsonRPCPluginTest.cs | 16 ++---
Flow.Launcher.Test/Plugins/UrlPluginTest.cs | 33 ++++-----
Flow.Launcher.Test/QueryBuilderTest.cs | 39 ++++++-----
8 files changed, 113 insertions(+), 133 deletions(-)
diff --git a/Flow.Launcher.Test/FilesFoldersTest.cs b/Flow.Launcher.Test/FilesFoldersTest.cs
index 3dead99183e..2621fc2da1f 100644
--- a/Flow.Launcher.Test/FilesFoldersTest.cs
+++ b/Flow.Launcher.Test/FilesFoldersTest.cs
@@ -1,5 +1,6 @@
using Flow.Launcher.Plugin.SharedCommands;
using NUnit.Framework;
+using NUnit.Framework.Legacy;
namespace Flow.Launcher.Test
{
@@ -35,7 +36,7 @@ public class FilesFoldersTest
[TestCase(@"c:\barr", @"c:\foo\..\bar\baz", false)]
public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult)
{
- Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path));
+ ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path));
}
// Equality
@@ -47,7 +48,7 @@ public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(strin
[TestCase(@"c:\foo", @"c:\foo\", true)]
public void GivenTwoPathsAreTheSame_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult)
{
- Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult));
+ ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult));
}
}
}
diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs
index d7f1432184c..9d3b7e70f66 100644
--- a/Flow.Launcher.Test/FuzzyMatcherTest.cs
+++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
@@ -21,8 +22,8 @@ public class FuzzyMatcherTest
private const string MicrosoftSqlServerManagementStudio = "Microsoft SQL Server Management Studio";
private const string VisualStudioCode = "Visual Studio Code";
- public List GetSearchStrings()
- => new List
+ public static List GetSearchStrings()
+ => new()
{
Chrome,
"Choose which programs you want Windows to use for activities like web browsing, editing photos, sending e-mail, and playing music.",
@@ -34,7 +35,7 @@ public List GetSearchStrings()
OneOneOneOne
};
- public List GetPrecisionScores()
+ public static List GetPrecisionScores()
{
var listToReturn = new List();
@@ -71,10 +72,10 @@ public void MatchTest()
results = results.Where(x => x.Score > 0).OrderByDescending(x => x.Score).ToList();
- Assert.IsTrue(results.Count == 3);
- Assert.IsTrue(results[0].Title == "Inste");
- Assert.IsTrue(results[1].Title == "Install Package");
- Assert.IsTrue(results[2].Title == "file open in browser-test");
+ ClassicAssert.IsTrue(results.Count == 3);
+ ClassicAssert.IsTrue(results[0].Title == "Inste");
+ ClassicAssert.IsTrue(results[1].Title == "Install Package");
+ ClassicAssert.IsTrue(results[2].Title == "file open in browser-test");
}
[TestCase("Chrome")]
@@ -84,7 +85,7 @@ public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(st
var matcher = new StringMatcher();
var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore;
- Assert.True(scoreResult == 0);
+ ClassicAssert.True(scoreResult == 0);
}
[TestCase("chr")]
@@ -125,7 +126,7 @@ public void GivenQueryString_WhenAppliedPrecisionFiltering_ThenShouldReturnGreat
Debug.WriteLine("###############################################");
Debug.WriteLine("");
- Assert.IsFalse(filteredResult.Any(x => x.Score < precisionScore));
+ ClassicAssert.IsFalse(filteredResult.Any(x => x.Score < precisionScore));
}
}
@@ -151,7 +152,7 @@ public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring(
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
// Should
- Assert.AreEqual(expectedScore, rawScore,
+ ClassicAssert.AreEqual(expectedScore, rawScore,
$"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
}
@@ -190,12 +191,12 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
Debug.WriteLine("###############################################");
Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
Debug.WriteLine(
- $"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int) expectedPrecisionScore})");
+ $"RAW SCORE: {matchResult.RawScore}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int) expectedPrecisionScore})");
Debug.WriteLine("###############################################");
Debug.WriteLine("");
// Should
- Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
+ ClassicAssert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
$"Query: {queryString}{Environment.NewLine} " +
$"Compare: {compareString}{Environment.NewLine}" +
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
@@ -241,12 +242,12 @@ public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings(
Debug.WriteLine("###############################################");
Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
Debug.WriteLine(
- $"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int) expectedPrecisionScore})");
+ $"RAW SCORE: {matchResult.RawScore}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int) expectedPrecisionScore})");
Debug.WriteLine("###############################################");
Debug.WriteLine("");
// Should
- Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
+ ClassicAssert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
$"Query:{queryString}{Environment.NewLine} " +
$"Compare:{compareString}{Environment.NewLine}" +
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
@@ -277,7 +278,7 @@ public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord(
Debug.WriteLine("");
// Should
- Assert.True(compareString1Result.Score > compareString2Result.Score,
+ ClassicAssert.True(compareString1Result.Score > compareString2Result.Score,
$"Query: \"{queryString}\"{Environment.NewLine} " +
$"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" +
$"Should be greater than{Environment.NewLine}" +
@@ -310,7 +311,7 @@ public void WhenGivenTwoStrings_Scoring_ShouldGiveMoreWeightToTheStringCloserToI
Debug.WriteLine("");
// Should
- Assert.True(compareString1Result.Score > compareString2Result.Score,
+ ClassicAssert.True(compareString1Result.Score > compareString2Result.Score,
$"Query: \"{queryString}\"{Environment.NewLine} " +
$"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" +
$"Should be greater than{Environment.NewLine}" +
@@ -336,7 +337,7 @@ public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(
var secondScore = new[] {secondNameMatch, secondDescriptionMatch, secondExecutableNameMatch}.Max();
// Assert
- Assert.IsTrue(firstScore > secondScore,
+ ClassicAssert.IsTrue(firstScore > secondScore,
$"Query: \"{queryString}\"{Environment.NewLine} " +
$"Name of first: \"{firstName}\", Final Score: {firstScore}{Environment.NewLine}" +
$"Should be greater than{Environment.NewLine}" +
@@ -360,7 +361,7 @@ public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString,
{
var matcher = new StringMatcher();
var score = matcher.FuzzyMatch(queryString, compareString).Score;
- Assert.IsTrue(score == desiredScore,
+ ClassicAssert.IsTrue(score == desiredScore,
$@"Query: ""{queryString}""
CompareString: ""{compareString}""
Score: {score}
diff --git a/Flow.Launcher.Test/HttpTest.cs b/Flow.Launcher.Test/HttpTest.cs
index e72ad7a6761..4f135978a6e 100644
--- a/Flow.Launcher.Test/HttpTest.cs
+++ b/Flow.Launcher.Test/HttpTest.cs
@@ -1,4 +1,5 @@
-using NUnit.Framework;
+using NUnit.Framework;
+using NUnit.Framework.Legacy;
using System;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Infrastructure.Http;
@@ -16,16 +17,16 @@ public void GivenHttpProxy_WhenUpdated_ThenWebProxyShouldAlsoBeUpdatedToTheSame(
proxy.Enabled = true;
proxy.Server = "127.0.0.1";
- Assert.AreEqual(Http.WebProxy.Address, new Uri($"http://{proxy.Server}:{proxy.Port}"));
- Assert.IsNull(Http.WebProxy.Credentials);
+ ClassicAssert.AreEqual(Http.WebProxy.Address, new Uri($"http://{proxy.Server}:{proxy.Port}"));
+ ClassicAssert.IsNull(Http.WebProxy.Credentials);
proxy.UserName = "test";
- Assert.NotNull(Http.WebProxy.Credentials);
- Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").UserName, proxy.UserName);
- Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, "");
+ ClassicAssert.NotNull(Http.WebProxy.Credentials);
+ ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").UserName, proxy.UserName);
+ ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, "");
proxy.Password = "test password";
- Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, proxy.Password);
+ ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, proxy.Password);
}
}
}
diff --git a/Flow.Launcher.Test/PluginLoadTest.cs b/Flow.Launcher.Test/PluginLoadTest.cs
index d6ba48f1905..2cc05f95a1e 100644
--- a/Flow.Launcher.Test/PluginLoadTest.cs
+++ b/Flow.Launcher.Test/PluginLoadTest.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
using System.Collections.Generic;
@@ -15,37 +16,37 @@ public void GivenDuplicatePluginMetadatasWhenLoadedThenShouldReturnOnlyUniqueLis
// Given
var duplicateList = new List
{
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
Version = "1.0.0"
},
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
Version = "1.0.1"
},
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
Version = "1.0.2"
},
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
Version = "1.0.0"
},
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
Version = "1.0.0"
},
- new PluginMetadata
+ new()
{
ID = "ABC0TYUC6D3B7855823D60DC76F28855",
Version = "1.0.0"
},
- new PluginMetadata
+ new()
{
ID = "ABC0TYUC6D3B7855823D60DC76F28855",
Version = "1.0.0"
@@ -56,11 +57,11 @@ public void GivenDuplicatePluginMetadatasWhenLoadedThenShouldReturnOnlyUniqueLis
(var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList);
// Then
- Assert.True(unique.FirstOrDefault().ID == "CEA0TYUC6D3B4085823D60DC76F28855" && unique.FirstOrDefault().Version == "1.0.2");
- Assert.True(unique.Count() == 1);
+ ClassicAssert.True(unique.FirstOrDefault().ID == "CEA0TYUC6D3B4085823D60DC76F28855" && unique.FirstOrDefault().Version == "1.0.2");
+ ClassicAssert.True(unique.Count == 1);
- Assert.False(duplicates.Any(x => x.Version == "1.0.2" && x.ID == "CEA0TYUC6D3B4085823D60DC76F28855"));
- Assert.True(duplicates.Count() == 6);
+ ClassicAssert.False(duplicates.Any(x => x.Version == "1.0.2" && x.ID == "CEA0TYUC6D3B4085823D60DC76F28855"));
+ ClassicAssert.True(duplicates.Count == 6);
}
[Test]
@@ -69,12 +70,12 @@ public void GivenDuplicatePluginMetadatasWithNoUniquePluginWhenLoadedThenShouldR
// Given
var duplicateList = new List
{
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B7855823D60DC76F28855",
Version = "1.0.0"
},
- new PluginMetadata
+ new()
{
ID = "CEA0TYUC6D3B7855823D60DC76F28855",
Version = "1.0.0"
@@ -85,8 +86,8 @@ public void GivenDuplicatePluginMetadatasWithNoUniquePluginWhenLoadedThenShouldR
(var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList);
// Then
- Assert.True(unique.Count() == 0);
- Assert.True(duplicates.Count() == 2);
+ ClassicAssert.True(unique.Count == 0);
+ ClassicAssert.True(duplicates.Count == 2);
}
}
}
diff --git a/Flow.Launcher.Test/Plugins/ExplorerTest.cs b/Flow.Launcher.Test/Plugins/ExplorerTest.cs
index 80cb74729fc..420da266d87 100644
--- a/Flow.Launcher.Test/Plugins/ExplorerTest.cs
+++ b/Flow.Launcher.Test/Plugins/ExplorerTest.cs
@@ -5,12 +5,10 @@
using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
using Flow.Launcher.Plugin.SharedCommands;
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Runtime.Versioning;
-using System.Threading;
-using System.Threading.Tasks;
using static Flow.Launcher.Plugin.Explorer.Search.SearchManager;
namespace Flow.Launcher.Test.Plugins
@@ -22,28 +20,6 @@ namespace Flow.Launcher.Test.Plugins
[TestFixture]
public class ExplorerTest
{
-#pragma warning disable CS1998 // async method with no await (more readable to leave it async to match the tested signature)
- private async Task> MethodWindowsIndexSearchReturnsZeroResultsAsync(Query dummyQuery, string dummyString, CancellationToken dummyToken)
- {
- return new List();
- }
-#pragma warning restore CS1998
-
- private List MethodDirectoryInfoClassSearchReturnsTwoResults(Query dummyQuery, string dummyString, CancellationToken token)
- {
- return new List
- {
- new Result
- {
- Title = "Result 1"
- },
- new Result
- {
- Title = "Result 2"
- }
- };
- }
-
private bool PreviousLocationExistsReturnsTrue(string dummyString) => true;
private bool PreviousLocationNotExistReturnsFalse(string dummyString) => false;
@@ -57,7 +33,7 @@ public void GivenWindowsIndexSearch_WhenProvidedFolderPath_ThenQueryWhereRestric
var result = QueryConstructor.TopLevelDirectoryConstraint(folderPath);
// Then
- Assert.IsTrue(result == expectedString,
+ ClassicAssert.IsTrue(result == expectedString,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual: {result}{Environment.NewLine}");
}
@@ -74,7 +50,7 @@ public void GivenWindowsIndexSearch_WhenSearchTypeIsTopLevelDirectorySearch_Then
var queryString = queryConstructor.Directory(folderPath);
// Then
- Assert.IsTrue(queryString.Replace(" ", " ") == expectedString.Replace(" ", " "),
+ ClassicAssert.IsTrue(queryString.Replace(" ", " ") == expectedString.Replace(" ", " "),
$"Expected string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {queryString}{Environment.NewLine}");
}
@@ -94,7 +70,7 @@ public void GivenWindowsIndexSearchTopLevelDirectory_WhenSearchingForSpecificIte
var queryString = queryConstructor.Directory(folderPath, userSearchString);
// Then
- Assert.AreEqual(expectedString, queryString);
+ ClassicAssert.AreEqual(expectedString, queryString);
}
[SupportedOSPlatform("windows7.0")]
@@ -105,7 +81,7 @@ public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryWhereR
const string resultString = QueryConstructor.RestrictionsForAllFilesAndFoldersSearch;
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
[SupportedOSPlatform("windows7.0")]
@@ -128,7 +104,7 @@ public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryShould
var resultString = queryConstructor.FilesAndFolders(userSearchString);
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
@@ -138,13 +114,13 @@ public void GivenWindowsIndexSearch_WhenQueryWhereRestrictionsIsForFileContentSe
string querySearchString, string expectedString)
{
// Given
- var queryConstructor = new QueryConstructor(new Settings());
+ _ = new QueryConstructor(new Settings());
//When
var resultString = QueryConstructor.RestrictionsForFileContentSearch(querySearchString);
// Then
- Assert.IsTrue(resultString == expectedString,
+ ClassicAssert.IsTrue(resultString == expectedString,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}");
}
@@ -162,12 +138,12 @@ public void GivenWindowsIndexSearch_WhenSearchForFileContent_ThenQueryShouldUseE
var resultString = queryConstructor.FileContent(userSearchString);
// Then
- Assert.IsTrue(resultString == expectedString,
+ ClassicAssert.IsTrue(resultString == expectedString,
$"Expected query string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}");
}
- public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileContentSearchRequiredShouldReturnTrue()
+ public static void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileContentSearchRequiredShouldReturnTrue()
{
// Given
var query = new Query
@@ -181,7 +157,7 @@ public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileConte
var result = searchManager.IsFileContentSearch(query.ActionKeyword);
// Then
- Assert.IsTrue(result,
+ ClassicAssert.IsTrue(result,
$"Expected True for file content search. {Environment.NewLine} " +
$"Actual result was: {result}{Environment.NewLine}");
}
@@ -206,7 +182,7 @@ public void WhenGivenQuerySearchString_ThenShouldIndicateIfIsLocationPathString(
var result = FilesFolders.IsLocationPathString(querySearchString);
//Then
- Assert.IsTrue(result == expectedResult,
+ ClassicAssert.IsTrue(result == expectedResult,
$"Expected query search string check result is: {expectedResult} {Environment.NewLine} " +
$"Actual check result is {result} {Environment.NewLine}");
@@ -233,7 +209,7 @@ public void GivenAPartialPath_WhenPreviousLevelDirectoryExists_ThenShouldReturnT
var previousDirectoryPath = FilesFolders.GetPreviousExistingDirectory(previousLocationExists, path);
//Then
- Assert.IsTrue(previousDirectoryPath == expectedString,
+ ClassicAssert.IsTrue(previousDirectoryPath == expectedString,
$"Expected path string: {expectedString} {Environment.NewLine} " +
$"Actual path string is {previousDirectoryPath} {Environment.NewLine}");
}
@@ -246,7 +222,7 @@ public void WhenGivenAPath_ThenShouldReturnThePreviousDirectoryPathIfIncompleteO
var returnedPath = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path);
//Then
- Assert.IsTrue(returnedPath == expectedString,
+ ClassicAssert.IsTrue(returnedPath == expectedString,
$"Expected path string: {expectedString} {Environment.NewLine} " +
$"Actual path string is {returnedPath} {Environment.NewLine}");
}
@@ -260,7 +236,7 @@ public void GivenFilePath_WhenSearchPatternHotKeyIsSearchAll_ThenQueryWhereRestr
var resultString = QueryConstructor.RecursiveDirectoryConstraint(path);
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
[SupportedOSPlatform("windows7.0")]
@@ -274,7 +250,7 @@ public void GivenDirectoryInfoSearch_WhenSearchPatternHotKeyIsSearchAll_ThenSear
var resultString = DirectoryInfoSearch.ConstructSearchCriteria(path);
// Then
- Assert.AreEqual(expectedString, resultString);
+ ClassicAssert.AreEqual(expectedString, resultString);
}
[TestCase("c:\\somefolder\\someotherfolder", ResultType.Folder, "irrelevant", false, true, "c:\\somefolder\\someotherfolder\\")]
@@ -305,7 +281,7 @@ public void GivenFolderResult_WhenGetPath_ThenPathShouldBeExpectedString(
var result = ResultManager.GetPathWithActionKeyword(path, type, actionKeyword);
// Then
- Assert.AreEqual(result, expectedResult);
+ ClassicAssert.AreEqual(result, expectedResult);
}
[TestCase("c:\\somefolder\\somefile", ResultType.File, "irrelevant", false, true, "e c:\\somefolder\\somefile")]
@@ -334,7 +310,7 @@ public void GivenFileResult_WhenGetPath_ThenPathShouldBeExpectedString(
var result = ResultManager.GetPathWithActionKeyword(path, type, actionKeyword);
// Then
- Assert.AreEqual(result, expectedResult);
+ ClassicAssert.AreEqual(result, expectedResult);
}
[TestCase("somefolder", "c:\\somefolder\\", ResultType.Folder, "q", false, false, "q somefolder")]
@@ -366,7 +342,7 @@ public void GivenQueryWithFolderTypeResult_WhenGetAutoComplete_ThenResultShouldB
var result = ResultManager.GetAutoCompleteText(title, query, path, resultType);
// Then
- Assert.AreEqual(result, expectedResult);
+ ClassicAssert.AreEqual(result, expectedResult);
}
[TestCase("somefile", "c:\\somefolder\\somefile", ResultType.File, "q", false, false, "q somefile")]
@@ -398,7 +374,7 @@ public void GivenQueryWithFileTypeResult_WhenGetAutoComplete_ThenResultShouldBeE
var result = ResultManager.GetAutoCompleteText(title, query, path, resultType);
// Then
- Assert.AreEqual(result, expectedResult);
+ ClassicAssert.AreEqual(result, expectedResult);
}
[TestCase(@"c:\foo", @"c:\foo", true)]
@@ -420,7 +396,7 @@ public void GivenTwoPaths_WhenCompared_ThenShouldBeExpectedSameOrDifferent(strin
};
// When, Then
- Assert.AreEqual(expectedResult, comparator.Equals(result1, result2));
+ ClassicAssert.AreEqual(expectedResult, comparator.Equals(result1, result2));
}
[TestCase(@"c:\foo\", @"c:\foo\")]
@@ -444,7 +420,7 @@ public void GivenTwoPaths_WhenComparedHasCode_ThenShouldBeSame(string path1, str
var hash2 = comparator.GetHashCode(result2);
// When, Then
- Assert.IsTrue(hash1 == hash2);
+ ClassicAssert.IsTrue(hash1 == hash2);
}
[TestCase(@"%appdata%", true)]
@@ -461,7 +437,7 @@ public void GivenPath_WhenHavingEnvironmentVariableOrNot_ThenShouldBeExpected(st
var result = EnvironmentVariables.HasEnvironmentVar(path);
// Then
- Assert.AreEqual(result, expectedResult);
+ ClassicAssert.AreEqual(result, expectedResult);
}
}
}
diff --git a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
index 42a4630fe5c..497f874e70f 100644
--- a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
+++ b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs
@@ -1,12 +1,11 @@
-using NUnit.Framework;
+using NUnit.Framework;
+using NUnit.Framework.Legacy;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Text;
-using System.Text.Json;
-using System.Linq;
using System.Collections.Generic;
namespace Flow.Launcher.Test.Plugins
@@ -40,13 +39,13 @@ public async Task GivenVariousJsonText_WhenVariousNamingCase_ThenExpectNotNullRe
Search = resultText
}, default);
- Assert.IsNotNull(results);
+ ClassicAssert.IsNotNull(results);
foreach (var result in results)
{
- Assert.IsNotNull(result);
- Assert.IsNotNull(result.AsyncAction);
- Assert.IsNotNull(result.Title);
+ ClassicAssert.IsNotNull(result);
+ ClassicAssert.IsNotNull(result.AsyncAction);
+ ClassicAssert.IsNotNull(result.Title);
}
}
@@ -56,12 +55,11 @@ public async Task GivenVariousJsonText_WhenVariousNamingCase_ThenExpectNotNullRe
new JsonRPCQueryResponseModel(0, new List()),
new JsonRPCQueryResponseModel(0, new List
{
- new JsonRPCResult
+ new()
{
Title = "Test1", SubTitle = "Test2"
}
})
};
-
}
}
diff --git a/Flow.Launcher.Test/Plugins/UrlPluginTest.cs b/Flow.Launcher.Test/Plugins/UrlPluginTest.cs
index 7ccac5bd59d..0dd1fe4895a 100644
--- a/Flow.Launcher.Test/Plugins/UrlPluginTest.cs
+++ b/Flow.Launcher.Test/Plugins/UrlPluginTest.cs
@@ -1,7 +1,8 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using Flow.Launcher.Plugin.Url;
-namespace Flow.Launcher.Test
+namespace Flow.Launcher.Test.Plugins
{
[TestFixture]
public class UrlPluginTest
@@ -10,23 +11,23 @@ public class UrlPluginTest
public void URLMatchTest()
{
var plugin = new Main();
- Assert.IsTrue(plugin.IsURL("http://www.google.com"));
- Assert.IsTrue(plugin.IsURL("https://www.google.com"));
- Assert.IsTrue(plugin.IsURL("http://google.com"));
- Assert.IsTrue(plugin.IsURL("www.google.com"));
- Assert.IsTrue(plugin.IsURL("google.com"));
- Assert.IsTrue(plugin.IsURL("http://localhost"));
- Assert.IsTrue(plugin.IsURL("https://localhost"));
- Assert.IsTrue(plugin.IsURL("http://localhost:80"));
- Assert.IsTrue(plugin.IsURL("https://localhost:80"));
- Assert.IsTrue(plugin.IsURL("http://110.10.10.10"));
- Assert.IsTrue(plugin.IsURL("110.10.10.10"));
- Assert.IsTrue(plugin.IsURL("ftp://110.10.10.10"));
+ ClassicAssert.IsTrue(plugin.IsURL("http://www.google.com"));
+ ClassicAssert.IsTrue(plugin.IsURL("https://www.google.com"));
+ ClassicAssert.IsTrue(plugin.IsURL("http://google.com"));
+ ClassicAssert.IsTrue(plugin.IsURL("www.google.com"));
+ ClassicAssert.IsTrue(plugin.IsURL("google.com"));
+ ClassicAssert.IsTrue(plugin.IsURL("http://localhost"));
+ ClassicAssert.IsTrue(plugin.IsURL("https://localhost"));
+ ClassicAssert.IsTrue(plugin.IsURL("http://localhost:80"));
+ ClassicAssert.IsTrue(plugin.IsURL("https://localhost:80"));
+ ClassicAssert.IsTrue(plugin.IsURL("http://110.10.10.10"));
+ ClassicAssert.IsTrue(plugin.IsURL("110.10.10.10"));
+ ClassicAssert.IsTrue(plugin.IsURL("ftp://110.10.10.10"));
- Assert.IsFalse(plugin.IsURL("wwww"));
- Assert.IsFalse(plugin.IsURL("wwww.c"));
- Assert.IsFalse(plugin.IsURL("wwww.c"));
+ ClassicAssert.IsFalse(plugin.IsURL("wwww"));
+ ClassicAssert.IsFalse(plugin.IsURL("wwww.c"));
+ ClassicAssert.IsFalse(plugin.IsURL("wwww.c"));
}
}
}
diff --git a/Flow.Launcher.Test/QueryBuilderTest.cs b/Flow.Launcher.Test/QueryBuilderTest.cs
index aa0c8da12b9..c8ac17748da 100644
--- a/Flow.Launcher.Test/QueryBuilderTest.cs
+++ b/Flow.Launcher.Test/QueryBuilderTest.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
@@ -17,17 +18,17 @@ public void ExclusivePluginQueryTest()
Query q = QueryBuilder.Build("> ping google.com -n 20 -6", nonGlobalPlugins);
- Assert.AreEqual("> ping google.com -n 20 -6", q.RawQuery);
- Assert.AreEqual("ping google.com -n 20 -6", q.Search, "Search should not start with the ActionKeyword.");
- Assert.AreEqual(">", q.ActionKeyword);
+ ClassicAssert.AreEqual("> ping google.com -n 20 -6", q.RawQuery);
+ ClassicAssert.AreEqual("ping google.com -n 20 -6", q.Search, "Search should not start with the ActionKeyword.");
+ ClassicAssert.AreEqual(">", q.ActionKeyword);
- Assert.AreEqual(5, q.SearchTerms.Length, "The length of SearchTerms should match.");
+ ClassicAssert.AreEqual(5, q.SearchTerms.Length, "The length of SearchTerms should match.");
- Assert.AreEqual("ping", q.FirstSearch);
- Assert.AreEqual("google.com", q.SecondSearch);
- Assert.AreEqual("-n", q.ThirdSearch);
+ ClassicAssert.AreEqual("ping", q.FirstSearch);
+ ClassicAssert.AreEqual("google.com", q.SecondSearch);
+ ClassicAssert.AreEqual("-n", q.ThirdSearch);
- Assert.AreEqual("google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters");
+ ClassicAssert.AreEqual("google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters");
}
[Test]
@@ -40,11 +41,11 @@ public void ExclusivePluginQueryIgnoreDisabledTest()
Query q = QueryBuilder.Build("> ping google.com -n 20 -6", nonGlobalPlugins);
- Assert.AreEqual("> ping google.com -n 20 -6", q.Search);
- Assert.AreEqual(q.Search, q.RawQuery, "RawQuery should be equal to Search.");
- Assert.AreEqual(6, q.SearchTerms.Length, "The length of SearchTerms should match.");
- Assert.AreNotEqual(">", q.ActionKeyword, "ActionKeyword should not match that of a disabled plugin.");
- Assert.AreEqual("ping google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters");
+ ClassicAssert.AreEqual("> ping google.com -n 20 -6", q.Search);
+ ClassicAssert.AreEqual(q.Search, q.RawQuery, "RawQuery should be equal to Search.");
+ ClassicAssert.AreEqual(6, q.SearchTerms.Length, "The length of SearchTerms should match.");
+ ClassicAssert.AreNotEqual(">", q.ActionKeyword, "ActionKeyword should not match that of a disabled plugin.");
+ ClassicAssert.AreEqual("ping google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters");
}
[Test]
@@ -52,13 +53,13 @@ public void GenericPluginQueryTest()
{
Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary());
- Assert.AreEqual("file.txt file2 file3", q.Search);
- Assert.AreEqual("", q.ActionKeyword);
+ ClassicAssert.AreEqual("file.txt file2 file3", q.Search);
+ ClassicAssert.AreEqual("", q.ActionKeyword);
- Assert.AreEqual("file.txt", q.FirstSearch);
- Assert.AreEqual("file2", q.SecondSearch);
- Assert.AreEqual("file3", q.ThirdSearch);
- Assert.AreEqual("file2 file3", q.SecondToEndSearch);
+ ClassicAssert.AreEqual("file.txt", q.FirstSearch);
+ ClassicAssert.AreEqual("file2", q.SecondSearch);
+ ClassicAssert.AreEqual("file3", q.ThirdSearch);
+ ClassicAssert.AreEqual("file2 file3", q.SecondToEndSearch);
}
}
}
From 3e9a0e2c71c39aa85b79b2839fed4ec2d580e71e Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 23 Feb 2025 06:10:41 +0900
Subject: [PATCH 0278/1335] Added basic structure for fluent window
---
Flow.Launcher.Core/Resource/Theme.cs | 151 ++++++++++++++++++++
Flow.Launcher.Infrastructure/Win32Helper.cs | 22 +++
Flow.Launcher/MainWindow.xaml | 10 +-
Flow.Launcher/MainWindow.xaml.cs | 4 +-
4 files changed, 181 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 2c2feeae171..ed975aa9dc2 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -12,6 +12,9 @@
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using System.Windows.Shell;
+using static Flow.Launcher.Core.Resource.Theme.ParameterTypes;
+using System.Runtime.InteropServices;
+using System.Windows.Interop;
namespace Flow.Launcher.Core.Resource
{
@@ -59,6 +62,153 @@ public Theme()
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
+ #region Blur Handling
+ public class ParameterTypes
+ {
+
+ [Flags]
+ public enum DWMWINDOWATTRIBUTE
+ {
+ DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
+ DWMWA_SYSTEMBACKDROP_TYPE = 38,
+ DWMWA_TRANSITIONS_FORCEDISABLED = 3,
+ DWMWA_BORDER_COLOR
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MARGINS
+ {
+ public int cxLeftWidth; // width of left border that retains its size
+ public int cxRightWidth; // width of right border that retains its size
+ public int cyTopHeight; // height of top border that retains its size
+ public int cyBottomHeight; // height of bottom border that retains its size
+ };
+ }
+
+ public static class Methods
+ {
+ [DllImport("DwmApi.dll")]
+ static extern int DwmExtendFrameIntoClientArea(
+ IntPtr hwnd,
+ ref ParameterTypes.MARGINS pMarInset);
+
+ [DllImport("dwmapi.dll")]
+ static extern int DwmSetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE dwAttribute, ref int pvAttribute, int cbAttribute);
+
+ public static int ExtendFrame(IntPtr hwnd, ParameterTypes.MARGINS margins)
+ => DwmExtendFrameIntoClientArea(hwnd, ref margins);
+
+ public static int SetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE attribute, int parameter)
+ => DwmSetWindowAttribute(hwnd, attribute, ref parameter, Marshal.SizeOf());
+ }
+
+ Window mainWindow = Application.Current.MainWindow;
+
+ public void RefreshFrame()
+ {
+ IntPtr mainWindowPtr = new WindowInteropHelper(mainWindow).Handle;
+ HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
+ //mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 255, 181, 178);
+
+ ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
+ margins.cxLeftWidth = -1;
+ margins.cxRightWidth = -1;
+ margins.cyTopHeight = -1;
+ margins.cyBottomHeight = -1;
+ Methods.ExtendFrame(mainWindowSrc.Handle, margins);
+
+ // Remove OS minimizing/maximizing animation
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
+ //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+ SetBlurForWindow();
+ }
+
+
+
+ ///
+ /// Sets the blur for a window via SetWindowCompositionAttribute
+ ///
+ public void SetBlurForWindow()
+ {
+ //SetWindowAccent();
+ var dict = GetThemeResourceDictionary(Settings.Theme);
+ var windowBorderStyle = dict["WindowBorderStyle"] as Style;
+ if (BlurEnabled)
+ {
+ windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
+ windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
+ //mainWindow.WindowStyle = WindowStyle.SingleBorderWindow;
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+ BlurColor(BlurMode());
+ }
+ else
+ {
+ mainWindow.WindowStyle = WindowStyle.None;
+ if (windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background") != null)
+ {
+ windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
+ }
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1);
+ }
+ UpdateResourceDictionary(dict);
+ }
+
+ public void BlurColor(string Color)
+ {
+ if (Color == "Light")
+ {
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
+ }
+ else if (Color == "Dark")
+ {
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
+ }
+ else /* Case of "Auto" Blur Type Theme */
+ {
+ //if (_isDarkTheme())
+ //{
+ // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
+ //}
+ //else
+ //{
+ // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
+ //}
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
+ }
+
+ }
+ public bool IsBlurTheme()
+ {
+ if (Environment.OSVersion.Version >= new Version(6, 2))
+ {
+ var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
+
+ if (resource is bool)
+ return (bool)resource;
+
+ return false;
+ }
+
+ return false;
+ }
+ public string BlurMode()
+ {
+ if (Environment.OSVersion.Version >= new Version(6, 2))
+ {
+ var resource = Application.Current.TryFindResource("BlurMode");
+
+ if (resource is string)
+ return (string)resource;
+
+ return null;
+ }
+
+ return null;
+ }
+
+ #endregion
+
private void MakeSureThemeDirectoriesExist()
{
foreach (var dir in _themeDirectories.Where(dir => !Directory.Exists(dir)))
@@ -103,6 +253,7 @@ public bool ChangeTheme(string theme)
AddDropShadowEffectToCurrentTheme();
Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
+ //Win32Helper.SetMicaForWindow(Application.Current.MainWindow, BlurEnabled);
}
catch (DirectoryNotFoundException)
{
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 867fef4f509..856748537e5 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -7,6 +7,28 @@ namespace Flow.Launcher.Infrastructure
{
public static class Win32Helper
{
+ private enum DwmSystemBackdropType
+ {
+ DWMSBT_AUTO = 0,
+ DWMSBT_NONE = 1,
+ DWMSBT_MICA = 2,
+ DWMSBT_ACRYLIC = 3,
+ DWMSBT_TABBED = 4
+ }
+
+ private const int DWMWA_SYSTEMBACKDROP_TYPE = 38;
+
+ [DllImport("dwmapi.dll")]
+ private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref DwmSystemBackdropType pvAttribute, int cbAttribute);
+
+ public static void SetMicaForWindow(Window window, bool enableMica)
+ {
+ var windowHelper = new WindowInteropHelper(window);
+ windowHelper.EnsureHandle();
+
+ DwmSystemBackdropType backdropType = enableMica ? DwmSystemBackdropType.DWMSBT_MICA : DwmSystemBackdropType.DWMSBT_NONE;
+ DwmSetWindowAttribute(windowHelper.Handle, DWMWA_SYSTEMBACKDROP_TYPE, ref backdropType, sizeof(int));
+ }
#region Blur Handling
/*
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 10fc3583b8b..22594217f52 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -15,12 +15,11 @@
MinHeight="30"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
AllowDrop="True"
- AllowsTransparency="True"
- Background="Transparent"
+ AllowsTransparency="False"
+ Background="#DB213C95"
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
- SourceInitialized="OnSourceInitialized"
Initialized="OnInitialized"
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
@@ -31,10 +30,11 @@
ResizeMode="CanResize"
ShowInTaskbar="False"
SizeToContent="Height"
+ SourceInitialized="OnSourceInitialized"
Topmost="True"
Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
WindowStartupLocation="Manual"
- WindowStyle="None"
+ WindowStyle="SingleBorderWindow"
mc:Ignorable="d">
@@ -213,7 +213,7 @@
Modifiers="{Binding CycleHistoryDownHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='modifiers'}" />
-
+
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 41dc68fd924..abb959ad8fa 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -60,7 +60,6 @@ public MainWindow(Settings settings, MainViewModel mainVM)
InitializePosition();
InitSoundEffects();
-
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
this.Loaded += (_, _) =>
@@ -182,6 +181,9 @@ private void OnInitialized(object sender, EventArgs e)
private void OnLoaded(object sender, RoutedEventArgs _)
{
+ // Remove OS minimizing/maximizing animation
+ ThemeManager.Instance.RefreshFrame();
+
// MouseEventHandler
PreviewMouseMove += MainPreviewMouseMove;
CheckFirstLaunch();
From 270f5b3ca07f4fe51079295a48f4948f46674dd2 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 23 Feb 2025 09:48:33 +0900
Subject: [PATCH 0279/1335] Base Structure for fluent window
---
Flow.Launcher.Core/Resource/Theme.cs | 52 ++++++++++++++-----
Flow.Launcher/MainWindow.xaml | 4 +-
Flow.Launcher/MainWindow.xaml.cs | 3 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 1 +
Flow.Launcher/Themes/BlurBlack.xaml | 2 +-
Flow.Launcher/Themes/Win11Light.xaml | 4 +-
6 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index ed975aa9dc2..3ebcd65c738 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -15,6 +15,7 @@
using static Flow.Launcher.Core.Resource.Theme.ParameterTypes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
+using System.Diagnostics;
namespace Flow.Launcher.Core.Resource
{
@@ -119,8 +120,9 @@ public void RefreshFrame()
// Remove OS minimizing/maximizing animation
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
+
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+ //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
SetBlurForWindow();
}
@@ -131,24 +133,26 @@ public void RefreshFrame()
///
public void SetBlurForWindow()
{
+
//SetWindowAccent();
var dict = GetThemeResourceDictionary(Settings.Theme);
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
if (BlurEnabled)
{
+ //mainWindow.WindowStyle = WindowStyle.SingleBorderWindow;
+ BlurColor(BlurMode());
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
- //mainWindow.WindowStyle = WindowStyle.SingleBorderWindow;
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- BlurColor(BlurMode());
}
else
{
- mainWindow.WindowStyle = WindowStyle.None;
- if (windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background") != null)
- {
- windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
- }
+ //mainWindow.WindowStyle = WindowStyle.None;
+ //if (windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background") != null)
+ //{
+ // windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
+ //}
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1);
}
UpdateResourceDictionary(dict);
@@ -156,28 +160,34 @@ public void SetBlurForWindow()
public void BlurColor(string Color)
{
+
if (Color == "Light")
{
+ //mainWindow.Background = new SolidColorBrush(defaultBGcolor.Value);
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
}
else if (Color == "Dark")
{
+ //mainWindow.Background = new SolidColorBrush(darkBGcolor.Value);
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
}
else /* Case of "Auto" Blur Type Theme */
{
//if (_isDarkTheme())
//{
+ // mainWindow.Background = new SolidColorBrush(darkBGcolor.Value);
// Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
//}
//else
//{
+ // mainWindow.Background = new SolidColorBrush(defaultBGcolor.Value);
// Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
//}
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- }
+ //mainWindow.Background = new SolidColorBrush(Colors.Red);
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1); }
}
+
public bool IsBlurTheme()
{
if (Environment.OSVersion.Version >= new Version(6, 2))
@@ -207,6 +217,24 @@ public string BlurMode()
return null;
}
+ //public SolidColorBrush BGColor(string colorBgKey)
+ //{
+ // var defaultBG = Application.Current.TryFindResource("DefaultBG");
+ // var darkBG = Application.Current.TryFindResource("DarkBG");
+
+ // if (colorBgKey == "")
+ // {
+ // var resource = Application.Current.TryFindResource("BlurMode");
+
+ // if (resource is string)
+ // return (SolidColorBrush)resource;
+
+ // return new SolidColorBrush(Colors.DarkGray);
+ // }
+
+ // return null;
+ //}
+
#endregion
private void MakeSureThemeDirectoriesExist()
@@ -252,8 +280,8 @@ public bool ChangeTheme(string theme)
if (Settings.UseDropShadowEffect && !BlurEnabled)
AddDropShadowEffectToCurrentTheme();
- Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
- //Win32Helper.SetMicaForWindow(Application.Current.MainWindow, BlurEnabled);
+ //Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
+ SetBlurForWindow();
}
catch (DirectoryNotFoundException)
{
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 22594217f52..d99787a8d6b 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -16,7 +16,7 @@
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
AllowDrop="True"
AllowsTransparency="False"
- Background="#DB213C95"
+ Background="#E12E2E2E"
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
@@ -213,7 +213,7 @@
Modifiers="{Binding CycleHistoryDownHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='modifiers'}" />
-
+
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index abb959ad8fa..8270150c24a 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -61,7 +61,6 @@ public MainWindow(Settings settings, MainViewModel mainVM)
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
-
this.Loaded += (_, _) =>
{
var handle = new WindowInteropHelper(this).Handle;
@@ -107,6 +106,7 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
return IntPtr.Zero;
}
+
private void OnResizeEnd()
{
int shadowMargin = 0;
@@ -181,7 +181,6 @@ private void OnInitialized(object sender, EventArgs e)
private void OnLoaded(object sender, RoutedEventArgs _)
{
- // Remove OS minimizing/maximizing animation
ThemeManager.Instance.RefreshFrame();
// MouseEventHandler
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 8d8ccb78041..ab2419d9937 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -39,6 +39,7 @@ public Theme.ThemeData SelectedTheme
if (ThemeManager.Instance.BlurEnabled && Settings.UseDropShadowEffect)
DropShadowEffect = false;
+ ThemeManager.Instance.RefreshFrame();
}
}
diff --git a/Flow.Launcher/Themes/BlurBlack.xaml b/Flow.Launcher/Themes/BlurBlack.xaml
index 5d0fc2c3c63..63fb836091a 100644
--- a/Flow.Launcher/Themes/BlurBlack.xaml
+++ b/Flow.Launcher/Themes/BlurBlack.xaml
@@ -10,8 +10,8 @@
-
True
+ Auto
diff --git a/Flow.Launcher/Themes/Win11Light.xaml b/Flow.Launcher/Themes/Win11Light.xaml
index 4fe3c0495c4..52758171a68 100644
--- a/Flow.Launcher/Themes/Win11Light.xaml
+++ b/Flow.Launcher/Themes/Win11Light.xaml
@@ -1,7 +1,7 @@
+ True
+ Auto
@@ -96,7 +88,7 @@
TargetType="{x:Type Rectangle}">
-
+
-
+
@@ -174,7 +166,7 @@
x:Key="ClockPanel"
BasedOn="{StaticResource ClockPanel}"
TargetType="{x:Type StackPanel}">
-
+
+
+
+ 70,9,18,9
+ 9,0,0,0
+ 0,0,9,0
From 3fa88064bd572741c8590ce7a1064fb65324b65a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 18:30:33 +0800
Subject: [PATCH 0340/1335] Remove useless localization
---
Flow.Launcher/Languages/en.xaml | 3 ---
Flow.Launcher/ReportWindow.xaml.cs | 33 +++++-------------------------
2 files changed, 5 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 493528a8980..5d2cb2d9e98 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -386,9 +386,6 @@
Please open new issue in
1. Upload log file: {0}
2. Copy below exception message
- Date: {0}
- Exception:
- Length
Please wait...
diff --git a/Flow.Launcher/ReportWindow.xaml.cs b/Flow.Launcher/ReportWindow.xaml.cs
index 12ffe3ffc5e..6fe90783ec9 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -6,10 +6,10 @@
using System.Linq;
using System.Windows;
using System.Windows.Documents;
+using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
-using Flow.Launcher.Infrastructure.Exception;
namespace Flow.Launcher
{
@@ -55,12 +55,11 @@ private void SetException(Exception exception)
ErrorTextbox.Document.Blocks.Add(paragraph);
StringBuilder content = new StringBuilder();
- content.AppendLine(RuntimeInfo());
+ content.AppendLine(ErrorReporting.RuntimeInfo());
+ content.AppendLine(ErrorReporting.DependenciesInfo());
content.AppendLine();
- content.AppendLine(DependenciesInfo());
- content.AppendLine();
- content.AppendLine(string.Format(App.API.GetTranslation("reportWindow_date"), DateTime.Now.ToString(CultureInfo.InvariantCulture)));
- content.AppendLine(App.API.GetTranslation("reportWindow_exception"));
+ content.AppendLine($"Date: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}");
+ content.AppendLine("Exception:");
content.AppendLine(exception.ToString());
paragraph = new Paragraph();
paragraph.Inlines.Add(content.ToString());
@@ -94,27 +93,5 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
-
- private static string RuntimeInfo()
- {
- var info =
- $"""
- Flow Launcher {App.API.GetTranslation("reportWindow_version")}: {Constant.Version}
- OS {App.API.GetTranslation("reportWindow_version")}: {ExceptionFormatter.GetWindowsFullVersionFromRegistry()}
- IntPtr {App.API.GetTranslation("reportWindow_length")}: {IntPtr.Size}
- x64: {Environment.Is64BitOperatingSystem}
- """;
- return info;
- }
-
- private static string DependenciesInfo()
- {
- var info =
- $"""
- {App.API.GetTranslation("pythonFilePath")}: {Constant.PythonPath}
- {App.API.GetTranslation("nodeFilePath")}: {Constant.NodePath}
- """;
- return info;
- }
}
}
From ed5e0bb2d9a8c908f301d794ce2f4bcda8d2b8ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 20:11:27 +0800
Subject: [PATCH 0341/1335] Improve documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 11 +++++------
Flow.Launcher/ProgressBoxEx.xaml.cs | 14 +++++++-------
Flow.Launcher/PublicAPIInstance.cs | 2 +-
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 8376fd07ba7..ef22b697e80 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,17 +322,16 @@ public interface IPublicAPI
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK);
///
- /// Displays a standardised Flow message box.
- /// If there is issue when showing the message box, it will return null.
+ /// Displays a standardised Flow progress box.
///
- /// The caption of the message box.
+ /// The caption of the progress box.
///
/// Time-consuming task function, whose input is the action to report progress.
/// The input of the action is the progress value which is a double value between 0 and 100.
/// If there are any exceptions, this action will be null.
///
- /// When user closes the progress box manually by button or esc key, this action will be called.
- /// A progress box interface.
- public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
+ /// When user cancel the progress, this action will be called.
+ ///
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 755fc4a1fa1..2395bdf3497 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -8,15 +8,15 @@ namespace Flow.Launcher
{
public partial class ProgressBoxEx : Window
{
- private readonly Action _forceClosed;
+ private readonly Action _cancelProgress;
- private ProgressBoxEx(Action forceClosed)
+ private ProgressBoxEx(Action cancelProgress)
{
- _forceClosed = forceClosed;
+ _cancelProgress = cancelProgress;
InitializeComponent();
}
- public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null)
+ public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null)
{
ProgressBoxEx prgBox = null;
try
@@ -25,7 +25,7 @@ public static async Task ShowAsync(string caption, Func, Task> re
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -35,7 +35,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
}
else
{
- prgBox = new ProgressBoxEx(forceClosed)
+ prgBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
@@ -113,7 +113,7 @@ private void Button_Background(object sender, RoutedEventArgs e)
private void ForceClose()
{
Close();
- _forceClosed?.Invoke();
+ _cancelProgress?.Invoke();
}
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 7706a64ba9d..848d7f14c00 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ public bool IsGameModeOn()
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
#endregion
From 51e62d2ad528b25c8046197b471b2d673492584d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 21:21:52 +0800
Subject: [PATCH 0342/1335] Improve action keyword panel
---
.../Resources/Controls/InstalledPluginDisplayKeyword.xaml | 5 +++--
Flow.Launcher/Resources/CustomControlTemplate.xaml | 7 ++++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index 6877253c47e..3944f6b75e0 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -20,7 +20,7 @@
Visibility="{Binding ActionKeywordsVisibility}">
- 70,9,18,9
- 9,0,0,0
- 0,0,9,0
+ 70,0,18,0
+ 9,9,0,9
+ 0,9,9,9
+ 9,9,9,9
From 8fa34917aab8ed9b1c46c96436c8fbb1d5efb111 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 21:22:17 +0800
Subject: [PATCH 0343/1335] Redesgin settings panel for calculator plugin
---
.../Views/CalculatorSettings.xaml | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
index d6237c6daf6..ceee3897c18 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
@@ -17,7 +17,7 @@
-
+
@@ -30,7 +30,7 @@
@@ -39,8 +39,9 @@
Grid.Row="0"
Grid.Column="1"
MaxWidth="300"
- Margin="10,5,0,5"
+ Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
+ VerticalAlignment="Center"
ItemsSource="{Binding Source={ui:EnumBindingSource {x:Type calculator:DecimalSeparator}}}"
SelectedItem="{Binding Settings.DecimalSeparator}">
@@ -53,7 +54,7 @@
@@ -61,8 +62,9 @@
x:Name="MaxDecimalPlaces"
Grid.Row="1"
Grid.Column="1"
- Margin="10,5,0,5"
+ Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
+ VerticalAlignment="Center"
ItemsSource="{Binding MaxDecimalPlacesRange}"
SelectedItem="{Binding Settings.MaxDecimalPlaces}" />
From f7b1190f9563e188fa4d733f1fa7d9b6c0b1c3cc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 22:03:26 +0800
Subject: [PATCH 0344/1335] Add global search panel
---
Flow.Launcher/ActionKeywords.xaml.cs | 18 ++-
Flow.Launcher/Languages/en.xaml | 1 +
.../InstalledPluginDisplayKeyword.xaml | 106 ++++++++++++------
Flow.Launcher/ViewModel/PluginViewModel.cs | 17 +++
4 files changed, 105 insertions(+), 37 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index 80a4abef126..4b678f42df0 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -77,11 +77,25 @@ private void ReplaceActionKeyword(string id, IReadOnlyList removedAction
{
foreach (var actionKeyword in removedActionKeywords)
{
- App.API.RemoveActionKeyword(id, actionKeyword);
+ if (actionKeyword == Query.GlobalPluginWildcardSign)
+ {
+ pluginViewModel.GlobalSearch = false;
+ }
+ else
+ {
+ App.API.RemoveActionKeyword(id, actionKeyword);
+ }
}
foreach (var actionKeyword in addedActionKeywords)
{
- App.API.AddActionKeyword(id, actionKeyword);
+ if (actionKeyword == Query.GlobalPluginWildcardSign)
+ {
+ pluginViewModel.GlobalSearch = true;
+ }
+ else
+ {
+ App.API.AddActionKeyword(id, actionKeyword);
+ }
}
// Update action keywords text and close window
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index b1575b252ee..f2eeb2de5d8 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -114,6 +114,7 @@
Off
Action keyword Setting
Action keyword
+ Global search
Current action keyword
New action keyword
Change Action Keywords
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index ff2f14c4b2d..197e9ddef76 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -4,44 +4,80 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModel="clr-namespace:Flow.Launcher.ViewModel"
d:DataContext="{d:DesignInstance viewModel:PluginViewModel}"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 9b717216aa6..026e9965b97 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -105,6 +105,23 @@ public Control SettingControl
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
public string InitAndQueryTime => InternationalizationManager.Instance.GetTranslation("plugin_init_time") + " " + PluginPair.Metadata.InitTime + "ms, " + InternationalizationManager.Instance.GetTranslation("plugin_query_time") + " " + PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
+ public bool GlobalSearch
+ {
+ get => PluginPair.Metadata.ActionKeywords.Contains(Query.GlobalPluginWildcardSign);
+ set
+ {
+ if (value)
+ {
+ App.API.AddActionKeyword(PluginPair.Metadata.ID, Query.GlobalPluginWildcardSign);
+ }
+ else
+ {
+ App.API.RemoveActionKeyword(PluginPair.Metadata.ID, Query.GlobalPluginWildcardSign);
+ }
+ OnPropertyChanged();
+ OnActionKeywordsChanged();
+ }
+ }
public int Priority => PluginPair.Metadata.Priority;
public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; }
From 0c6b89fc92565b2487ce9450c9cc2c426e0a5110 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 26 Feb 2025 22:27:16 +0800
Subject: [PATCH 0345/1335] Revert "Add global search panel"
This reverts commit f7b1190f9563e188fa4d733f1fa7d9b6c0b1c3cc.
---
Flow.Launcher/ActionKeywords.xaml.cs | 18 +--
Flow.Launcher/Languages/en.xaml | 1 -
.../InstalledPluginDisplayKeyword.xaml | 106 ++++++------------
Flow.Launcher/ViewModel/PluginViewModel.cs | 17 ---
4 files changed, 37 insertions(+), 105 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index 4b678f42df0..80a4abef126 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -77,25 +77,11 @@ private void ReplaceActionKeyword(string id, IReadOnlyList removedAction
{
foreach (var actionKeyword in removedActionKeywords)
{
- if (actionKeyword == Query.GlobalPluginWildcardSign)
- {
- pluginViewModel.GlobalSearch = false;
- }
- else
- {
- App.API.RemoveActionKeyword(id, actionKeyword);
- }
+ App.API.RemoveActionKeyword(id, actionKeyword);
}
foreach (var actionKeyword in addedActionKeywords)
{
- if (actionKeyword == Query.GlobalPluginWildcardSign)
- {
- pluginViewModel.GlobalSearch = true;
- }
- else
- {
- App.API.AddActionKeyword(id, actionKeyword);
- }
+ App.API.AddActionKeyword(id, actionKeyword);
}
// Update action keywords text and close window
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f2eeb2de5d8..b1575b252ee 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -114,7 +114,6 @@
Off
Action keyword Setting
Action keyword
- Global search
Current action keyword
New action keyword
Change Action Keywords
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index 197e9ddef76..ff2f14c4b2d 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -4,80 +4,44 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModel="clr-namespace:Flow.Launcher.ViewModel"
d:DataContext="{d:DesignInstance viewModel:PluginViewModel}"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 026e9965b97..9b717216aa6 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -105,23 +105,6 @@ public Control SettingControl
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
public string InitAndQueryTime => InternationalizationManager.Instance.GetTranslation("plugin_init_time") + " " + PluginPair.Metadata.InitTime + "ms, " + InternationalizationManager.Instance.GetTranslation("plugin_query_time") + " " + PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
- public bool GlobalSearch
- {
- get => PluginPair.Metadata.ActionKeywords.Contains(Query.GlobalPluginWildcardSign);
- set
- {
- if (value)
- {
- App.API.AddActionKeyword(PluginPair.Metadata.ID, Query.GlobalPluginWildcardSign);
- }
- else
- {
- App.API.RemoveActionKeyword(PluginPair.Metadata.ID, Query.GlobalPluginWildcardSign);
- }
- OnPropertyChanged();
- OnActionKeywordsChanged();
- }
- }
public int Priority => PluginPair.Metadata.Priority;
public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; }
From fb9980e90a87add97d37d6a48bdf276e171e094c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 10:39:57 +0800
Subject: [PATCH 0346/1335] Upgrade nuget packages
---
Flow.Launcher/Flow.Launcher.csproj | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index c2e51584409..cc43bd2ac7d 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -91,9 +91,8 @@
-
-
-
+
+
all
@@ -105,7 +104,7 @@
-
+
From a153bb6baef1fe0a5c9ab5e4bfe25ed771ceed44 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 12:38:45 +0800
Subject: [PATCH 0347/1335] Test Jack251970.TaskScheduler package
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index cc43bd2ac7d..d77847bef96 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From 406b1961b2b837512bec4ce74c0cc7ea4b07e7ea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 13:25:21 +0800
Subject: [PATCH 0348/1335] Test updated Jack251970.TaskScheduler package
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index d77847bef96..33d13614f8a 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From c9f2a1427d0e92e4b63fefbc995c232e35ba9bbb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 13:48:32 +0800
Subject: [PATCH 0349/1335] Remove useless usings
---
Flow.Launcher/PublicAPIInstance.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 248688f7681..f7c70adff1a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -26,7 +26,6 @@
using System.Diagnostics;
using System.Collections.Specialized;
using Flow.Launcher.Core;
-using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
From 64f02c3fd7ee40f673c36aabee44f67a7311899b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 18:22:56 +0800
Subject: [PATCH 0350/1335] Redesign settings panel for sys plugin & Improve
design styles
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 ++
.../Controls/InstalledPluginDisplayKeyword.xaml | 6 +++---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 9 +++++++--
.../Views/CalculatorSettings.xaml | 4 ++--
Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml | 4 ++--
5 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 2a4b22bf395..b1888e574fc 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -30,6 +30,8 @@ public class JsonRPCPluginSettings
private JsonStorage> _storage;
// maybe move to resource?
+ private static Thickness settingPanelMargin1 = (Thickness)System.Windows.Application.Current.FindResource("SettingPanelMargin");
+
private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
private static readonly Thickness settingPanelMargin = new(0, 0, 0, 0);
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index 3944f6b75e0..d2d2afa095a 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -20,7 +20,7 @@
Visibility="{Binding ActionKeywordsVisibility}">
- 70,0,18,0
+ 70,9,18,9
+ 9,0,0,0
+ 0,0,9,0
+ 0,9,0,9
+
9,9,0,9
0,9,9,9
- 9,9,9,9
+ 9,0,0,9
+ 0,0,9,9
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
index ceee3897c18..d7bd11b83c4 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
@@ -54,7 +54,7 @@
@@ -62,7 +62,7 @@
x:Name="MaxDecimalPlaces"
Grid.Row="1"
Grid.Column="1"
- Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
+ Margin="{StaticResource SettingPanelItemRightBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding MaxDecimalPlacesRange}"
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
index f806900dedc..95fdd78d4b8 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
@@ -7,11 +7,11 @@
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
-
+
Date: Thu, 27 Feb 2025 18:27:43 +0800
Subject: [PATCH 0351/1335] Improve design for inner settings panel
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 2 --
.../Views/CalculatorSettings.xaml | 4 ++--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index e2a3bda375e..3cd1f5c1c70 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5594,6 +5594,4 @@
9,9,0,9
0,9,9,9
- 9,0,0,9
- 0,0,9,9
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
index d7bd11b83c4..ceee3897c18 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
@@ -54,7 +54,7 @@
@@ -62,7 +62,7 @@
x:Name="MaxDecimalPlaces"
Grid.Row="1"
Grid.Column="1"
- Margin="{StaticResource SettingPanelItemRightBottomMargin}"
+ Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding MaxDecimalPlacesRange}"
From 65fb98fe84af625b80817ec022b83b5b89e747b9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 19:01:32 +0800
Subject: [PATCH 0352/1335] Redesgin settings panel for shell plugin
---
.../ShellSetting.xaml | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
index 8a3b7f11533..32f2ad69c1a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/ShellSetting.xaml
@@ -8,7 +8,7 @@
d:DesignWidth="300"
Loaded="CMDSetting_OnLoaded"
mc:Ignorable="d">
-
+
@@ -21,37 +21,37 @@
CMD
PowerShell
@@ -61,11 +61,11 @@
From 6d4919f15e1d32de70393044fc7d4ac853ee9a50 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 19:56:31 +0800
Subject: [PATCH 0353/1335] Redesgin settings panel for plugins manager plugin
---
.../Views/PluginsManagerSettings.xaml | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
index f93f7799aba..5b767eb53c8 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
@@ -7,7 +7,7 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
-
+
@@ -15,13 +15,12 @@
From ac956bccef6bfb34de21fbe3ca3817f0e3f2c238 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 20:51:16 +0800
Subject: [PATCH 0354/1335] Redesgin settings panel for program plugin
---
.../Resources/CustomControlTemplate.xaml | 8 +++
.../Views/ProgramSetting.xaml | 68 +++++++------------
2 files changed, 33 insertions(+), 43 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index 3cd1f5c1c70..e57a293208a 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5588,10 +5588,18 @@
70,9,18,9
+
9,0,0,0
0,0,9,0
0,9,0,9
9,9,0,9
0,9,9,9
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index 973ac9f60af..353056ad077 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -10,124 +10,108 @@
-
+
-
+
-
-
-
+
+
-
+
@@ -140,12 +124,13 @@
x:Name="progressBarIndexing"
Width="80"
Height="20"
+ Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
IsIndeterminate="True"
Maximum="100"
Minimum="0" />
@@ -154,7 +139,7 @@
-
+
From 16b45d38be7584c7ff60ea7b7e23d8923ef3e07f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 20:58:06 +0800
Subject: [PATCH 0355/1335] Redesgin settings panel for bookmark plugin
---
.../Views/SettingsControl.xaml | 146 ++++++++++--------
1 file changed, 78 insertions(+), 68 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index 014deff03b6..6183fa1b2de 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -8,77 +8,87 @@
d:DesignWidth="500"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
-
+
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ MinWidth="130"
+ Click="NewCustomBrowser"
+ Content="{DynamicResource flowlauncher_plugin_browserbookmark_addBrowserBookmark}" />
+
+
+
+
+
+
From 975d6eefddc79bb441fdc12e508839bd20491b10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 27 Feb 2025 21:20:29 +0800
Subject: [PATCH 0356/1335] Redesgin settings panel for websearch plugin
---
.../SettingsControl.xaml | 82 +++++++++----------
1 file changed, 39 insertions(+), 43 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml
index 4cf3bed405f..5c782d044e8 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml
@@ -35,16 +35,17 @@
-
+
+
@@ -69,11 +70,11 @@
+ Header="{DynamicResource flowlauncher_plugin_websearch_action_keyword}" />
+ Header="{DynamicResource flowlauncher_plugin_websearch_title}" />
@@ -97,57 +98,52 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From ca7999454395756742e41060f05e0ef102d32ec0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 09:25:20 +0800
Subject: [PATCH 0357/1335] Change to HideActionKeywordPanel
---
Flow.Launcher.Plugin/PluginMetadata.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
Plugins/Flow.Launcher.Plugin.Explorer/plugin.json | 2 +-
Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Plugin/PluginMetadata.cs b/Flow.Launcher.Plugin/PluginMetadata.cs
index 14a7202038b..91256298bc6 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -34,7 +34,7 @@ internal set
public List ActionKeywords { get; set; }
- public bool AllowModifyActionKeywords { get; set; } = true;
+ public bool HideActionKeywordPanel { get; set; }
public string IcoPath { get; set;}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 9b717216aa6..c71c3b0884d 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -99,7 +99,7 @@ public Control SettingControl
: null;
private ImageSource _image = ImageLoader.MissingImage;
- public Visibility ActionKeywordsVisibility => PluginPair.Metadata.AllowModifyActionKeywords ? Visibility.Visible : Visibility.Collapsed;
+ public Visibility ActionKeywordsVisibility => PluginPair.Metadata.HideActionKeywordPanel ? Visibility.Collapsed : Visibility.Visible;
public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
index 7b067f5761e..d2440ab614e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/plugin.json
@@ -7,7 +7,7 @@
"*",
"*"
],
- "AllowModifyActionKeywords": false,
+ "HideActionKeywordPanel": true,
"Name": "Explorer",
"Description": "Find and manage files and folders via Windows Search or Everything",
"Author": "Jeremy Wu",
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index 1fc9967fcdb..20f6def705e 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -23,7 +23,7 @@
"yahoo",
"bd"
],
- "AllowModifyActionKeywords": false,
+ "HideActionKeywordPanel": true,
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
From 912c9917b3137a92840910aa98efd7d5e9a03bbb Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 28 Feb 2025 12:19:19 +0900
Subject: [PATCH 0358/1335] Fix theme.cs
---
Flow.Launcher.Core/Resource/Theme.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 2050bd3a405..34bbd8e6884 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -149,7 +149,7 @@ public void SetBlurForWindow()
{
//SetWindowAccent();
- var dict = GetThemeResourceDictionary(Settings.Theme);
+ var dict = GetThemeResourceDictionary(_settings.Theme);
if (dict == null)
return;
@@ -183,7 +183,7 @@ public void SetBlurForWindow()
// WindowBorderStyle에서 Background 색상 가져오는 함수
private Color GetWindowBorderStyleBackground()
{
- var Resources = GetThemeResourceDictionary(Settings.Theme);
+ var Resources = GetThemeResourceDictionary(_settings.Theme);
var windowBorderStyle = (Style)Resources["WindowBorderStyle"];
var backgroundSetter = windowBorderStyle.Setters
@@ -225,7 +225,7 @@ private Color GetWindowBorderStyleBackground()
public void ThemeModeColor(string Mode)
{
- var dict = GetThemeResourceDictionary(Settings.Theme);
+ var dict = GetThemeResourceDictionary(_settings.Theme);
Color lightBG;
Color darkBG;
@@ -256,7 +256,7 @@ public void ThemeModeColor(string Mode)
if (Mode == "Auto")
{
int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
- string colorScheme = Settings.ColorScheme;
+ string colorScheme = _settings.ColorScheme;
bool isDarkMode = themeValue == 0; // 0이면 다크 모드
if (colorScheme == "System")
{
From 5c48acad8922d9367bce917246a5de5d067e98ea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 11:26:14 +0800
Subject: [PATCH 0359/1335] Add loading api functions for all plugins
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 10 ++++++++++
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 10 ++++++++++
2 files changed, 20 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index e0a0434a203..8df2ce9ed9e 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -175,5 +175,15 @@ public void BackToQueryResults()
{
_api.BackToQueryResults();
}
+
+ public void StartLoadingBar()
+ {
+ _api.StartLoadingBar();
+ }
+
+ public void StopLoadingBar()
+ {
+ _api.StopLoadingBar();
+ }
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 07fc378c3c4..fd96c82c484 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -335,5 +335,15 @@ public interface IPublicAPI
/// When user closes the progress box manually by button or esc key, this action will be called.
/// A progress box interface.
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
+
+ ///
+ /// Start the loading bar in main window
+ ///
+ public void StartLoadingBar();
+
+ ///
+ /// Stop the loading bar in main window
+ ///
+ public void StopLoadingBar();
}
}
From 9ec8681ab8aebfcc8f177a2604d66dac39125991 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 14:54:24 +0800
Subject: [PATCH 0360/1335] Remove useless project reference
---
.../Flow.Launcher.Plugin.Calculator.csproj | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
index 92719fa54c2..9cdef365d04 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj
@@ -43,7 +43,6 @@
-
From 9dbc174994e77124c2b42b2864ab6ab1f4d8ab10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 15:34:59 +0800
Subject: [PATCH 0361/1335] Add cache size management & Add error handling
---
.../Helper/WallpaperPathRetrieval.cs | 69 ++++++++++++-------
1 file changed, 45 insertions(+), 24 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 9f66a270c98..eedc78ecad1 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -17,6 +17,7 @@ public static class WallpaperPathRetrieval
private static readonly int MAX_PATH = 260;
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
+ private const int MaxCacheSize = 3;
public static Brush GetWallpaperBrush()
{
@@ -26,35 +27,55 @@ public static Brush GetWallpaperBrush()
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}
- var wallpaperPath = GetWallpaperPath();
- if (wallpaperPath is not null && File.Exists(wallpaperPath))
+ try
{
- // Since the wallpaper file name can be the same (TranscodedWallpaper),
- // we need to add the last modified date to differentiate them
- var dateModified = File.GetLastWriteTime(wallpaperPath);
- wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
- if (cachedWallpaper != null)
+ var wallpaperPath = GetWallpaperPath();
+ if (wallpaperPath is not null && File.Exists(wallpaperPath))
{
- return cachedWallpaper;
+ // Since the wallpaper file name can be the same (TranscodedWallpaper),
+ // we need to add the last modified date to differentiate them
+ var dateModified = File.GetLastWriteTime(wallpaperPath);
+ wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
+ if (cachedWallpaper != null)
+ {
+ return cachedWallpaper;
+ }
+
+ // We should not dispose the memory stream since the bitmap is still in use
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = memStream;
+ bitmap.DecodePixelWidth = 800;
+ bitmap.DecodePixelHeight = 600;
+ bitmap.EndInit();
+ bitmap.Freeze(); // Make the bitmap thread-safe
+ var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ wallpaperBrush.Freeze(); // Make the brush thread-safe
+
+ // Manage cache size
+ if (wallpaperCache.Count >= MaxCacheSize)
+ {
+ // Remove the oldest wallpaper from the cache
+ var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
+ if (oldestCache != default)
+ {
+ wallpaperCache.Remove(oldestCache);
+ }
+ }
+
+ wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ return wallpaperBrush;
}
- // We should not dispose the memory stream since the bitmap is still in use
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.DecodePixelWidth = 800;
- bitmap.DecodePixelHeight = 600;
- bitmap.EndInit();
- bitmap.Freeze(); // Make the bitmap thread-safe
- var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
- wallpaperBrush.Freeze(); // Make the brush thread-safe
- wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
- return wallpaperBrush;
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+ catch (Exception ex)
+ {
+ App.API.LogException(nameof(WallpaperPathRetrieval), "Error retrieving wallpaper", ex);
+ return new SolidColorBrush(Colors.Transparent);
}
-
- var wallpaperColor = GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
}
private static unsafe string GetWallpaperPath()
From c06042f96bee6f65fe1b4b761643a2e2bd495978 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 17:03:53 +0800
Subject: [PATCH 0362/1335] Fix API instance create twice issue & Make
PluginManager.API private
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 4 +++-
Flow.Launcher/MainWindow.xaml.cs | 2 +-
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 5 ++---
.../SettingPages/Views/SettingsPanePluginStore.xaml.cs | 3 +--
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 8 ++++----
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 6e7b5ec6002..09711051e24 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -29,7 +29,9 @@ public static class PluginManager
public static readonly HashSet GlobalPlugins = new();
public static readonly Dictionary NonGlobalPlugins = new();
- public static IPublicAPI API { get; private set; } = Ioc.Default.GetRequiredService();
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
private static PluginsSettings Settings;
private static List _metadatas;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 41dc68fd924..3f1bae090a3 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -438,7 +438,7 @@ private void CheckFirstLaunch()
if (_settings.FirstLaunch)
{
_settings.FirstLaunch = false;
- PluginManager.API.SaveAppAllSettings();
+ App.API.SaveAppAllSettings();
OpenWelcomeWindow();
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index cb434f399f0..ade65028472 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -6,7 +6,6 @@
using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
-using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -77,7 +76,7 @@ private void AskClearLogFolderConfirmation()
[RelayCommand]
private void OpenSettingsFolder()
{
- PluginManager.API.OpenDirectory(Path.Combine(DataLocation.DataDirectory(), Constant.Settings));
+ App.API.OpenDirectory(Path.Combine(DataLocation.DataDirectory(), Constant.Settings));
}
[RelayCommand]
@@ -85,7 +84,7 @@ private void OpenParentOfSettingsFolder(object parameter)
{
string settingsFolderPath = Path.Combine(DataLocation.DataDirectory(), Constant.Settings);
string parentFolderPath = Path.GetDirectoryName(settingsFolderPath);
- PluginManager.API.OpenDirectory(parentFolderPath);
+ App.API.OpenDirectory(parentFolderPath);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index dfb4a7eaf6c..db476331908 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -3,7 +3,6 @@
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
-using Flow.Launcher.Core.Plugin;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
@@ -49,7 +48,7 @@ private void SettingsPanePlugins_OnKeyDown(object sender, KeyEventArgs e)
private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
- PluginManager.API.OpenUrl(e.Uri.AbsoluteUri);
+ App.API.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 650a276109d..6b0144a0384 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -442,7 +442,7 @@ private void OpenSetting()
[RelayCommand]
private void SelectHelp()
{
- PluginManager.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
+ App.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
}
[RelayCommand]
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index bae9292bff7..46f8e00a222 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -134,20 +134,20 @@ private void OpenPluginDirectory()
{
var directory = PluginPair.Metadata.PluginDirectory;
if (!string.IsNullOrEmpty(directory))
- PluginManager.API.OpenDirectory(directory);
+ App.API.OpenDirectory(directory);
}
[RelayCommand]
private void OpenSourceCodeLink()
{
- PluginManager.API.OpenUrl(PluginPair.Metadata.Website);
+ App.API.OpenUrl(PluginPair.Metadata.Website);
}
[RelayCommand]
private void OpenDeletePluginWindow()
{
- PluginManager.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
- PluginManager.API.ShowMainWindow();
+ App.API.ChangeQuery($"{PluginManagerActionKeyword} uninstall {PluginPair.Metadata.Name}".Trim(), true);
+ App.API.ShowMainWindow();
}
public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
From d8c547f7ef3a640b613778713508a9b111c90ab6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 18:10:58 +0800
Subject: [PATCH 0363/1335] Improve code quality
---
Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index eedc78ecad1..a3bd83a97a6 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -15,9 +15,9 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
+ private static readonly int MAX_CACHE_SIZE = 3;
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
- private const int MaxCacheSize = 3;
public static Brush GetWallpaperBrush()
{
@@ -54,7 +54,7 @@ public static Brush GetWallpaperBrush()
wallpaperBrush.Freeze(); // Make the brush thread-safe
// Manage cache size
- if (wallpaperCache.Count >= MaxCacheSize)
+ if (wallpaperCache.Count >= MAX_CACHE_SIZE)
{
// Remove the oldest wallpaper from the cache
var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
From 330a11a843e5f6b41d582ca9aeb2b6b90d1b9a95 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 21:57:27 +0800
Subject: [PATCH 0364/1335] Adjust margin & Make title vertically center in
program plugin
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 10 +++++-----
.../Views/ProgramSetting.xaml | 2 ++
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index e57a293208a..7d33047c789 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5587,17 +5587,17 @@
- 70,9,18,9
+ 70,13.5,18,13.5
9,0,0,0
0,0,9,0
- 0,9,0,9
+ 0,4.5,0,4.5
- 9,9,0,9
- 0,9,9,9
+ 9,4.5,0,4.5
+ 0,4.5,9,4.5
From 51a9999a649c8f13e72b9daad96dee2b571b1913 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Feb 2025 22:56:51 +0800
Subject: [PATCH 0366/1335] Improve code quality & Add seperator type
---
.../Plugin/JsonRPCPluginSettings.cs | 463 ++++++++----------
1 file changed, 217 insertions(+), 246 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index b1888e574fc..bca7f8d9710 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -30,16 +30,9 @@ public class JsonRPCPluginSettings
private JsonStorage> _storage;
// maybe move to resource?
- private static Thickness settingPanelMargin1 = (Thickness)System.Windows.Application.Current.FindResource("SettingPanelMargin");
-
private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
- private static readonly Thickness settingPanelMargin = new(0, 0, 0, 0);
- private static readonly Thickness settingTextBlockMargin = new(70, 9, 18, 9);
- private static readonly Thickness settingLabelPanelMargin = new(70, 9, 18, 9);
- private static readonly Thickness settingLabelMargin = new(0, 0, 0, 0);
- private static readonly Thickness settingDescMargin = new(0, 2, 0, 0);
- private static readonly Thickness settingSepMargin = new(0, 0, 0, 2);
+ private static readonly Thickness settingPanelMargin = (Thickness)System.Windows.Application.Current.FindResource("SettingPanelMargin");
public async Task InitializeAsync()
{
@@ -51,9 +44,10 @@ public async Task InitializeAsync()
return;
}
- foreach (var (type, attributes) in Configuration.Body)
+ foreach (var (_, attributes) in Configuration.Body)
{
- if (attributes.Name == null)
+ // Skip if the setting does not have attributes or name
+ if (attributes?.Name == null)
{
continue;
}
@@ -65,7 +59,6 @@ public async Task InitializeAsync()
}
}
-
public void UpdateSettings(IReadOnlyDictionary settings)
{
if (settings == null || settings.Count == 0)
@@ -113,298 +106,249 @@ public void Save()
public Control CreateSettingPanel()
{
- if (Settings == null || Settings.Count == 0)
+ // If there are no settings or the settings are empty, return null
+ if (Settings == null || Settings.IsEmpty)
+ {
return null;
+ }
- var settingWindow = new UserControl();
+ // Create main grid
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
+ mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
+ {
+ Width = new GridLength(70, GridUnitType.Star) // TODO: Auto
+ });
+ mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
+ {
+ Width = new GridLength(30, GridUnitType.Star) // TODO: Auto
+ });
- ColumnDefinition gridCol1 = new ColumnDefinition();
- ColumnDefinition gridCol2 = new ColumnDefinition();
-
- gridCol1.Width = new GridLength(70, GridUnitType.Star);
- gridCol2.Width = new GridLength(30, GridUnitType.Star);
- mainPanel.ColumnDefinitions.Add(gridCol1);
- mainPanel.ColumnDefinitions.Add(gridCol2);
- settingWindow.Content = mainPanel;
+ // Iterate over each setting and create one row for it
int rowCount = 0;
-
- foreach (var (type, attribute) in Configuration.Body)
+ foreach (var (type, attributes) in Configuration.Body)
{
- Separator sep = new Separator();
- sep.VerticalAlignment = VerticalAlignment.Top;
- sep.Margin = settingSepMargin;
- sep.SetResourceReference(Separator.BackgroundProperty, "Color03B"); /* for theme change */
- var panel = new StackPanel
- {
- Orientation = Orientation.Vertical,
- VerticalAlignment = VerticalAlignment.Center,
- Margin = settingLabelPanelMargin
- };
-
- RowDefinition gridRow = new RowDefinition();
- mainPanel.RowDefinitions.Add(gridRow);
- var name = new TextBlock()
- {
- Text = attribute.Label,
- VerticalAlignment = VerticalAlignment.Center,
- Margin = settingLabelMargin,
- TextWrapping = TextWrapping.WrapWithOverflow
- };
-
- var desc = new TextBlock()
+ // Skip if the setting does not have attributes or name
+ if (attributes?.Name == null)
{
- Text = attribute.Description,
- FontSize = 12,
- VerticalAlignment = VerticalAlignment.Center,
- Margin = settingDescMargin,
- TextWrapping = TextWrapping.WrapWithOverflow
- };
-
- desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B");
-
- if (attribute.Description == null) /* if no description, hide */
- desc.Visibility = Visibility.Collapsed;
-
-
- if (type != "textBlock") /* if textBlock, hide desc */
- {
- panel.Children.Add(name);
- panel.Children.Add(desc);
+ continue;
}
+ // Add a new row to the main grid
+ mainPanel.RowDefinitions.Add(new RowDefinition());
- Grid.SetColumn(panel, 0);
- Grid.SetRow(panel, rowCount);
-
+ // State controls for column 0 and 1
+ StackPanel panel = null;
FrameworkElement contentControl;
- switch (type)
+ // If the type is textBlock or seperator, we do not need to create a panel
+ if (type != "textBlock" && type != "seperator")
{
- case "textBlock":
+ // Create a panel to hold the label and description
+ panel = new StackPanel
{
- contentControl = new TextBlock
+ Orientation = Orientation.Vertical,
+ VerticalAlignment = VerticalAlignment.Center
+ };
+
+ // Create a text block for name
+ var name = new TextBlock()
+ {
+ Text = attributes.Label,
+ VerticalAlignment = VerticalAlignment.Center,
+ TextWrapping = TextWrapping.WrapWithOverflow
+ };
+
+ // Create a text block for description
+ TextBlock desc = null;
+ if (attributes.Description != null)
+ {
+ desc = new TextBlock()
{
- Text = attribute.Description.Replace("\\r\\n", "\r\n"),
- Margin = settingTextBlockMargin,
- Padding = new Thickness(0, 0, 0, 0),
- HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
- TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
+ Text = attributes.Description,
+ FontSize = 12,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = new(0, 2, 0, 0), // TODO: Use resource
+ TextWrapping = TextWrapping.WrapWithOverflow
};
- Grid.SetColumn(contentControl, 0);
- Grid.SetColumnSpan(contentControl, 2);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
-
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
-
- break;
+ desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); // for theme change
}
- case "input":
+
+ // Add the name and description to the panel
+ panel.Children.Add(name);
+ if (desc != null)
{
- var textBox = new TextBox()
+ panel.Children.Add(desc);
+ }
+ }
+
+ switch (type)
+ {
+ case "textBlock":
{
- Text = Settings[attribute.Name] as string ?? string.Empty,
- Margin = settingControlMargin,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
- ToolTip = attribute.Description
- };
+ contentControl = new TextBlock
+ {
+ Text = attributes.Description.Replace("\\r\\n", "\r\n"),
+ Padding = new Thickness(0, 0, 0, 0),
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
+ TextAlignment = TextAlignment.Left,
+ TextWrapping = TextWrapping.Wrap
+ };
- textBox.TextChanged += (_, _) =>
+ break;
+ }
+ case "input":
{
- Settings[attribute.Name] = textBox.Text;
- };
+ var textBox = new TextBox()
+ {
+ Text = Settings[attributes.Name] as string ?? string.Empty,
+ Margin = settingControlMargin,
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ ToolTip = attributes.Description
+ };
- contentControl = textBox;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
+ textBox.TextChanged += (_, _) =>
+ {
+ Settings[attributes.Name] = textBox.Text;
+ };
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ contentControl = textBox;
- break;
- }
+ break;
+ }
case "inputWithFileBtn":
case "inputWithFolderBtn":
- {
- var textBox = new TextBox()
- {
- Margin = new Thickness(10, 0, 0, 0),
- Text = Settings[attribute.Name] as string ?? string.Empty,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
- ToolTip = attribute.Description
- };
-
- textBox.TextChanged += (_, _) =>
- {
- Settings[attribute.Name] = textBox.Text;
- };
-
- var Btn = new System.Windows.Controls.Button()
{
- Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
- };
+ var textBox = new TextBox()
+ {
+ Margin = new Thickness(10, 0, 0, 0),
+ Text = Settings[attributes.Name] as string ?? string.Empty,
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ ToolTip = attributes.Description
+ };
- Btn.Click += (_, _) =>
- {
- using CommonDialog dialog = type switch
+ textBox.TextChanged += (_, _) =>
{
- "inputWithFolderBtn" => new FolderBrowserDialog(),
- _ => new OpenFileDialog(),
+ Settings[attributes.Name] = textBox.Text;
};
- if (dialog.ShowDialog() != DialogResult.OK) return;
- var path = dialog switch
+ var Btn = new System.Windows.Controls.Button()
{
- FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
- OpenFileDialog fileDialog => fileDialog.FileName,
+ Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
};
- textBox.Text = path;
- Settings[attribute.Name] = path;
- };
- var dockPanel = new DockPanel() { Margin = settingControlMargin };
+ Btn.Click += (_, _) =>
+ {
+ using CommonDialog dialog = type switch
+ {
+ "inputWithFolderBtn" => new FolderBrowserDialog(),
+ _ => new OpenFileDialog(),
+ };
+ if (dialog.ShowDialog() != DialogResult.OK) return;
+
+ var path = dialog switch
+ {
+ FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
+ OpenFileDialog fileDialog => fileDialog.FileName,
+ };
+ textBox.Text = path;
+ Settings[attributes.Name] = path;
+ };
- DockPanel.SetDock(Btn, Dock.Right);
- dockPanel.Children.Add(Btn);
- dockPanel.Children.Add(textBox);
- contentControl = dockPanel;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
+ var dockPanel = new DockPanel() { Margin = settingControlMargin };
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ DockPanel.SetDock(Btn, Dock.Right);
+ dockPanel.Children.Add(Btn);
+ dockPanel.Children.Add(textBox);
+ contentControl = dockPanel;
- break;
- }
+ break;
+ }
case "textarea":
- {
- var textBox = new TextBox()
- {
- Height = 120,
- Margin = settingControlMargin,
- VerticalAlignment = VerticalAlignment.Center,
- TextWrapping = TextWrapping.WrapWithOverflow,
- AcceptsReturn = true,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
- Text = Settings[attribute.Name] as string ?? string.Empty,
- ToolTip = attribute.Description
- };
-
- textBox.TextChanged += (sender, _) =>
{
- Settings[attribute.Name] = ((TextBox)sender).Text;
- };
+ var textBox = new TextBox()
+ {
+ Height = 120,
+ Margin = settingControlMargin,
+ VerticalAlignment = VerticalAlignment.Center,
+ TextWrapping = TextWrapping.WrapWithOverflow,
+ AcceptsReturn = true,
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ Text = Settings[attributes.Name] as string ?? string.Empty,
+ ToolTip = attributes.Description
+ };
- contentControl = textBox;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
+ textBox.TextChanged += (sender, _) =>
+ {
+ Settings[attributes.Name] = ((TextBox)sender).Text;
+ };
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ contentControl = textBox;
- break;
- }
+ break;
+ }
case "passwordBox":
- {
- var passwordBox = new PasswordBox()
{
- Margin = settingControlMargin,
- Password = Settings[attribute.Name] as string ?? string.Empty,
- PasswordChar = attribute.passwordChar == default ? '*' : attribute.passwordChar,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
- ToolTip = attribute.Description
- };
-
- passwordBox.PasswordChanged += (sender, _) =>
- {
- Settings[attribute.Name] = ((PasswordBox)sender).Password;
- };
+ var passwordBox = new PasswordBox()
+ {
+ Margin = settingControlMargin,
+ Password = Settings[attributes.Name] as string ?? string.Empty,
+ PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ ToolTip = attributes.Description
+ };
- contentControl = passwordBox;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
+ passwordBox.PasswordChanged += (sender, _) =>
+ {
+ Settings[attributes.Name] = ((PasswordBox)sender).Password;
+ };
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ contentControl = passwordBox;
- break;
- }
+ break;
+ }
case "dropdown":
- {
- var comboBox = new System.Windows.Controls.ComboBox()
{
- ItemsSource = attribute.Options,
- SelectedItem = Settings[attribute.Name],
- Margin = settingControlMargin,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
- ToolTip = attribute.Description
- };
-
- comboBox.SelectionChanged += (sender, _) =>
- {
- Settings[attribute.Name] = (string)((System.Windows.Controls.ComboBox)sender).SelectedItem;
- };
+ var comboBox = new ComboBox()
+ {
+ ItemsSource = attributes.Options,
+ SelectedItem = Settings[attributes.Name],
+ Margin = settingControlMargin,
+ HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
+ ToolTip = attributes.Description
+ };
- contentControl = comboBox;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
+ comboBox.SelectionChanged += (sender, _) =>
+ {
+ Settings[attributes.Name] = (string)((ComboBox)sender).SelectedItem;
+ };
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ contentControl = comboBox;
- break;
- }
+ break;
+ }
case "checkbox":
var checkBox = new CheckBox
{
IsChecked =
- Settings[attribute.Name] is bool isChecked
+ Settings[attributes.Name] is bool isChecked
? isChecked
- : bool.Parse(attribute.DefaultValue),
+ : bool.Parse(attributes.DefaultValue),
Margin = settingCheckboxMargin,
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
- ToolTip = attribute.Description
+ ToolTip = attributes.Description
};
checkBox.Click += (sender, _) =>
{
- Settings[attribute.Name] = ((CheckBox)sender).IsChecked;
+ Settings[attributes.Name] = ((CheckBox)sender).IsChecked;
};
contentControl = checkBox;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
-
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
break;
case "hyperlink":
- var hyperlink = new Hyperlink { ToolTip = attribute.Description, NavigateUri = attribute.url };
+ var hyperlink = new Hyperlink { ToolTip = attributes.Description, NavigateUri = attributes.url };
var linkbtn = new System.Windows.Controls.Button
{
@@ -412,32 +356,59 @@ Settings[attribute.Name] is bool isChecked
Margin = settingControlMargin
};
- linkbtn.Content = attribute.urlLabel;
+ linkbtn.Content = attributes.urlLabel;
contentControl = linkbtn;
- Grid.SetColumn(contentControl, 1);
- Grid.SetRow(contentControl, rowCount);
- if (rowCount != 0)
- mainPanel.Children.Add(sep);
- Grid.SetRow(sep, rowCount);
- Grid.SetColumn(sep, 0);
- Grid.SetColumnSpan(sep, 2);
+ break;
+ case "seperator": // TODO: Support seperator
+ // TODO: Use style for Seperator
+ contentControl = new Separator
+ {
+ VerticalAlignment = VerticalAlignment.Top,
+ Margin = new(-70, 13.5, -18, 13.5),
+ Height = 1
+ };
+ contentControl.SetResourceReference(Separator.BackgroundProperty, "Color03B");
break;
default:
continue;
}
- if (type != "textBlock")
- SettingControls[attribute.Name] = contentControl;
+ // If type is textBlock or seperator, we just add the content control to the main grid
+ if (panel == null)
+ {
+ // Add the content control to the column 0, row rowCount and columnSpan 2 of the main grid
+ mainPanel.Children.Add(contentControl);
+ Grid.SetColumn(contentControl, 0);
+ Grid.SetColumnSpan(contentControl, 2);
+ Grid.SetRow(contentControl, rowCount);
+ }
+ else
+ {
+ // Add the panel to the column 0 and row rowCount of the main grid
+ mainPanel.Children.Add(panel);
+ Grid.SetColumn(panel, 0);
+ Grid.SetRow(panel, rowCount);
+
+ // Add the content control to the column 1 and row rowCount of the main grid
+ mainPanel.Children.Add(contentControl);
+ Grid.SetColumn(contentControl, 1);
+ Grid.SetRow(contentControl, rowCount);
+
+ // Add into SettingControls for later use if need
+ SettingControls[attributes.Name] = contentControl;
+ }
- mainPanel.Children.Add(panel);
- mainPanel.Children.Add(contentControl);
rowCount++;
}
- return settingWindow;
+ // Wrap the main grid in a user control
+ return new UserControl()
+ {
+ Content = mainPanel
+ };
}
}
}
From f283105182c69dbae71e8796c03971e9d59a96f1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 10:08:04 +0800
Subject: [PATCH 0367/1335] Enable nullable & Improve code quality
---
.../Plugin/JsonRPCPluginSettings.cs | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index bca7f8d9710..cf09d96552c 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -14,6 +14,8 @@
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
+#nullable enable
+
namespace Flow.Launcher.Core.Plugin
{
public class JsonRPCPluginSettings
@@ -24,12 +26,12 @@ public class JsonRPCPluginSettings
public Dictionary SettingControls { get; } = new();
public IReadOnlyDictionary Inner => Settings;
- protected ConcurrentDictionary Settings { get; set; }
+ protected ConcurrentDictionary Settings { get; set; } = null!;
public required IPublicAPI API { get; init; }
- private JsonStorage> _storage;
+ private JsonStorage> _storage = null!;
- // maybe move to resource?
+ // TODO: Move to resource
private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
private static readonly Thickness settingPanelMargin = (Thickness)System.Windows.Application.Current.FindResource("SettingPanelMargin");
@@ -104,10 +106,10 @@ public void Save()
_storage.Save();
}
- public Control CreateSettingPanel()
+ public Control? CreateSettingPanel()
{
// If there are no settings or the settings are empty, return null
- if (Settings == null || Settings.IsEmpty)
+ if (Configuration == null || Settings == null || Settings.IsEmpty)
{
return null;
}
@@ -124,7 +126,7 @@ public Control CreateSettingPanel()
});
// Iterate over each setting and create one row for it
- int rowCount = 0;
+ var rowCount = 0;
foreach (var (type, attributes) in Configuration.Body)
{
// Skip if the setting does not have attributes or name
@@ -137,7 +139,7 @@ public Control CreateSettingPanel()
mainPanel.RowDefinitions.Add(new RowDefinition());
// State controls for column 0 and 1
- StackPanel panel = null;
+ StackPanel? panel = null;
FrameworkElement contentControl;
// If the type is textBlock or seperator, we do not need to create a panel
@@ -151,6 +153,7 @@ public Control CreateSettingPanel()
};
// Create a text block for name
+ // TODO: Move to resource
var name = new TextBlock()
{
Text = attributes.Label,
@@ -159,9 +162,10 @@ public Control CreateSettingPanel()
};
// Create a text block for description
- TextBlock desc = null;
+ TextBlock? desc = null;
if (attributes.Description != null)
{
+ // TODO: Move to resource
desc = new TextBlock()
{
Text = attributes.Description,
@@ -170,7 +174,6 @@ public Control CreateSettingPanel()
Margin = new(0, 2, 0, 0), // TODO: Use resource
TextWrapping = TextWrapping.WrapWithOverflow
};
-
desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); // for theme change
}
@@ -188,7 +191,7 @@ public Control CreateSettingPanel()
{
contentControl = new TextBlock
{
- Text = attributes.Description.Replace("\\r\\n", "\r\n"),
+ Text = attributes.Description?.Replace("\\r\\n", "\r\n") ?? string.Empty,
Padding = new Thickness(0, 0, 0, 0),
HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
TextAlignment = TextAlignment.Left,
@@ -250,6 +253,7 @@ public Control CreateSettingPanel()
{
FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
OpenFileDialog fileDialog => fileDialog.FileName,
+ _ => string.Empty
};
textBox.Text = path;
Settings[attributes.Name] = path;
@@ -341,7 +345,7 @@ Settings[attributes.Name] is bool isChecked
checkBox.Click += (sender, _) =>
{
- Settings[attributes.Name] = ((CheckBox)sender).IsChecked;
+ Settings[attributes.Name] = ((CheckBox)sender).IsChecked!;
};
contentControl = checkBox;
From 196a840991047f1286af3d9de9223cfb3a5ea779 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 10:21:17 +0800
Subject: [PATCH 0368/1335] Use auto height row & auto width column
---
.../Plugin/JsonRPCPluginSettings.cs | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index cf09d96552c..63c1c7f9d89 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -114,15 +114,15 @@ public void Save()
return null;
}
- // Create main grid
+ // Create main grid with two columns
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
- Width = new GridLength(70, GridUnitType.Star) // TODO: Auto
+ Width = new GridLength(0, GridUnitType.Auto)
});
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
- Width = new GridLength(30, GridUnitType.Star) // TODO: Auto
+ Width = new GridLength(0, GridUnitType.Auto)
});
// Iterate over each setting and create one row for it
@@ -136,7 +136,10 @@ public void Save()
}
// Add a new row to the main grid
- mainPanel.RowDefinitions.Add(new RowDefinition());
+ mainPanel.RowDefinitions.Add(new RowDefinition()
+ {
+ Height = new GridLength(0, GridUnitType.Auto)
+ });
// State controls for column 0 and 1
StackPanel? panel = null;
@@ -357,11 +360,10 @@ Settings[attributes.Name] is bool isChecked
var linkbtn = new System.Windows.Controls.Button
{
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
- Margin = settingControlMargin
+ Margin = settingControlMargin,
+ Content = attributes.urlLabel
};
- linkbtn.Content = attributes.urlLabel;
-
contentControl = linkbtn;
break;
From 43043291c9f39bf7cf1aa7ef877670b071288ad0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 10:33:08 +0800
Subject: [PATCH 0369/1335] Improve code quality
---
.../Plugin/JsonRPCPluginSettings.cs | 111 +++++++++---------
1 file changed, 58 insertions(+), 53 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 63c1c7f9d89..5b84c1781cc 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -4,15 +4,8 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
-using System.Windows.Forms;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
-using CheckBox = System.Windows.Controls.CheckBox;
-using ComboBox = System.Windows.Controls.ComboBox;
-using Control = System.Windows.Controls.Control;
-using Orientation = System.Windows.Controls.Orientation;
-using TextBox = System.Windows.Controls.TextBox;
-using UserControl = System.Windows.Controls.UserControl;
#nullable enable
@@ -34,7 +27,7 @@ public class JsonRPCPluginSettings
// TODO: Move to resource
private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
- private static readonly Thickness settingPanelMargin = (Thickness)System.Windows.Application.Current.FindResource("SettingPanelMargin");
+ private static readonly Thickness settingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
public async Task InitializeAsync()
{
@@ -64,7 +57,9 @@ public async Task InitializeAsync()
public void UpdateSettings(IReadOnlyDictionary settings)
{
if (settings == null || settings.Count == 0)
+ {
return;
+ }
foreach (var (key, value) in settings)
{
@@ -174,7 +169,7 @@ public void Save()
Text = attributes.Description,
FontSize = 12,
VerticalAlignment = VerticalAlignment.Center,
- Margin = new(0, 2, 0, 0), // TODO: Use resource
+ Margin = new(0, 2, 0, 0),
TextWrapping = TextWrapping.WrapWithOverflow
};
desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B"); // for theme change
@@ -196,7 +191,7 @@ public void Save()
{
Text = attributes.Description?.Replace("\\r\\n", "\r\n") ?? string.Empty,
Padding = new Thickness(0, 0, 0, 0),
- HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
+ HorizontalAlignment = HorizontalAlignment.Left,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
@@ -209,7 +204,7 @@ public void Save()
{
Text = Settings[attributes.Name] as string ?? string.Empty,
Margin = settingControlMargin,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -229,7 +224,7 @@ public void Save()
{
Margin = new Thickness(10, 0, 0, 0),
Text = Settings[attributes.Name] as string ?? string.Empty,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -238,25 +233,29 @@ public void Save()
Settings[attributes.Name] = textBox.Text;
};
- var Btn = new System.Windows.Controls.Button()
+ var Btn = new Button()
{
Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
};
Btn.Click += (_, _) =>
{
- using CommonDialog dialog = type switch
+ using System.Windows.Forms.CommonDialog dialog = type switch
{
- "inputWithFolderBtn" => new FolderBrowserDialog(),
- _ => new OpenFileDialog(),
+ "inputWithFolderBtn" => new System.Windows.Forms.FolderBrowserDialog(),
+ _ => new System.Windows.Forms.OpenFileDialog(),
};
- if (dialog.ShowDialog() != DialogResult.OK) return;
+
+ if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
+ {
+ return;
+ }
var path = dialog switch
{
- FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
- OpenFileDialog fileDialog => fileDialog.FileName,
- _ => string.Empty
+ System.Windows.Forms.FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
+ System.Windows.Forms.OpenFileDialog fileDialog => fileDialog.FileName,
+ _ => throw new System.NotImplementedException()
};
textBox.Text = path;
Settings[attributes.Name] = path;
@@ -280,7 +279,7 @@ public void Save()
VerticalAlignment = VerticalAlignment.Center,
TextWrapping = TextWrapping.WrapWithOverflow,
AcceptsReturn = true,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
@@ -301,7 +300,7 @@ public void Save()
Margin = settingControlMargin,
Password = Settings[attributes.Name] as string ?? string.Empty,
PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -321,7 +320,7 @@ public void Save()
ItemsSource = attributes.Options,
SelectedItem = Settings[attributes.Name],
Margin = settingControlMargin,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
+ HorizontalAlignment = HorizontalAlignment.Right,
ToolTip = attributes.Description
};
@@ -335,49 +334,55 @@ public void Save()
break;
}
case "checkbox":
- var checkBox = new CheckBox
{
- IsChecked =
+ var checkBox = new CheckBox
+ {
+ IsChecked =
Settings[attributes.Name] is bool isChecked
? isChecked
: bool.Parse(attributes.DefaultValue),
- Margin = settingCheckboxMargin,
- HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
- ToolTip = attributes.Description
- };
+ Margin = settingCheckboxMargin,
+ HorizontalAlignment = HorizontalAlignment.Right,
+ ToolTip = attributes.Description
+ };
- checkBox.Click += (sender, _) =>
- {
- Settings[attributes.Name] = ((CheckBox)sender).IsChecked!;
- };
+ checkBox.Click += (sender, _) =>
+ {
+ Settings[attributes.Name] = ((CheckBox)sender).IsChecked!;
+ };
- contentControl = checkBox;
+ contentControl = checkBox;
- break;
+ break;
+ }
case "hyperlink":
- var hyperlink = new Hyperlink { ToolTip = attributes.Description, NavigateUri = attributes.url };
-
- var linkbtn = new System.Windows.Controls.Button
{
- HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
- Margin = settingControlMargin,
- Content = attributes.urlLabel
- };
+ var hyperlink = new Hyperlink { ToolTip = attributes.Description, NavigateUri = attributes.url };
- contentControl = linkbtn;
+ var linkbtn = new Button
+ {
+ HorizontalAlignment = HorizontalAlignment.Right,
+ Margin = settingControlMargin,
+ Content = attributes.urlLabel
+ };
+
+ contentControl = linkbtn;
- break;
- case "seperator": // TODO: Support seperator
- // TODO: Use style for Seperator
- contentControl = new Separator
+ break;
+ }
+ case "seperator":
{
- VerticalAlignment = VerticalAlignment.Top,
- Margin = new(-70, 13.5, -18, 13.5),
- Height = 1
- };
- contentControl.SetResourceReference(Separator.BackgroundProperty, "Color03B");
+ // TODO: Move to resource
+ contentControl = new Separator
+ {
+ VerticalAlignment = VerticalAlignment.Top,
+ Margin = new(-70, 13.5, -18, 13.5),
+ Height = 1
+ };
+ contentControl.SetResourceReference(Separator.BackgroundProperty, "Color03B");
- break;
+ break;
+ }
default:
continue;
}
From f99648f3b46ba7b92341b115429653cd3e323e69 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 11:41:27 +0800
Subject: [PATCH 0370/1335] Redesgin json rpc settings
---
.../Plugin/JsonRPCPluginSettings.cs | 88 +++++++++++++------
1 file changed, 60 insertions(+), 28 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 5b84c1781cc..a604b2b91f1 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -24,10 +24,14 @@ public class JsonRPCPluginSettings
private JsonStorage> _storage = null!;
- // TODO: Move to resource
- private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
- private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
- private static readonly Thickness settingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
+ private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
+
+ private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin");
+ private static readonly Thickness SettingPanelItemRightMargin = (Thickness)Application.Current.FindResource("SettingPanelItemRightMargin");
+ private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin");
+
+ private static readonly Thickness SettingPanelItemLeftTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftTopBottomMargin");
+ private static readonly Thickness SettingPanelItemRightTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemRightTopBottomMargin");
public async Task InitializeAsync()
{
@@ -109,15 +113,15 @@ public void Save()
return null;
}
- // Create main grid with two columns
- var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
+ // Create main grid with two columns (Column 1: Auto, Column 2: *)
+ var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(0, GridUnitType.Auto)
});
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
- Width = new GridLength(0, GridUnitType.Auto)
+ Width = new GridLength(1, GridUnitType.Star)
});
// Iterate over each setting and create one row for it
@@ -140,12 +144,13 @@ public void Save()
StackPanel? panel = null;
FrameworkElement contentControl;
- // If the type is textBlock or seperator, we do not need to create a panel
- if (type != "textBlock" && type != "seperator")
+ // If the type is textBlock, seperator or check box, we do not need to create a panel
+ if (type != "textBlock" && type != "seperator" && type != "checkbox")
{
// Create a panel to hold the label and description
panel = new StackPanel
{
+ Margin = SettingPanelItemTopBottomMargin,
Orientation = Orientation.Vertical,
VerticalAlignment = VerticalAlignment.Center
};
@@ -190,7 +195,7 @@ public void Save()
contentControl = new TextBlock
{
Text = attributes.Description?.Replace("\\r\\n", "\r\n") ?? string.Empty,
- Padding = new Thickness(0, 0, 0, 0),
+ Margin = SettingPanelItemTopBottomMargin,
HorizontalAlignment = HorizontalAlignment.Left,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
@@ -203,7 +208,7 @@ public void Save()
var textBox = new TextBox()
{
Text = Settings[attributes.Name] as string ?? string.Empty,
- Margin = settingControlMargin,
+ Margin = SettingPanelItemLeftTopBottomMargin,
HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -222,7 +227,7 @@ public void Save()
{
var textBox = new TextBox()
{
- Margin = new Thickness(10, 0, 0, 0),
+ Margin = SettingPanelItemLeftMargin,
Text = Settings[attributes.Name] as string ?? string.Empty,
HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
@@ -235,7 +240,8 @@ public void Save()
var Btn = new Button()
{
- Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
+ Margin = SettingPanelItemLeftMargin,
+ Content = "Browse" // TODO: Localization
};
Btn.Click += (_, _) =>
@@ -257,15 +263,20 @@ public void Save()
System.Windows.Forms.OpenFileDialog fileDialog => fileDialog.FileName,
_ => throw new System.NotImplementedException()
};
+
textBox.Text = path;
Settings[attributes.Name] = path;
};
- var dockPanel = new DockPanel() { Margin = settingControlMargin };
+ var dockPanel = new DockPanel()
+ {
+ Margin = SettingPanelItemTopBottomMargin
+ };
DockPanel.SetDock(Btn, Dock.Right);
dockPanel.Children.Add(Btn);
dockPanel.Children.Add(textBox);
+
contentControl = dockPanel;
break;
@@ -274,8 +285,8 @@ public void Save()
{
var textBox = new TextBox()
{
- Height = 120,
- Margin = settingControlMargin,
+ Height = 150,
+ Margin = SettingPanelItemLeftTopBottomMargin,
VerticalAlignment = VerticalAlignment.Center,
TextWrapping = TextWrapping.WrapWithOverflow,
AcceptsReturn = true,
@@ -297,7 +308,7 @@ public void Save()
{
var passwordBox = new PasswordBox()
{
- Margin = settingControlMargin,
+ Margin = SettingPanelItemLeftTopBottomMargin,
Password = Settings[attributes.Name] as string ?? string.Empty,
PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
HorizontalAlignment = HorizontalAlignment.Stretch,
@@ -319,8 +330,8 @@ public void Save()
{
ItemsSource = attributes.Options,
SelectedItem = Settings[attributes.Name],
- Margin = settingControlMargin,
- HorizontalAlignment = HorizontalAlignment.Right,
+ Margin = SettingPanelItemLeftTopBottomMargin,
+ HorizontalAlignment = HorizontalAlignment.Left,
ToolTip = attributes.Description
};
@@ -341,8 +352,9 @@ public void Save()
Settings[attributes.Name] is bool isChecked
? isChecked
: bool.Parse(attributes.DefaultValue),
- Margin = settingCheckboxMargin,
- HorizontalAlignment = HorizontalAlignment.Right,
+ Margin = SettingPanelItemTopBottomMargin,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ Content = attributes.Label,
ToolTip = attributes.Description
};
@@ -357,13 +369,27 @@ Settings[attributes.Name] is bool isChecked
}
case "hyperlink":
{
- var hyperlink = new Hyperlink { ToolTip = attributes.Description, NavigateUri = attributes.url };
+ var hyperlink = new Hyperlink
+ {
+ ToolTip = attributes.Description,
+ NavigateUri = attributes.url
+ };
+
+ hyperlink.Inlines.Add(attributes.urlLabel);
+ hyperlink.RequestNavigate += (sender, e) =>
+ {
+ API.OpenUrl(e.Uri);
+ e.Handled = true;
+ };
+
+ var textBlock = new TextBlock();
+ textBlock.Inlines.Add(hyperlink);
var linkbtn = new Button
{
- HorizontalAlignment = HorizontalAlignment.Right,
- Margin = settingControlMargin,
- Content = attributes.urlLabel
+ HorizontalAlignment = HorizontalAlignment.Left,
+ Margin = SettingPanelItemLeftTopBottomMargin,
+ Content = textBlock
};
contentControl = linkbtn;
@@ -373,13 +399,16 @@ Settings[attributes.Name] is bool isChecked
case "seperator":
{
// TODO: Move to resource
- contentControl = new Separator
+ var sep = new Separator
{
VerticalAlignment = VerticalAlignment.Top,
Margin = new(-70, 13.5, -18, 13.5),
Height = 1
};
- contentControl.SetResourceReference(Separator.BackgroundProperty, "Color03B");
+
+ sep.SetResourceReference(Separator.BackgroundProperty, "Color03B");
+
+ contentControl = sep;
break;
}
@@ -407,8 +436,11 @@ Settings[attributes.Name] is bool isChecked
mainPanel.Children.Add(contentControl);
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
+ }
- // Add into SettingControls for later use if need
+ // Add into SettingControls for later use if need
+ if (type != "textBlock" && type != "seperator")
+ {
SettingControls[attributes.Name] = contentControl;
}
From e893645b2446aa0a20995b2b581db8dcf276b1ce Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 12:13:58 +0800
Subject: [PATCH 0371/1335] Improve JsonRPC settings panel design
---
.../Plugin/JsonRPCPluginSettings.cs | 61 +++++++++++--------
1 file changed, 36 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index a604b2b91f1..1e0e471f7b1 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -25,13 +25,9 @@ public class JsonRPCPluginSettings
private JsonStorage> _storage = null!;
private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
-
private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin");
- private static readonly Thickness SettingPanelItemRightMargin = (Thickness)Application.Current.FindResource("SettingPanelItemRightMargin");
private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin");
-
private static readonly Thickness SettingPanelItemLeftTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftTopBottomMargin");
- private static readonly Thickness SettingPanelItemRightTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemRightTopBottomMargin");
public async Task InitializeAsync()
{
@@ -195,8 +191,9 @@ public void Save()
contentControl = new TextBlock
{
Text = attributes.Description?.Replace("\\r\\n", "\r\n") ?? string.Empty,
- Margin = SettingPanelItemTopBottomMargin,
HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = SettingPanelItemTopBottomMargin,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
@@ -207,9 +204,11 @@ public void Save()
{
var textBox = new TextBox()
{
- Text = Settings[attributes.Name] as string ?? string.Empty,
+ MinWidth = 180,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
- HorizontalAlignment = HorizontalAlignment.Stretch,
+ Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
@@ -227,9 +226,11 @@ public void Save()
{
var textBox = new TextBox()
{
+ MinWidth = 240,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
Text = Settings[attributes.Name] as string ?? string.Empty,
- HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -240,6 +241,8 @@ public void Save()
var Btn = new Button()
{
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
Content = "Browse" // TODO: Localization
};
@@ -268,16 +271,19 @@ public void Save()
Settings[attributes.Name] = path;
};
- var dockPanel = new DockPanel()
+ var stackPanel = new StackPanel()
{
- Margin = SettingPanelItemTopBottomMargin
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = SettingPanelItemTopBottomMargin,
+ Orientation = Orientation.Horizontal
};
- DockPanel.SetDock(Btn, Dock.Right);
- dockPanel.Children.Add(Btn);
- dockPanel.Children.Add(textBox);
+ // Create a stack panel to wrap the button and text box
+ stackPanel.Children.Add(textBox);
+ stackPanel.Children.Add(Btn);
- contentControl = dockPanel;
+ contentControl = stackPanel;
break;
}
@@ -286,11 +292,12 @@ public void Save()
var textBox = new TextBox()
{
Height = 150,
- Margin = SettingPanelItemLeftTopBottomMargin,
+ MinWidth = 180,
+ HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
+ Margin = SettingPanelItemLeftTopBottomMargin,
TextWrapping = TextWrapping.WrapWithOverflow,
AcceptsReturn = true,
- HorizontalAlignment = HorizontalAlignment.Stretch,
Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
@@ -308,10 +315,12 @@ public void Save()
{
var passwordBox = new PasswordBox()
{
+ MinWidth = 180,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
Password = Settings[attributes.Name] as string ?? string.Empty,
PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
- HorizontalAlignment = HorizontalAlignment.Stretch,
ToolTip = attributes.Description
};
@@ -330,8 +339,9 @@ public void Save()
{
ItemsSource = attributes.Options,
SelectedItem = Settings[attributes.Name],
- Margin = SettingPanelItemLeftTopBottomMargin,
HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = SettingPanelItemLeftTopBottomMargin,
ToolTip = attributes.Description
};
@@ -352,8 +362,9 @@ public void Save()
Settings[attributes.Name] is bool isChecked
? isChecked
: bool.Parse(attributes.DefaultValue),
- Margin = SettingPanelItemTopBottomMargin,
HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = SettingPanelItemTopBottomMargin,
Content = attributes.Label,
ToolTip = attributes.Description
};
@@ -382,17 +393,17 @@ Settings[attributes.Name] is bool isChecked
e.Handled = true;
};
- var textBlock = new TextBlock();
- textBlock.Inlines.Add(hyperlink);
-
- var linkbtn = new Button
+ var textBlock = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
- Content = textBlock
+ TextAlignment = TextAlignment.Left,
+ TextWrapping = TextWrapping.Wrap
};
+ textBlock.Inlines.Add(hyperlink);
- contentControl = linkbtn;
+ contentControl = textBlock;
break;
}
From e1c446128624779d7402a0668b1ecff7378c61e6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 17:43:45 +0800
Subject: [PATCH 0372/1335] Fix JsonElement parse issue
---
.../Plugin/JsonRPCPluginSettings.cs | 63 +++++++++++++++----
1 file changed, 50 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 1e0e471f7b1..8282dec4c9c 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -18,11 +19,11 @@ public class JsonRPCPluginSettings
public required string SettingPath { get; init; }
public Dictionary SettingControls { get; } = new();
- public IReadOnlyDictionary Inner => Settings;
- protected ConcurrentDictionary Settings { get; set; } = null!;
+ public IReadOnlyDictionary Inner => Settings;
+ protected ConcurrentDictionary Settings { get; set; } = null!;
public required IPublicAPI API { get; init; }
- private JsonStorage> _storage = null!;
+ private JsonStorage> _storage = null!;
private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin");
@@ -31,15 +32,35 @@ public class JsonRPCPluginSettings
public async Task InitializeAsync()
{
- _storage = new JsonStorage>(SettingPath);
- Settings = await _storage.LoadAsync();
+ if (Settings == null)
+ {
+ _storage = new JsonStorage>(SettingPath);
+ Settings = await _storage.LoadAsync();
+
+ // Because value type of settings dictionary is object which causes them to be JsonElement when loading from json files,
+ // we need to convert it to the correct type
+ foreach (var (key, value) in Settings)
+ {
+ if (value is JsonElement jsonElement)
+ {
+ Settings[key] = jsonElement.ValueKind switch
+ {
+ JsonValueKind.String => jsonElement.GetString() ?? value,
+ JsonValueKind.True => jsonElement.GetBoolean(),
+ JsonValueKind.False => jsonElement.GetBoolean(),
+ JsonValueKind.Null => null,
+ _ => value
+ };
+ }
+ }
+ }
if (Configuration == null)
{
return;
}
- foreach (var (_, attributes) in Configuration.Body)
+ foreach (var (type, attributes) in Configuration.Body)
{
// Skip if the setting does not have attributes or name
if (attributes?.Name == null)
@@ -47,9 +68,20 @@ public async Task InitializeAsync()
continue;
}
- if (!Settings.ContainsKey(attributes.Name))
+ if (NeedSaveInSettings(type))
{
- Settings[attributes.Name] = attributes.DefaultValue;
+ // If need save in settings, we need to make sure the setting exists in the settings file
+ if (!Settings.ContainsKey(attributes.Name))
+ {
+ if (type == "checkbox")
+ {
+ Settings[attributes.Name] = bool.Parse(attributes.DefaultValue);
+ }
+ else
+ {
+ Settings[attributes.Name] = attributes.DefaultValue;
+ }
+ }
}
}
}
@@ -103,8 +135,8 @@ public void Save()
public Control? CreateSettingPanel()
{
- // If there are no settings or the settings are empty, return null
- if (Configuration == null || Settings == null || Settings.IsEmpty)
+ // If there are no settings or the settings configuration is empty, return null
+ if (Configuration == null || Settings == null || Configuration.Body.Count == 0)
{
return null;
}
@@ -291,7 +323,7 @@ public void Save()
{
var textBox = new TextBox()
{
- Height = 150,
+ MaxHeight = 150,
MinWidth = 180,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
@@ -449,8 +481,8 @@ Settings[attributes.Name] is bool isChecked
Grid.SetRow(contentControl, rowCount);
}
- // Add into SettingControls for later use if need
- if (type != "textBlock" && type != "seperator")
+ // Add into SettingControls for settings storage if need
+ if (NeedSaveInSettings(type))
{
SettingControls[attributes.Name] = contentControl;
}
@@ -464,5 +496,10 @@ Settings[attributes.Name] is bool isChecked
Content = mainPanel
};
}
+
+ private static bool NeedSaveInSettings(string type)
+ {
+ return type != "textBlock" && type != "seperator" && type != "hyperlink";
+ }
}
}
From 4e4758677f2b533fb6ed107f948ff7d7a1ab2570 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 19:21:09 +0800
Subject: [PATCH 0373/1335] Remove unneccessary CreateSettingPanel by
introducing need check
---
Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 7 ++++++-
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 9 +++++++--
Flow.Launcher/ViewModel/PluginViewModel.cs | 8 ++++----
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
index ed8f94bcf25..7248c625947 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
@@ -34,7 +34,7 @@ namespace Flow.Launcher.Core.Plugin
/// Represent the plugin that using JsonPRC
/// every JsonRPC plugin should has its own plugin instance
///
- internal abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable
+ public abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable
{
protected PluginInitContext Context;
public const string JsonRPC = "JsonRPC";
@@ -157,6 +157,11 @@ public void Save()
Settings?.Save();
}
+ public bool NeedCreateSettingPanel()
+ {
+ return Settings.NeedCreateSettingPanel();
+ }
+
public Control CreateSettingPanel()
{
return Settings.CreateSettingPanel();
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 2a4b22bf395..8412ba7e89a 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -109,10 +109,15 @@ public void Save()
_storage.Save();
}
+ public bool NeedCreateSettingPanel()
+ {
+ // If there are no settings or the settings configuration is empty, return null
+ return Settings != null && Configuration != null && Configuration.Body.Count != 0;
+ }
+
public Control CreateSettingPanel()
{
- if (Settings == null || Settings.Count == 0)
- return null;
+ // No need to check if NeedCreateSettingPanel is true because CreateSettingPanel will only be called if it's true
var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 46f8e00a222..209a813955a 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -90,13 +90,13 @@ public bool IsExpanded
private Control _bottomPart2;
public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginDisplayBottomData() : null;
- public bool HasSettingControl => PluginPair.Plugin is ISettingProvider settingProvider && settingProvider.CreateSettingPanel() != null;
+ public bool HasSettingControl => PluginPair.Plugin is ISettingProvider && (PluginPair.Plugin is not JsonRPCPluginBase jsonRPCPluginBase || jsonRPCPluginBase.NeedCreateSettingPanel());
public Control SettingControl
=> IsExpanded
? _settingControl
- ??= PluginPair.Plugin is not ISettingProvider settingProvider
- ? null
- : settingProvider.CreateSettingPanel()
+ ??= HasSettingControl
+ ? ((ISettingProvider)PluginPair.Plugin).CreateSettingPanel()
+ : null
: null;
private ImageSource _image = ImageLoader.MissingImage;
From 62677bc40ea5c35ef302723264d43be97f35cb84 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 22:08:08 +0800
Subject: [PATCH 0374/1335] Fix program plugin settings panel top bottom margin
issue
---
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index 6a6657959b5..d57e44542a4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -67,21 +67,20 @@
Text="{DynamicResource flowlauncher_plugin_program_index_option}" />
From 317258af2f0b4a372f7f94813a35d56c4f57c362 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 22:08:40 +0800
Subject: [PATCH 0375/1335] Redesgin settings panel for explorer plugin
---
.../Plugin/JsonRPCPluginSettings.cs | 2 +-
.../Views/ExplorerSettings.xaml | 1242 ++++++++---------
2 files changed, 614 insertions(+), 630 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 8282dec4c9c..ab679847304 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -227,7 +227,7 @@ public void Save()
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
+ TextWrapping = TextWrapping.Wrap // TODO: Check password and others
};
break;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index ecd6d1fcade..85b155a3956 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -14,99 +14,21 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
+
-
+
+
@@ -146,7 +68,7 @@
-
+
+
+ 180
+ 240
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 85b155a3956..836e2d5589d 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -174,7 +174,7 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Orientation="Horizontal">
From 86c055338fc5dde4b1c6f4314aa1d8c2dfe66a0d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 22:17:16 +0800
Subject: [PATCH 0377/1335] Unify operation button width
---
.../Views/SettingsControl.xaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index 6183fa1b2de..30424f4e892 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -65,11 +65,11 @@
HorizontalAlignment="Right"
Orientation="Horizontal">
@@ -85,7 +85,7 @@
From 9f55e8387ebfa1591d75404761fe06db565dc25b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 22:25:51 +0800
Subject: [PATCH 0378/1335] Change file select string
---
.../Plugin/JsonRPCPluginSettings.cs | 2 +-
.../Views/ExplorerSettings.xaml | 15 ++++++---------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 499371c4b46..0729fba4231 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -278,7 +278,7 @@ public void Save()
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
- Content = "Browse" // TODO: Localization
+ Content = API.GetTranslation("select")
};
Btn.Click += (_, _) =>
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 836e2d5589d..e525c84add1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -174,18 +174,17 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Orientation="Horizontal">
+ Content="{DynamicResource select}" />
+ Content="{DynamicResource select}" />
+ Content="{DynamicResource select}" />
Date: Sat, 1 Mar 2025 22:29:14 +0800
Subject: [PATCH 0379/1335] Improve text area
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 4 ++--
.../Views/ExplorerSettings.xaml | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 0729fba4231..69934e9f48b 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -325,8 +325,8 @@ public void Save()
{
var textBox = new TextBox()
{
- MaxHeight = 150,
- MinWidth = SettingPanelTextBlockMinWidth,
+ MinHeight = 150,
+ MinWidth = 240,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index e525c84add1..a5e5f60071a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -358,8 +358,8 @@
Grid.Row="15"
Grid.Column="0"
Grid.ColumnSpan="2"
- MinWidth="{StaticResource SettingPanelTextBlockMinWidth}"
- MaxHeight="150"
+ MinWidth="240"
+ MinHeight="150"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Left"
AcceptsReturn="True"
@@ -378,8 +378,8 @@
Grid.Row="17"
Grid.Column="0"
Grid.ColumnSpan="2"
- MinWidth="{StaticResource SettingPanelTextBlockMinWidth}"
- MaxHeight="150"
+ MinWidth="240"
+ MinHeight="150"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Left"
AcceptsReturn="True"
From af3a1a310c87feef3196f021000642edc72e698d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 1 Mar 2025 22:38:11 +0800
Subject: [PATCH 0380/1335] Unify text area min width & height
---
.../Plugin/JsonRPCPluginSettings.cs | 21 +++++++++++--------
.../Resources/CustomControlTemplate.xaml | 6 ++++--
.../Views/ExplorerSettings.xaml | 20 +++++++++---------
3 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 69934e9f48b..388f0b2c962 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -29,8 +29,10 @@ public class JsonRPCPluginSettings
private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin");
private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin");
private static readonly Thickness SettingPanelItemLeftTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftTopBottomMargin");
- private static readonly double SettingPanelTextBlockMinWidth = (double)Application.Current.FindResource("SettingPanelTextBlockMinWidth");
- private static readonly double SettingPanelPathTextBlockMinWidth = (double)Application.Current.FindResource("SettingPanelPathTextBlockMinWidth");
+ private static readonly double SettingPanelTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelTextBoxMinWidth");
+ private static readonly double SettingPanelPathTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelPathTextBoxMinWidth");
+ private static readonly double SettingPanelAreaTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelAreaTextBoxMinWidth");
+ private static readonly double SettingPanelAreaTextBoxMinHeight = (double)Application.Current.FindResource("SettingPanelAreaTextBoxMinHeight");
public async Task InitializeAsync()
{
@@ -229,7 +231,7 @@ public void Save()
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap // TODO: Check password and others
+ TextWrapping = TextWrapping.Wrap
};
break;
@@ -238,7 +240,7 @@ public void Save()
{
var textBox = new TextBox()
{
- MinWidth = SettingPanelTextBlockMinWidth,
+ MinWidth = SettingPanelTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
@@ -260,7 +262,7 @@ public void Save()
{
var textBox = new TextBox()
{
- MinWidth = SettingPanelPathTextBlockMinWidth,
+ MinWidth = SettingPanelPathTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
@@ -325,8 +327,8 @@ public void Save()
{
var textBox = new TextBox()
{
- MinHeight = 150,
- MinWidth = 240,
+ MinHeight = SettingPanelAreaTextBoxMinHeight,
+ MinWidth = SettingPanelAreaTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
@@ -349,15 +351,16 @@ public void Save()
{
var passwordBox = new PasswordBox()
{
- MinWidth = SettingPanelTextBlockMinWidth,
+ MinWidth = SettingPanelTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
Password = Settings[attributes.Name] as string ?? string.Empty,
PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
- ToolTip = attributes.Description
+ ToolTip = attributes.Description,
};
+ // TODO: Fix issue here
passwordBox.PasswordChanged += (sender, _) =>
{
Settings[attributes.Name] = ((PasswordBox)sender).Password;
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index e10539c8e34..65002a3a06e 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5603,6 +5603,8 @@
- 180
- 240
+ 180
+ 240
+ 270
+ 150
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index a5e5f60071a..709b1805148 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -174,7 +174,7 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Orientation="Horizontal">
From 6a736a833b1faa6aadce1a12c77709f60da00807 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 2 Mar 2025 04:41:22 +0900
Subject: [PATCH 0381/1335] Add bgcolor for blur
---
Flow.Launcher/Themes/BlurWhite.xaml | 3 ++-
Flow.Launcher/Themes/Circle System.xaml | 6 +++++-
Flow.Launcher/Themes/Win11Light.xaml | 2 +-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Themes/BlurWhite.xaml b/Flow.Launcher/Themes/BlurWhite.xaml
index a13f3bfcc77..ed290d0c8af 100644
--- a/Flow.Launcher/Themes/BlurWhite.xaml
+++ b/Flow.Launcher/Themes/BlurWhite.xaml
@@ -10,8 +10,9 @@
-
True
+ light
+ #BFFAFAFA
diff --git a/Flow.Launcher/Themes/Win11Light.xaml b/Flow.Launcher/Themes/Win11Light.xaml
index ba162fe9cd2..5ba82f12ecc 100644
--- a/Flow.Launcher/Themes/Win11Light.xaml
+++ b/Flow.Launcher/Themes/Win11Light.xaml
@@ -14,6 +14,7 @@
True
Auto
+ ROUND
#BFFAFAFA
#DD202020
diff --git a/Flow.Launcher/Themes/BlurWhite.xaml b/Flow.Launcher/Themes/BlurWhite.xaml
index ed290d0c8af..29fe38a9cd9 100644
--- a/Flow.Launcher/Themes/BlurWhite.xaml
+++ b/Flow.Launcher/Themes/BlurWhite.xaml
@@ -11,8 +11,10 @@
True
- light
+ Light
+ DoNotRound
#BFFAFAFA
+ #BFFAFAFA
diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml
index d6f9813d001..a8b04d64025 100644
--- a/Flow.Launcher/Themes/Pink.xaml
+++ b/Flow.Launcher/Themes/Pink.xaml
@@ -1,7 +1,15 @@
-
+
+ True
+ Light
+ RoundSmall
+ #DDFEC7D7
+ #DDFEC7D7
0 0 0 0
From 1681ac470c74ef88ae5579782a880a54de982ad3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 2 Mar 2025 11:42:15 +0800
Subject: [PATCH 0387/1335] Fix path select button possibly invisible issue
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 4 ++--
Flow.Launcher/Resources/CustomControlTemplate.xaml | 2 +-
.../Views/ExplorerSettings.xaml | 9 +++++----
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index a28b4ae0c15..92089489600 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -30,7 +30,7 @@ public class JsonRPCPluginSettings
private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin");
private static readonly Thickness SettingPanelItemLeftTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftTopBottomMargin");
private static readonly double SettingPanelTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelTextBoxMinWidth");
- private static readonly double SettingPanelPathTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelPathTextBoxMinWidth");
+ private static readonly double SettingPanelPathTextBoxWidth = (double)Application.Current.FindResource("SettingPanelPathTextBoxWidth");
private static readonly double SettingPanelAreaTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelAreaTextBoxMinWidth");
private static readonly double SettingPanelAreaTextBoxMinHeight = (double)Application.Current.FindResource("SettingPanelAreaTextBoxMinHeight");
@@ -259,7 +259,7 @@ public void Save()
{
var textBox = new TextBox()
{
- MinWidth = SettingPanelPathTextBoxMinWidth,
+ Width = SettingPanelPathTextBoxWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index b646cb6951d..10d7ff987f3 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5604,7 +5604,7 @@
180
- 240
+ 240
270
150
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 709b1805148..5989192f42c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -174,7 +174,7 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Orientation="Horizontal">
+
From 31892a0fc84bea21ea6d7f9d4aff0d84e57846c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 2 Mar 2025 11:45:25 +0800
Subject: [PATCH 0388/1335] Adjust installed plugin keyword margin
---
.../Resources/Controls/InstalledPluginDisplayKeyword.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
index d2d2afa095a..ded6e0e2776 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplayKeyword.xaml
@@ -34,9 +34,10 @@
DockPanel.Dock="Left"
Style="{DynamicResource SettingTitleLabel}"
Text="{DynamicResource actionKeywords}" />
+
Date: Mon, 3 Mar 2025 20:01:40 +0800
Subject: [PATCH 0389/1335] Remove unnecessary todo
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 92089489600..c9a0d6e47c2 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -357,7 +357,6 @@ public void Save()
ToolTip = attributes.Description,
};
- // TODO: Fix issue here
passwordBox.PasswordChanged += (sender, _) =>
{
Settings[attributes.Name] = ((PasswordBox)sender).Password;
From 889f4cbfeb4959477c3c3db8bdaf66c527cb902e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 4 Mar 2025 11:08:09 +0800
Subject: [PATCH 0390/1335] Fix null reference exception when checking source
---
.../Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f4c8a66da31..4ceadec56fc 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -593,7 +593,10 @@ private bool InstallSourceKnown(string url)
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
return url.StartsWith(acceptedSource) &&
- Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart));
+ Context.API.GetAllPlugins().Any(x =>
+ !string.IsNullOrEmpty(x.Metadata.Website) &&
+ x.Metadata.Website.StartsWith(constructedUrlPart)
+ );
}
internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
From ff18abcddd452b4343b222cfda3d4572a9d0250b Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 4 Mar 2025 12:49:46 +0900
Subject: [PATCH 0391/1335] Change Window type
---
Flow.Launcher.Core/Resource/Theme.cs | 4 ++--
Flow.Launcher/MainWindow.xaml | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 39aa2d6f4f8..e871dd29a95 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -149,12 +149,12 @@ public void RefreshFrame()
Methods.ExtendFrame(mainWindowSrc.Handle, margins);
// Remove OS minimizing/maximizing animation
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
+ //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
SetBlurForWindow();
- SetCornerForWindow();
+ //SetCornerForWindow();
}
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index d99787a8d6b..c2e1978f9a6 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -15,8 +15,8 @@
MinHeight="30"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
AllowDrop="True"
- AllowsTransparency="False"
- Background="#E12E2E2E"
+ AllowsTransparency="True"
+ Background="Transparent"
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
@@ -34,7 +34,7 @@
Topmost="True"
Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
WindowStartupLocation="Manual"
- WindowStyle="SingleBorderWindow"
+ WindowStyle="None"
mc:Ignorable="d">
From f0b1422f63e24fd82dc15eaafe554e4caad7b35f Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 4 Mar 2025 13:46:36 +0900
Subject: [PATCH 0392/1335] Change AddShadow Logic
---
Flow.Launcher.Core/Resource/Theme.cs | 192 ++++++++++++------
.../ViewModels/SettingsPaneThemeViewModel.cs | 16 +-
2 files changed, 139 insertions(+), 69 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index e871dd29a95..e64df9c8799 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -153,10 +153,69 @@ public void RefreshFrame()
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+
+ if (!_settings.UseDropShadowEffect && BlurEnabled)
+ {
+ _settings.UseDropShadowEffect = true;
+ AddDropShadowEffectToCurrentTheme();
+ }
+
+ if (_settings.UseDropShadowEffect)
+ {
+ AddDropShadowEffectToCurrentTheme();
+ }
+ //else if (!_settings.usedropshadoweffect && blurenabled)
+ //{
+ // adddropshadoweffecttocurrenttheme();
+ // _settings.usedropshadoweffect = true;
+ //}
SetBlurForWindow();
//SetCornerForWindow();
}
+ public void AutoDropShadow()
+ {
+ if (_settings.UseDropShadowEffect)
+ {
+ RemoveDropShadowEffectFromCurrentTheme();
+ if (BlurEnabled)
+ {
+ Debug.WriteLine("이거는 블러있는 테마이므로 외곽선 주고 그림자");
+ SetWindowCornerPreference("Round");
+ }
+ else
+ {
+ Debug.WriteLine("이거는 블러없는 테마");
+ AddDropShadowEffectToCurrentTheme();
+ }
+ }
+ else
+ {
+ RemoveDropShadowEffectFromCurrentTheme();
+ if (BlurEnabled)
+ {
+ SetWindowCornerPreference("Default");
+ }
+ else
+ {
+ RemoveDropShadowEffectFromCurrentTheme();
+ }
+ }
+ }
+
+ public void SetWindowCornerPreference(string cornerType)
+ {
+ DWM_WINDOW_CORNER_PREFERENCE preference = cornerType switch
+ {
+ "DoNotRound" => DWM_WINDOW_CORNER_PREFERENCE.DoNotRound,
+ "Round" => DWM_WINDOW_CORNER_PREFERENCE.Round,
+ "RoundSmall" => DWM_WINDOW_CORNER_PREFERENCE.RoundSmall,
+ "Default" => DWM_WINDOW_CORNER_PREFERENCE.Default,
+ _ => DWM_WINDOW_CORNER_PREFERENCE.Default,
+ };
+
+ SetWindowCornerPreference(mainWindow, preference);
+ }
public void SetCornerForWindow()
{
@@ -465,10 +524,11 @@ public bool ChangeTheme(string theme)
}
BlurEnabled = Win32Helper.IsBlurTheme();
-
- if (_settings.UseDropShadowEffect && !BlurEnabled)
+ if (_settings.UseDropShadowEffect)
AddDropShadowEffectToCurrentTheme();
+
+
//Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
SetBlurForWindow();
}
@@ -656,76 +716,86 @@ private string GetThemePath(string themeName)
public void AddDropShadowEffectToCurrentTheme()
{
- var dict = GetCurrentResourceDictionary();
+ SetWindowCornerPreference("Default");
+ if (BlurEnabled)
+ {
+ SetWindowCornerPreference("Round");
+ }
+ else
+ {
+ var dict = GetCurrentResourceDictionary();
- //var windowBorderStyle = dict["WindowBorderStyle"] as Style;
+ var windowBorderStyle = dict["WindowBorderStyle"] as Style;
- //var effectSetter = new Setter
- //{
- // Property = Border.EffectProperty,
- // Value = new DropShadowEffect
- // {
- // Opacity = 0.3,
- // ShadowDepth = 12,
- // Direction = 270,
- // BlurRadius = 30
- // }
- //};
-
- //var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
- //if (marginSetter == null)
- //{
- // var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
- // marginSetter = new Setter()
- // {
- // Property = Border.MarginProperty,
- // Value = margin,
- // };
- // windowBorderStyle.Setters.Add(marginSetter);
-
- // SetResizeBoarderThickness(margin);
- //}
- //else
- //{
- // var baseMargin = (Thickness)marginSetter.Value;
- // var newMargin = new Thickness(
- // baseMargin.Left + ShadowExtraMargin,
- // baseMargin.Top + ShadowExtraMargin,
- // baseMargin.Right + ShadowExtraMargin,
- // baseMargin.Bottom + ShadowExtraMargin);
- // marginSetter.Value = newMargin;
-
- // SetResizeBoarderThickness(newMargin);
- //}
+ var effectSetter = new Setter
+ {
+ Property = Border.EffectProperty,
+ Value = new DropShadowEffect
+ {
+ Opacity = 0.3,
+ ShadowDepth = 12,
+ Direction = 270,
+ BlurRadius = 30
+ }
+ };
+
+ var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
+ if (marginSetter == null)
+ {
+ var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
+ marginSetter = new Setter()
+ {
+ Property = Border.MarginProperty,
+ Value = margin,
+ };
+ windowBorderStyle.Setters.Add(marginSetter);
+
+ SetResizeBoarderThickness(margin);
+ }
+ else
+ {
+ var baseMargin = (Thickness)marginSetter.Value;
+ var newMargin = new Thickness(
+ baseMargin.Left + ShadowExtraMargin,
+ baseMargin.Top + ShadowExtraMargin,
+ baseMargin.Right + ShadowExtraMargin,
+ baseMargin.Bottom + ShadowExtraMargin);
+ marginSetter.Value = newMargin;
+
+ SetResizeBoarderThickness(newMargin);
+ }
- //windowBorderStyle.Setters.Add(effectSetter);
+ windowBorderStyle.Setters.Add(effectSetter);
- UpdateResourceDictionary(dict);
+ UpdateResourceDictionary(dict);
+ }
}
public void RemoveDropShadowEffectFromCurrentTheme()
{
+ SetWindowCornerPreference("Default");
+
var dict = GetCurrentResourceDictionary();
- mainWindow.WindowStyle = WindowStyle.None;
- //var windowBorderStyle = dict["WindowBorderStyle"] as Style;
+ //mainWindow.WindowStyle = WindowStyle.None;
+ var windowBorderStyle = dict["WindowBorderStyle"] as Style;
- //var effectSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) as Setter;
- //var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
+ var effectSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) as Setter;
+ var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
- //if (effectSetter != null)
- //{
- // windowBorderStyle.Setters.Remove(effectSetter);
- //}
- //if (marginSetter != null)
- //{
- // var currentMargin = (Thickness)marginSetter.Value;
- // var newMargin = new Thickness(
- // currentMargin.Left - ShadowExtraMargin,
- // currentMargin.Top - ShadowExtraMargin,
- // currentMargin.Right - ShadowExtraMargin,
- // currentMargin.Bottom - ShadowExtraMargin);
- // marginSetter.Value = newMargin;
- //}
+ if (effectSetter != null)
+ {
+ windowBorderStyle.Setters.Remove(effectSetter);
+ }
+ if (marginSetter != null)
+ {
+ var currentMargin = (Thickness)marginSetter.Value;
+ var newMargin = new Thickness(
+ currentMargin.Left - ShadowExtraMargin,
+ currentMargin.Top - ShadowExtraMargin,
+ currentMargin.Right - ShadowExtraMargin,
+ currentMargin.Bottom - ShadowExtraMargin);
+ marginSetter.Value = newMargin;
+ }
SetResizeBoarderThickness(null);
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index cd5abb95840..1437a7d1a47 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -53,14 +53,14 @@ public bool DropShadowEffect
return;
}
- //if (value)
- //{
- // ThemeManager.Instance.AddDropShadowEffectToCurrentTheme();
- //}
- //else
- //{
- // ThemeManager.Instance.RemoveDropShadowEffectFromCurrentTheme();
- //}
+ if (value)
+ {
+ ThemeManager.Instance.AddDropShadowEffectToCurrentTheme();
+ }
+ else
+ {
+ ThemeManager.Instance.RemoveDropShadowEffectFromCurrentTheme();
+ }
Settings.UseDropShadowEffect = value;
}
From 90828d9daaec267ade693f1d1889c0e3c539e844 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 5 Mar 2025 07:00:38 +0900
Subject: [PATCH 0393/1335] Fix Shadow Timing
---
Flow.Launcher.Core/Resource/Theme.cs | 59 ++++++++++++-------
Flow.Launcher/MainWindow.xaml.cs | 5 --
.../ViewModels/SettingsPaneThemeViewModel.cs | 1 +
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index e64df9c8799..2bf8a5d3526 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -153,23 +153,26 @@ public void RefreshFrame()
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
-
- if (!_settings.UseDropShadowEffect && BlurEnabled)
- {
- _settings.UseDropShadowEffect = true;
- AddDropShadowEffectToCurrentTheme();
- }
- if (_settings.UseDropShadowEffect)
- {
- AddDropShadowEffectToCurrentTheme();
- }
+ //if (!_settings.UseDropShadowEffect && BlurEnabled)
+ //{
+ // _settings.UseDropShadowEffect = true;
+ // AddDropShadowEffectToCurrentTheme();
+ //}
+
+ //if (_settings.UseDropShadowEffect)
+ //{
+ // AddDropShadowEffectToCurrentTheme();
+ //}
+ //AutoDropShadow();
+ SetBlurForWindow();
+
//else if (!_settings.usedropshadoweffect && blurenabled)
//{
// adddropshadoweffecttocurrenttheme();
// _settings.usedropshadoweffect = true;
//}
- SetBlurForWindow();
+
//SetCornerForWindow();
}
@@ -185,6 +188,7 @@ public void AutoDropShadow()
}
else
{
+ SetWindowCornerPreference("Default");
Debug.WriteLine("이거는 블러없는 테마");
AddDropShadowEffectToCurrentTheme();
}
@@ -247,6 +251,7 @@ public void SetCornerForWindow()
///
public void SetBlurForWindow()
{
+ //AutoDropShadow();
//SetWindowAccent();
var dict = GetThemeResourceDictionary(_settings.Theme);
if (dict == null)
@@ -265,6 +270,7 @@ public void SetBlurForWindow()
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+ SetWindowCornerPreference("Round");
}
else
{
@@ -274,10 +280,24 @@ public void SetBlurForWindow()
// windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
//}
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1);
+ SetWindowCornerPreference("Default");
+ if (_settings.UseDropShadowEffect)
+ {
+
+ AddDropShadowEffectToCurrentTheme();
+ }
+ else
+ {
+ RemoveDropShadowEffectFromCurrentTheme();
+ }
}
ThemeModeColor(BlurMode());
+
UpdateResourceDictionary(dict);
+
+
+
}
// WindowBorderStyle에서 Background 색상 가져오는 함수
@@ -403,6 +423,7 @@ public void ThemeModeColor(string Mode)
}
else
{
+ //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
mainWindow.Background = new SolidColorBrush(Colors.Transparent);
}
}
@@ -716,14 +737,9 @@ private string GetThemePath(string themeName)
public void AddDropShadowEffectToCurrentTheme()
{
- SetWindowCornerPreference("Default");
- if (BlurEnabled)
- {
- SetWindowCornerPreference("Round");
- }
- else
- {
- var dict = GetCurrentResourceDictionary();
+
+ //SetWindowCornerPreference("Default");
+ var dict = GetCurrentResourceDictionary();
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
@@ -768,13 +784,12 @@ public void AddDropShadowEffectToCurrentTheme()
windowBorderStyle.Setters.Add(effectSetter);
UpdateResourceDictionary(dict);
- }
+
}
public void RemoveDropShadowEffectFromCurrentTheme()
{
- SetWindowCornerPreference("Default");
-
+
var dict = GetCurrentResourceDictionary();
//mainWindow.WindowStyle = WindowStyle.None;
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index cd6dda39d22..ae1f5d04ca3 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -67,11 +67,6 @@ public MainWindow(Settings settings, MainViewModel mainVM)
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
};
- if (_settings.UseDropShadowEffect == false) /* Shadow Effect */
- {
- FlowMainWindow.WindowStyle = WindowStyle.None;
- FlowMainWindow.AllowsTransparency = true;
- }
}
DispatcherTimer timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 500), IsEnabled = false };
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 1437a7d1a47..d05fe98a874 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -38,6 +38,7 @@ public Theme.ThemeData SelectedTheme
if (ThemeManager.Instance.BlurEnabled && Settings.UseDropShadowEffect == false)
DropShadowEffect = true;
ThemeManager.Instance.RefreshFrame();
+ //ThemeManager.Instance.SetBlurForWindow();
}
}
From f712f635bfb1868be6ee74a213f2fc8059752f38 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 5 Mar 2025 09:36:33 +0900
Subject: [PATCH 0394/1335] Adjust Animator
---
Flow.Launcher/MainWindow.xaml.cs | 110 +++++++++++++++--------
Flow.Launcher/ViewModel/MainViewModel.cs | 27 +-----
2 files changed, 76 insertions(+), 61 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index ae1f5d04ca3..0e86023bb59 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -67,8 +67,67 @@ public MainWindow(Settings settings, MainViewModel mainVM)
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
};
+
+ _viewModel.PropertyChanged += (o, e) =>
+ {
+ if (e.PropertyName == nameof(MainViewModel.MainWindowVisibilityStatus))
+ {
+ Dispatcher.Invoke(() =>
+ {
+ if (_viewModel.MainWindowVisibilityStatus)
+ ShowWithOptionalAnimation();
+ else
+ HideImmediately();
+ });
+ }
+ };
+ }
+
+ private void ShowWithOptionalAnimation()
+ {
+ if (this.Visibility == Visibility.Visible && this.Opacity == 1) return; // ✅ 이미 보이는 상태라면 실행하지 않음.
+
+ this.Opacity = 0; // 🔹 먼저 Opacity를 0으로 설정하여 깜빡임 방지
+ this.Visibility = Visibility.Visible; // 🔹 이제 Visibility를 변경하여 창을 표시
+
+ UpdatePosition(); // 🔹 창 위치 업데이트
+
+ if (_settings.UseAnimation)
+ {
+ // 🔹 아이콘 & 시계 애니메이션만 실행
+ WindowAnimator();
+ }
+
+ if (_settings.UseAnimation)
+ {
+ var fadeIn = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(150))
+ {
+ FillBehavior = FillBehavior.HoldEnd
+ };
+
+ fadeIn.Completed += (_, _) =>
+ {
+ this.Opacity = 1; // 🔹 애니메이션 종료 후 Opacity를 1로 유지
+ };
+ this.BeginAnimation(Window.OpacityProperty, fadeIn);
+ }
+ else
+ {
+ this.Opacity = 1; // 🔹 애니메이션 없이 즉시 표시
+ }
+
+ Activate(); // 🔹 창 활성화
}
+ private void HideImmediately()
+ {
+ if (this.Visibility != Visibility.Visible) return; // ✅ 이미 숨겨져 있다면 실행하지 않음.
+
+ this.Opacity = 0; // 🔹 Opacity를 먼저 줄여서 깜빡임 방지
+ this.Visibility = Visibility.Collapsed; // 🔹 창을 완전히 숨김
+ }
+
+
DispatcherTimer timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 500), IsEnabled = false };
public MainWindow()
@@ -481,15 +540,11 @@ public void WindowAnimator()
if (_animating)
return;
- isArrowKeyPressed = true;
_animating = true;
- UpdatePosition();
- Storyboard windowsb = new Storyboard();
Storyboard clocksb = new Storyboard();
Storyboard iconsb = new Storyboard();
- CircleEase easing = new CircleEase();
- easing.EasingMode = EasingMode.EaseInOut;
+ CircleEase easing = new CircleEase { EasingMode = EasingMode.EaseInOut };
var animationLength = _settings.AnimationSpeed switch
{
@@ -499,28 +554,13 @@ public void WindowAnimator()
_ => _settings.CustomAnimationLength
};
- var WindowOpacity = new DoubleAnimation
- {
- From = 0,
- To = 1,
- Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
- FillBehavior = FillBehavior.Stop
- };
-
- var WindowMotion = new DoubleAnimation
- {
- From = Top + 10,
- To = Top,
- Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
- FillBehavior = FillBehavior.Stop
- };
var IconMotion = new DoubleAnimation
{
From = 12,
To = 0,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd // ✅ 애니메이션 종료 후 값을 유지
};
var ClockOpacity = new DoubleAnimation
@@ -529,16 +569,17 @@ public void WindowAnimator()
To = 1,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd // ✅ 애니메이션 종료 후 값 유지
};
- double TargetIconOpacity = SearchIcon.Opacity; // Animation Target Opacity from Style
+
+ double TargetIconOpacity = SearchIcon.Opacity;
var IconOpacity = new DoubleAnimation
{
From = 0,
To = TargetIconOpacity,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd // ✅ 애니메이션 종료 후 값 유지
};
double right = ClockPanel.Margin.Right;
@@ -548,39 +589,34 @@ public void WindowAnimator()
To = new Thickness(0, 0, right, 0),
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd // ✅ 애니메이션 종료 후 값 유지
};
Storyboard.SetTargetProperty(ClockOpacity, new PropertyPath(OpacityProperty));
Storyboard.SetTargetName(thicknessAnimation, "ClockPanel");
Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(MarginProperty));
- Storyboard.SetTarget(WindowOpacity, this);
- Storyboard.SetTargetProperty(WindowOpacity, new PropertyPath(Window.OpacityProperty));
- Storyboard.SetTargetProperty(WindowMotion, new PropertyPath(Window.TopProperty));
Storyboard.SetTargetProperty(IconMotion, new PropertyPath(TopProperty));
Storyboard.SetTargetProperty(IconOpacity, new PropertyPath(OpacityProperty));
clocksb.Children.Add(thicknessAnimation);
clocksb.Children.Add(ClockOpacity);
- windowsb.Children.Add(WindowOpacity);
- windowsb.Children.Add(WindowMotion);
iconsb.Children.Add(IconMotion);
iconsb.Children.Add(IconOpacity);
- windowsb.Completed += (_, _) => _animating = false;
- _settings.WindowLeft = Left;
- _settings.WindowTop = Top;
- isArrowKeyPressed = false;
+ // ✅ 애니메이션 완료 후 _animating 상태를 안전하게 변경
+ clocksb.Completed += (_, _) => _animating = false;
+ iconsb.Completed += (_, _) => _animating = false;
+ // ✅ 시계와 아이콘 애니메이션 실행
if (QueryTextBox.Text.Length == 0)
{
- clocksb.Begin(ClockPanel);
+ clocksb.Begin(ClockPanel, HandoffBehavior.SnapshotAndReplace, true);
}
- iconsb.Begin(SearchIcon);
- windowsb.Begin(FlowMainWindow);
+ iconsb.Begin(SearchIcon, HandoffBehavior.SnapshotAndReplace, true);
}
+
private void InitSoundEffects()
{
if (_settings.WMPInstalled)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8140d80e2fe..43878266eec 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1385,15 +1385,14 @@ public void Show()
Application.Current.Dispatcher.Invoke(() =>
{
MainWindowVisibility = Visibility.Visible;
-
- MainWindowOpacity = 1;
+ MainWindowOpacity = Settings.UseAnimation ? 0 : 1;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
- public async void Hide()
+ public void Hide()
{
lastHistoryIndex = 1;
@@ -1412,29 +1411,9 @@ public async void Hide()
if (Settings.LastQueryMode == LastQueryMode.Empty)
{
ChangeQueryText(string.Empty);
- await Task.Yield(); // UI 갱신 보장
- }
-
- switch (Settings.LastQueryMode)
- {
- case LastQueryMode.Preserved:
- case LastQueryMode.Selected:
- LastQuerySelected = (Settings.LastQueryMode == LastQueryMode.Preserved);
- break;
-
- case LastQueryMode.ActionKeywordPreserved:
- case LastQueryMode.ActionKeywordSelected:
- var newQuery = _lastQuery.ActionKeyword;
- if (!string.IsNullOrEmpty(newQuery))
- newQuery += " ";
- ChangeQueryText(newQuery);
-
- if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected)
- LastQuerySelected = false;
- break;
}
- // 창 숨김 즉시 처리
+ // 즉시 창 숨김
MainWindowVisibilityStatus = false;
MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
From 92e6e53ab4a01d7eb201b6499dd814fdd92f573a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 5 Mar 2025 13:39:25 +0800
Subject: [PATCH 0395/1335] Use dependency injection instead of navigation
parameter
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs | 11 ++++-------
Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs | 8 ++------
Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs | 9 +++------
Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs | 9 +++------
Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs | 9 +++------
.../ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
Flow.Launcher/WelcomeWindow.xaml.cs | 12 ++++--------
8 files changed, 21 insertions(+), 41 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 3f1bae090a3..3616e4c59ca 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -445,7 +445,7 @@ private void CheckFirstLaunch()
private void OpenWelcomeWindow()
{
- var WelcomeWindow = new WelcomeWindow(_settings);
+ var WelcomeWindow = new WelcomeWindow();
WelcomeWindow.Show();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 98fb47288ea..8d4312ba57a 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Core.Resource;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Resources.Pages
{
@@ -10,10 +10,7 @@ public partial class WelcomePage1
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (e.ExtraData is Settings settings)
- Settings = settings;
- else
- throw new ArgumentException("Unexpected Navigation Parameter for Settings");
+ Settings = Ioc.Default.GetRequiredService();
InitializeComponent();
}
private Internationalization _translater => InternationalizationManager.Instance;
@@ -37,4 +34,4 @@ public string CustomLanguage
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 1ed5747cdc6..4a4679a4aa3 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -1,11 +1,11 @@
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
-using System;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
using System.Windows.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Resources.Pages
{
@@ -15,11 +15,7 @@ public partial class WelcomePage2
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (e.ExtraData is Settings settings)
- Settings = settings;
- else
- throw new ArgumentException("Unexpected Parameter setting.");
-
+ Settings = Ioc.Default.GetRequiredService();
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index 9051e7c2798..38cb8642a2d 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -1,5 +1,5 @@
-using System;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.Resources.Pages
@@ -8,10 +8,7 @@ public partial class WelcomePage3
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (e.ExtraData is Settings settings)
- Settings = settings;
- else if(Settings is null)
- throw new ArgumentException("Unexpected Navigation Parameter for Settings");
+ Settings = Ioc.Default.GetRequiredService();
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index 11bbcd6ed22..fc656893533 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -1,5 +1,5 @@
-using Flow.Launcher.Infrastructure.UserSettings;
-using System;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.UserSettings;
using System.Windows.Navigation;
namespace Flow.Launcher.Resources.Pages
@@ -8,10 +8,7 @@ public partial class WelcomePage4
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (e.ExtraData is Settings settings)
- Settings = settings;
- else
- throw new ArgumentException("Unexpected Navigation Parameter for Settings");
+ Settings = Ioc.Default.GetRequiredService();
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index abb8053035c..5327eb5c858 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Windows;
+using System.Windows;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
using Flow.Launcher.Infrastructure;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Resources.Pages
{
@@ -15,10 +15,7 @@ public partial class WelcomePage5
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (e.ExtraData is Settings settings)
- Settings = settings;
- else
- throw new ArgumentException("Unexpected Navigation Parameter for Settings");
+ Settings = Ioc.Default.GetRequiredService();
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index ade65028472..6606b00f01c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -54,7 +54,7 @@ public SettingsPaneAboutViewModel(Settings settings, Updater updater)
[RelayCommand]
private void OpenWelcomeWindow()
{
- var window = new WelcomeWindow(_settings);
+ var window = new WelcomeWindow();
window.ShowDialog();
}
diff --git a/Flow.Launcher/WelcomeWindow.xaml.cs b/Flow.Launcher/WelcomeWindow.xaml.cs
index c3723a8c529..1d55b5741a2 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -2,7 +2,6 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Resources.Pages;
using ModernWpf.Media.Animation;
@@ -10,13 +9,10 @@ namespace Flow.Launcher
{
public partial class WelcomeWindow : Window
{
- private readonly Settings settings;
-
- public WelcomeWindow(Settings settings)
+ public WelcomeWindow()
{
InitializeComponent();
BackButton.IsEnabled = false;
- this.settings = settings;
}
private NavigationTransitionInfo _transitionInfo = new SlideNavigationTransitionInfo()
@@ -57,7 +53,7 @@ private void ForwardButton_Click(object sender, RoutedEventArgs e)
pageNum++;
UpdateView();
- ContentFrame.Navigate(PageTypeSelector(pageNum), settings, _transitionInfo);
+ ContentFrame.Navigate(PageTypeSelector(pageNum), null, _transitionInfo);
}
private void BackwardButton_Click(object sender, RoutedEventArgs e)
@@ -66,7 +62,7 @@ private void BackwardButton_Click(object sender, RoutedEventArgs e)
{
pageNum--;
UpdateView();
- ContentFrame.Navigate(PageTypeSelector(pageNum), settings, _backTransitionInfo);
+ ContentFrame.Navigate(PageTypeSelector(pageNum), null, _backTransitionInfo);
}
else
{
@@ -109,7 +105,7 @@ private void OnActivated(object sender, EventArgs e)
private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
- ContentFrame.Navigate(PageTypeSelector(1), settings); /* Set First Page */
+ ContentFrame.Navigate(PageTypeSelector(1)); /* Set First Page */
}
}
}
From f2248e93b18d92dfc1c4d9d0920f2d9167044702 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 5 Mar 2025 14:42:08 +0800
Subject: [PATCH 0396/1335] Use dependency injection instead of dependency
property
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 1 -
Flow.Launcher/HotkeyControl.xaml.cs | 139 +++++++++++++++---
Flow.Launcher/HotkeyControlDialog.xaml.cs | 7 +-
.../Resources/Pages/WelcomePage2.xaml | 3 +-
.../Views/SettingsPaneHotkey.xaml | 42 ++----
5 files changed, 137 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 70ebb404b91..ccf4de8706b 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -103,7 +103,6 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
HorizontalContentAlignment="Left"
- HotkeySettings="{Binding Settings}"
DefaultHotkey="" />
();
+
public string Hotkey
{
- get { return (string)GetValue(HotkeyProperty); }
- set { SetValue(HotkeyProperty, value); }
+ get
+ {
+ return Type switch
+ {
+ HotkeyType.Hotkey => _settings.Hotkey,
+ HotkeyType.PreviewHotkey => _settings.PreviewHotkey,
+ HotkeyType.OpenContextMenuHotkey => _settings.OpenContextMenuHotkey,
+ HotkeyType.SettingWindowHotkey => _settings.SettingWindowHotkey,
+ HotkeyType.CycleHistoryUpHotkey => _settings.CycleHistoryUpHotkey,
+ HotkeyType.CycleHistoryDownHotkey => _settings.CycleHistoryDownHotkey,
+ HotkeyType.SelectPrevPageHotkey => _settings.SelectPrevPageHotkey,
+ HotkeyType.SelectNextPageHotkey => _settings.SelectNextPageHotkey,
+ HotkeyType.AutoCompleteHotkey => _settings.AutoCompleteHotkey,
+ HotkeyType.AutoCompleteHotkey2 => _settings.AutoCompleteHotkey2,
+ HotkeyType.SelectPrevItemHotkey => _settings.SelectPrevItemHotkey,
+ HotkeyType.SelectPrevItemHotkey2 => _settings.SelectPrevItemHotkey2,
+ HotkeyType.SelectNextItemHotkey => _settings.SelectNextItemHotkey,
+ HotkeyType.SelectNextItemHotkey2 => _settings.SelectNextItemHotkey2,
+ _ => string.Empty
+ };
+ }
+ set
+ {
+ switch (Type)
+ {
+ case HotkeyType.Hotkey:
+ _settings.Hotkey = value;
+ break;
+ case HotkeyType.PreviewHotkey:
+ _settings.PreviewHotkey = value;
+ break;
+ case HotkeyType.OpenContextMenuHotkey:
+ _settings.OpenContextMenuHotkey = value;
+ break;
+ case HotkeyType.SettingWindowHotkey:
+ _settings.SettingWindowHotkey = value;
+ break;
+ case HotkeyType.CycleHistoryUpHotkey:
+ _settings.CycleHistoryUpHotkey = value;
+ break;
+ case HotkeyType.CycleHistoryDownHotkey:
+ _settings.CycleHistoryDownHotkey = value;
+ break;
+ case HotkeyType.SelectPrevPageHotkey:
+ _settings.SelectPrevPageHotkey = value;
+ break;
+ case HotkeyType.SelectNextPageHotkey:
+ _settings.SelectNextPageHotkey = value;
+ break;
+ case HotkeyType.AutoCompleteHotkey:
+ _settings.AutoCompleteHotkey = value;
+ break;
+ case HotkeyType.AutoCompleteHotkey2:
+ _settings.AutoCompleteHotkey2 = value;
+ break;
+ case HotkeyType.SelectPrevItemHotkey:
+ _settings.SelectPrevItemHotkey = value;
+ break;
+ case HotkeyType.SelectNextItemHotkey:
+ _settings.SelectNextItemHotkey = value;
+ break;
+ case HotkeyType.SelectPrevItemHotkey2:
+ _settings.SelectPrevItemHotkey2 = value;
+ break;
+ case HotkeyType.SelectNextItemHotkey2:
+ _settings.SelectNextItemHotkey2 = value;
+ break;
+ default:
+ return;
+ }
+
+ // After setting the hotkey, we need to refresh the interface
+ RefreshHotkeyInterface(Hotkey);
+ }
}
public HotkeyControl()
@@ -108,7 +198,14 @@ public HotkeyControl()
InitializeComponent();
HotkeyList.ItemsSource = KeysToDisplay;
- SetKeysToDisplay(CurrentHotkey);
+
+ RefreshHotkeyInterface(Hotkey);
+ }
+
+ public void RefreshHotkeyInterface(string hotkey)
+ {
+ SetKeysToDisplay(new HotkeyModel(Hotkey));
+ CurrentHotkey = new HotkeyModel(Hotkey);
}
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
@@ -133,7 +230,7 @@ private async Task OpenHotkeyDialog()
HotKeyMapper.RemoveHotkey(Hotkey);
}
- var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, HotkeySettings, WindowTitle);
+ var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle);
await dialog.ShowAsync();
switch (dialog.ResultType)
{
diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs
index a4d21a7827b..2f8c5eb2616 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -4,9 +4,11 @@
using System.Windows;
using System.Windows.Input;
using ChefKeys;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using ModernWpf.Controls;
@@ -16,7 +18,7 @@ namespace Flow.Launcher;
public partial class HotkeyControlDialog : ContentDialog
{
- private IHotkeySettings _hotkeySettings;
+ private static readonly IHotkeySettings _hotkeySettings = Ioc.Default.GetRequiredService();
private Action? _overwriteOtherHotkey;
private string DefaultHotkey { get; }
public string WindowTitle { get; }
@@ -36,7 +38,7 @@ public enum EResultType
private static bool isOpenFlowHotkey;
- public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings hotkeySettings, string windowTitle = "")
+ public HotkeyControlDialog(string hotkey, string defaultHotkey, string windowTitle = "")
{
WindowTitle = windowTitle switch
{
@@ -45,7 +47,6 @@ public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings
};
DefaultHotkey = defaultHotkey;
CurrentHotkey = new HotkeyModel(hotkey);
- _hotkeySettings = hotkeySettings;
SetKeysToDisplay(CurrentHotkey);
InitializeComponent();
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
index 6c6fcbb625f..04c76d0277f 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
@@ -114,8 +114,7 @@
Margin="0,8,0,0"
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space"
- Hotkey="{Binding Settings.Hotkey}"
- HotkeySettings="{Binding Settings}"
+ Type="Hotkey"
ValidateKeyGesture="True"
WindowTitle="{DynamicResource flowlauncherHotkey}" />
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
index 22e3960ef19..b1d72ede5bf 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml
@@ -34,8 +34,7 @@
@@ -46,8 +45,7 @@
Sub="{DynamicResource previewHotkeyToolTip}">
@@ -105,8 +103,7 @@
Type="Inside">
@@ -221,8 +213,7 @@
@@ -244,8 +234,7 @@
@@ -267,8 +255,7 @@
From c68a764dcfcf1842224bee88ed136de67d08f510 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 5 Mar 2025 14:52:14 +0800
Subject: [PATCH 0397/1335] Improve code quality
---
Flow.Launcher/HotkeyControl.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index 869774882cd..273d18e3f5d 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -111,7 +111,7 @@ public enum HotkeyType
SelectNextItemHotkey2
}
- // We can initialize settings in static field because it has been construct in App constuctor
+ // We can initialize settings in static field because it has been constructed in App constuctor
// and it will not construct settings instances twice
private static readonly Settings _settings = Ioc.Default.GetRequiredService();
@@ -202,7 +202,7 @@ public HotkeyControl()
RefreshHotkeyInterface(Hotkey);
}
- public void RefreshHotkeyInterface(string hotkey)
+ private void RefreshHotkeyInterface(string hotkey)
{
SetKeysToDisplay(new HotkeyModel(Hotkey));
CurrentHotkey = new HotkeyModel(Hotkey);
From 31d47a2340173b09ec30b1d1e6ab201796204fc1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 5 Mar 2025 15:18:06 +0800
Subject: [PATCH 0398/1335] Use dependency injection instead of navigation
parameter
---
.../SettingPages/Views/SettingsPaneAbout.xaml.cs | 10 ++++++----
.../SettingPages/Views/SettingsPaneGeneral.xaml.cs | 11 +++++++----
.../SettingPages/Views/SettingsPaneHotkey.xaml.cs | 8 ++++----
.../Views/SettingsPanePluginStore.xaml.cs | 8 ++++----
.../SettingPages/Views/SettingsPanePlugins.xaml.cs | 8 ++++----
.../SettingPages/Views/SettingsPaneProxy.xaml.cs | 10 ++++++----
.../SettingPages/Views/SettingsPaneTheme.xaml.cs | 10 ++++------
Flow.Launcher/SettingWindow.xaml.cs | 13 ++-----------
8 files changed, 37 insertions(+), 41 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index de6a4df5ee8..1ecc02aa6b3 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -1,6 +1,8 @@
-using System;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
+using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Infrastructure.UserSettings;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.SettingPages.Views;
@@ -12,8 +14,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: { } updater })
- throw new ArgumentException("Settings are required for SettingsPaneAbout.");
+ var settings = Ioc.Default.GetRequiredService();
+ var updater = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPaneAboutViewModel(settings, updater);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index f95015b2eef..dd7fd13a995 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -1,5 +1,7 @@
-using System;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
+using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
@@ -13,8 +15,9 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: {} updater, Portable: {} portable })
- throw new ArgumentException("Settings, Updater and Portable are required for SettingsPaneGeneral.");
+ var settings = Ioc.Default.GetRequiredService();
+ var updater = Ioc.Default.GetRequiredService();
+ var portable = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 061eabf515d..eb100da0ca8 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -1,6 +1,7 @@
-using System;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -12,8 +13,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
- throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
+ var settings = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPaneHotkeyViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index db476331908..3bd24bc1323 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -1,10 +1,11 @@
-using System;
-using System.ComponentModel;
+using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -16,8 +17,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
- throw new ArgumentException($"Settings are required for {nameof(SettingsPanePluginStore)}.");
+ var settings = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPanePluginStoreViewModel();
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index d48505c3dbe..f6b4351864e 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -1,7 +1,8 @@
-using System;
-using System.Windows.Input;
+using System.Windows.Input;
using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -13,8 +14,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
- throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
+ var settings = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPanePluginsViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
index 95c88d6277b..26350b8bbd5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
@@ -1,6 +1,8 @@
-using System;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -12,8 +14,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: { } updater })
- throw new ArgumentException($"Settings are required for {nameof(SettingsPaneProxy)}.");
+ var settings = Ioc.Default.GetRequiredService();
+ var updater = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPaneProxyViewModel(settings, updater);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index 7f32728c217..bf7502e1927 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -1,10 +1,9 @@
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
+using System.Windows.Controls;
using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Page = ModernWpf.Controls.Page;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -16,8 +15,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
- throw new ArgumentException($"Settings are required for {nameof(SettingsPaneTheme)}.");
+ var settings = Ioc.Default.GetRequiredService();
_viewModel = new SettingsPaneThemeViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index f87194c30cb..30b51f992b0 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -4,8 +4,6 @@
using System.Windows.Input;
using System.Windows.Interop;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -18,8 +16,6 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
- private readonly Updater _updater;
- private readonly IPortable _portable;
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
@@ -30,8 +26,6 @@ public SettingWindow()
_settings = Ioc.Default.GetRequiredService();
DataContext = viewModel;
_viewModel = viewModel;
- _updater = Ioc.Default.GetRequiredService();
- _portable = Ioc.Default.GetRequiredService();
_api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
@@ -166,10 +160,9 @@ private double WindowTop()
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
- var paneData = new PaneData(_settings, _updater, _portable);
if (args.IsSettingsSelected)
{
- ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
+ ContentFrame.Navigate(typeof(SettingsPaneGeneral));
}
else
{
@@ -191,7 +184,7 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
nameof(About) => typeof(SettingsPaneAbout),
_ => typeof(SettingsPaneGeneral)
};
- ContentFrame.Navigate(pageType, paneData);
+ ContentFrame.Navigate(pageType);
}
}
@@ -211,6 +204,4 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
-
- public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
}
From 719d30ebf0a09e54a46948a786caa6069303ca0e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 6 Mar 2025 07:41:22 +0800
Subject: [PATCH 0399/1335] Use official Task Scheduler
---
Flow.Launcher/Flow.Launcher.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 33d13614f8a..8f6e47bbba8 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,7 +104,7 @@
-
+
From 8ce4bd92e2d39331b40b5a6cc1344b4dd262a3a6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Mar 2025 10:44:15 +0800
Subject: [PATCH 0400/1335] Fix page number issue when navigating with keyboard
---
Flow.Launcher/App.xaml.cs | 1 +
.../Resources/Pages/WelcomePage1.xaml.cs | 4 ++
.../Resources/Pages/WelcomePage2.xaml.cs | 3 +
.../Resources/Pages/WelcomePage3.xaml.cs | 4 ++
.../Resources/Pages/WelcomePage4.xaml.cs | 4 ++
.../Resources/Pages/WelcomePage5.xaml.cs | 4 ++
Flow.Launcher/ViewModel/WelcomeViewModel.cs | 68 +++++++++++++++++++
Flow.Launcher/WelcomeWindow.xaml | 25 ++++---
Flow.Launcher/WelcomeWindow.xaml.cs | 62 ++++++++---------
9 files changed, 130 insertions(+), 45 deletions(-)
create mode 100644 Flow.Launcher/ViewModel/WelcomeViewModel.cs
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 447eca79267..07b721b9991 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -64,6 +64,7 @@ public App()
.AddSingleton()
.AddSingleton()
.AddSingleton()
+ .AddSingleton()
).Build();
Ioc.Default.ConfigureServices(host.Services);
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 8d4312ba57a..880bfd9bcc2 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -3,6 +3,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@@ -11,6 +12,9 @@ public partial class WelcomePage1
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService();
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ Ioc.Default.GetRequiredService().PageNum = 1;
InitializeComponent();
}
private Internationalization _translater => InternationalizationManager.Instance;
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 4a4679a4aa3..786b4d5063d 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,6 +16,9 @@ public partial class WelcomePage2
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService();
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ Ioc.Default.GetRequiredService().PageNum = 2;
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index 38cb8642a2d..f59b65c1c4c 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -1,6 +1,7 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@@ -9,6 +10,9 @@ public partial class WelcomePage3
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService();
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ Ioc.Default.GetRequiredService().PageNum = 3;
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index fc656893533..4c83f3a83e0 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -1,5 +1,6 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.ViewModel;
using System.Windows.Navigation;
namespace Flow.Launcher.Resources.Pages
@@ -9,6 +10,9 @@ public partial class WelcomePage4
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService();
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ Ioc.Default.GetRequiredService().PageNum = 4;
InitializeComponent();
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index 5327eb5c858..95d7ff1a0d2 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -4,6 +4,7 @@
using Microsoft.Win32;
using Flow.Launcher.Infrastructure;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@@ -16,6 +17,9 @@ public partial class WelcomePage5
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Settings = Ioc.Default.GetRequiredService();
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ Ioc.Default.GetRequiredService().PageNum = 5;
InitializeComponent();
}
diff --git a/Flow.Launcher/ViewModel/WelcomeViewModel.cs b/Flow.Launcher/ViewModel/WelcomeViewModel.cs
new file mode 100644
index 00000000000..5eecabfde85
--- /dev/null
+++ b/Flow.Launcher/ViewModel/WelcomeViewModel.cs
@@ -0,0 +1,68 @@
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.ViewModel
+{
+ public partial class WelcomeViewModel : BaseModel
+ {
+ public const int MaxPageNum = 5;
+
+ public string PageDisplay => $"{PageNum}/5";
+
+ private int _pageNum = 1;
+ public int PageNum
+ {
+ get => _pageNum;
+ set
+ {
+ if (_pageNum != value)
+ {
+ _pageNum = value;
+ OnPropertyChanged();
+ UpdateView();
+ }
+ }
+ }
+
+ private bool _backEnabled = false;
+ public bool BackEnabled
+ {
+ get => _backEnabled;
+ set
+ {
+ _backEnabled = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _nextEnabled = true;
+ public bool NextEnabled
+ {
+ get => _nextEnabled;
+ set
+ {
+ _nextEnabled = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private void UpdateView()
+ {
+ OnPropertyChanged(nameof(PageDisplay));
+ if (PageNum == 1)
+ {
+ BackEnabled = false;
+ NextEnabled = true;
+ }
+ else if (PageNum == MaxPageNum)
+ {
+ BackEnabled = true;
+ NextEnabled = false;
+ }
+ else
+ {
+ BackEnabled = true;
+ NextEnabled = true;
+ }
+ }
+ }
+}
diff --git a/Flow.Launcher/WelcomeWindow.xaml b/Flow.Launcher/WelcomeWindow.xaml
index 73f423d0ba6..e7c483f89b5 100644
--- a/Flow.Launcher/WelcomeWindow.xaml
+++ b/Flow.Launcher/WelcomeWindow.xaml
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Flow.Launcher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
+ xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
Name="FlowWelcomeWindow"
Title="{DynamicResource Welcome_Page1_Title}"
Width="550"
@@ -14,8 +15,10 @@
MinHeight="650"
MaxWidth="550"
MaxHeight="650"
+ d:DataContext="{d:DesignInstance Type=vm:WelcomeViewModel}"
Activated="OnActivated"
Background="{DynamicResource Color00B}"
+ Closed="Window_Closed"
Foreground="{DynamicResource PopupTextColor}"
MouseDown="window_MouseDown"
WindowStartupLocation="CenterScreen"
@@ -41,12 +44,12 @@
Grid.Column="0"
Width="16"
Height="16"
- Margin="10,4,4,4"
+ Margin="10 4 4 4"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Images/app.png" />
+ BorderThickness="0 1 0 0">
@@ -109,11 +112,11 @@
VerticalAlignment="Center">
@@ -122,25 +125,26 @@
Grid.Column="0"
Width="100"
Height="40"
- Margin="20,5,0,5"
+ Margin="20 5 0 5"
Click="BtnCancel_OnClick"
Content="{DynamicResource Skip}"
DockPanel.Dock="Right"
FontSize="14" />
+ FontSize="18"
+ IsEnabled="{Binding NextEnabled, Mode=OneWay}" />
+ FontSize="18"
+ IsEnabled="{Binding BackEnabled, Mode=OneWay}" />
diff --git a/Flow.Launcher/WelcomeWindow.xaml.cs b/Flow.Launcher/WelcomeWindow.xaml.cs
index 1d55b5741a2..637f9448d9a 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -4,69 +4,55 @@
using System.Windows.Controls;
using Flow.Launcher.Resources.Pages;
using ModernWpf.Media.Animation;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.ViewModel;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class WelcomeWindow : Window
{
- public WelcomeWindow()
- {
- InitializeComponent();
- BackButton.IsEnabled = false;
- }
+ private readonly WelcomeViewModel _viewModel;
- private NavigationTransitionInfo _transitionInfo = new SlideNavigationTransitionInfo()
+ private readonly NavigationTransitionInfo _forwardTransitionInfo = new SlideNavigationTransitionInfo()
{
Effect = SlideNavigationTransitionEffect.FromRight
};
- private NavigationTransitionInfo _backTransitionInfo = new SlideNavigationTransitionInfo()
+ private readonly NavigationTransitionInfo _backTransitionInfo = new SlideNavigationTransitionInfo()
{
Effect = SlideNavigationTransitionEffect.FromLeft
};
- private int pageNum = 1;
- private int MaxPage = 5;
- public string PageDisplay => $"{pageNum}/5";
+ public WelcomeWindow()
+ {
+ _viewModel = Ioc.Default.GetRequiredService();
+ DataContext = _viewModel;
+ InitializeComponent();
+ }
- private void UpdateView()
+ private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
- PageNavigation.Text = PageDisplay;
- if (pageNum == 1)
+ if (_viewModel.PageNum < WelcomeViewModel.MaxPageNum)
{
- BackButton.IsEnabled = false;
- NextButton.IsEnabled = true;
- }
- else if (pageNum == MaxPage)
- {
- BackButton.IsEnabled = true;
- NextButton.IsEnabled = false;
+ _viewModel.PageNum++;
+ ContentFrame.Navigate(PageTypeSelector(_viewModel.PageNum), null, _forwardTransitionInfo);
}
else
{
- BackButton.IsEnabled = true;
- NextButton.IsEnabled = true;
+ _viewModel.NextEnabled = false;
}
}
- private void ForwardButton_Click(object sender, RoutedEventArgs e)
- {
- pageNum++;
- UpdateView();
-
- ContentFrame.Navigate(PageTypeSelector(pageNum), null, _transitionInfo);
- }
-
private void BackwardButton_Click(object sender, RoutedEventArgs e)
{
- if (pageNum > 1)
+ if (_viewModel.PageNum > 1)
{
- pageNum--;
- UpdateView();
- ContentFrame.Navigate(PageTypeSelector(pageNum), null, _backTransitionInfo);
+ _viewModel.PageNum--;
+ ContentFrame.Navigate(PageTypeSelector(_viewModel.PageNum), null, _backTransitionInfo);
}
else
{
- BackButton.IsEnabled = false;
+ _viewModel.BackEnabled = false;
}
}
@@ -107,5 +93,11 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
ContentFrame.Navigate(PageTypeSelector(1)); /* Set First Page */
}
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ // Save settings when window is closed
+ Ioc.Default.GetRequiredService().Save();
+ }
}
}
From 4ab5ef03f76d333e977b5c84c8604c1052fc0820 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 12:30:55 +0900
Subject: [PATCH 0401/1335] Adjust Animation
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index ae1f5d04ca3..e4c92b936f5 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ public void WindowAnimator()
var WindowMotion = new DoubleAnimation
{
- From = Top + 10,
+ From = Top,
To = Top,
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
From 2a55cabeff247f941637fd0edd57e20205e93bbc Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 12:50:57 +0900
Subject: [PATCH 0402/1335] Fix Show Function
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e4c92b936f5..ae1f5d04ca3 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ public void WindowAnimator()
var WindowMotion = new DoubleAnimation
{
- From = Top,
+ From = Top + 10,
To = Top,
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 43878266eec..fa64348cf00 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1385,7 +1385,7 @@ public void Show()
Application.Current.Dispatcher.Invoke(() =>
{
MainWindowVisibility = Visibility.Visible;
- MainWindowOpacity = Settings.UseAnimation ? 0 : 1;
+ MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
From 40ca75a3f331e3b3d328e7fd0edbe21ad05f2220 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 13:12:11 +0900
Subject: [PATCH 0403/1335] Adjust Comment, Adjust Shadow Timing.
---
Flow.Launcher.Core/Resource/Theme.cs | 117 +++++----------------------
Flow.Launcher/MainWindow.xaml.cs | 2 +-
2 files changed, 23 insertions(+), 96 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 2bf8a5d3526..edf1da05e8b 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -139,7 +139,6 @@ public void RefreshFrame()
HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
if (mainWindowSrc == null)
return;
- //mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 255, 181, 178);
ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
margins.cxLeftWidth = -1;
@@ -154,26 +153,17 @@ public void RefreshFrame()
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- //if (!_settings.UseDropShadowEffect && BlurEnabled)
- //{
- // _settings.UseDropShadowEffect = true;
- // AddDropShadowEffectToCurrentTheme();
- //}
-
- //if (_settings.UseDropShadowEffect)
- //{
- // AddDropShadowEffectToCurrentTheme();
- //}
- //AutoDropShadow();
+ // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
+ if (BlurEnabled)
+ {
+ AutoDropShadow();
+ }
SetBlurForWindow();
- //else if (!_settings.usedropshadoweffect && blurenabled)
- //{
- // adddropshadoweffecttocurrenttheme();
- // _settings.usedropshadoweffect = true;
- //}
-
- //SetCornerForWindow();
+ if (!BlurEnabled)
+ {
+ AutoDropShadow();
+ }
}
public void AutoDropShadow()
@@ -183,13 +173,11 @@ public void AutoDropShadow()
RemoveDropShadowEffectFromCurrentTheme();
if (BlurEnabled)
{
- Debug.WriteLine("이거는 블러있는 테마이므로 외곽선 주고 그림자");
SetWindowCornerPreference("Round");
}
else
{
SetWindowCornerPreference("Default");
- Debug.WriteLine("이거는 블러없는 테마");
AddDropShadowEffectToCurrentTheme();
}
}
@@ -251,7 +239,7 @@ public void SetCornerForWindow()
///
public void SetBlurForWindow()
{
- //AutoDropShadow();
+
//SetWindowAccent();
var dict = GetThemeResourceDictionary(_settings.Theme);
if (dict == null)
@@ -270,7 +258,7 @@ public void SetBlurForWindow()
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- SetWindowCornerPreference("Round");
+ //SetWindowCornerPreference("Round");
}
else
{
@@ -280,27 +268,15 @@ public void SetBlurForWindow()
// windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
//}
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1);
- SetWindowCornerPreference("Default");
- if (_settings.UseDropShadowEffect)
- {
-
- AddDropShadowEffectToCurrentTheme();
- }
- else
- {
- RemoveDropShadowEffectFromCurrentTheme();
- }
-
}
ThemeModeColor(BlurMode());
-
UpdateResourceDictionary(dict);
}
- // WindowBorderStyle에서 Background 색상 가져오는 함수
+ // Get Background Color from WindowBorderStyle when there not color for BG.
private Color GetWindowBorderStyleBackground()
{
var Resources = GetThemeResourceDictionary(_settings.Theme);
@@ -312,19 +288,19 @@ private Color GetWindowBorderStyleBackground()
if (backgroundSetter != null)
{
- // Background의 Value가 DynamicColor일 경우 처리
+ // Background's Value is DynamicColor Case
var backgroundValue = backgroundSetter.Value;
if (backgroundValue is SolidColorBrush solidColorBrush)
{
- return solidColorBrush.Color; // SolidColorBrush의 Color 반환
+ return solidColorBrush.Color; // Return SolidColorBrush's Color
}
else if (backgroundValue is DynamicResourceExtension dynamicResource)
{
- // DynamicResource Extension을 처리할 때, Key는 리소스에 대한 이름입니다.
+ // When DynamicResource Extension it is, Key is resource's name.
var resourceKey = backgroundSetter.Value.ToString();
- // 리소스에서 해당 키를 찾아 색상 반환
+ // find key in resource and return color.
if (Resources.Contains(resourceKey))
{
var colorResource = Resources[resourceKey];
@@ -340,7 +316,7 @@ private Color GetWindowBorderStyleBackground()
}
}
- return Colors.Transparent; // 기본값: 투명
+ return Colors.Transparent; // Default is transparent
}
public void ThemeModeColor(string Mode)
@@ -350,26 +326,25 @@ public void ThemeModeColor(string Mode)
Color lightBG;
Color darkBG;
- // lightBG 값을 가져오기 (없으면 WindowBorderStyle의 Background 값 사용)
+ // get lightBG value. if not, get windowborderstyle's background.
try
{
- // dict["lightBG"] 값이 없거나 null이면 WindowBorderStyle의 Background 값 사용
lightBG = dict.Contains("lightBG") ? (Color)dict["lightBG"] : GetWindowBorderStyleBackground();
}
catch (Exception)
{
- // lightBG가 없으면 WindowBorderStyle의 Background 값 사용
+ // if not lightBG, use windowborderstyle's background.
lightBG = GetWindowBorderStyleBackground();
}
- // darkBG 값을 가져오기 (없으면 lightBG 값으로 설정)
+ // get darkBG value, (if not, use lightBG)
try
{
darkBG = dict.Contains("darkBG") ? (Color)dict["darkBG"] : lightBG;
}
catch (Exception)
{
- darkBG = lightBG; // darkBG가 없으면 lightBG 값을 사용
+ darkBG = lightBG; // if not darkBG, use lightBG
}
@@ -377,7 +352,7 @@ public void ThemeModeColor(string Mode)
{
int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
string colorScheme = _settings.ColorScheme;
- bool isDarkMode = themeValue == 0; // 0이면 다크 모드
+ bool isDarkMode = themeValue == 0; // 0 is dark mode.
if (colorScheme == "System")
{
if (isDarkMode)
@@ -423,39 +398,9 @@ public void ThemeModeColor(string Mode)
}
else
{
- //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
mainWindow.Background = new SolidColorBrush(Colors.Transparent);
}
}
- public void BlurColor(string Color)
- {
-
- if (Color == "Light")
- {
- //mainWindow.Background = new SolidColorBrush(defaultBGcolor.Value);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- }
- else if (Color == "Dark")
- {
- //mainWindow.Background = new SolidColorBrush(darkBGcolor.Value);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- }
- else /* Case of "Auto" Blur Type Theme */
- {
- //if (_isDarkTheme())
- //{
- // mainWindow.Background = new SolidColorBrush(darkBGcolor.Value);
- // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- //}
- //else
- //{
- // mainWindow.Background = new SolidColorBrush(defaultBGcolor.Value);
- // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- //}
- //mainWindow.Background = new SolidColorBrush(Colors.Red);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1); }
-
- }
public bool IsBlurTheme()
{
@@ -486,24 +431,6 @@ public string BlurMode()
return null;
}
- //public SolidColorBrush BGColor(string colorBgKey)
- //{
- // var defaultBG = Application.Current.TryFindResource("DefaultBG");
- // var darkBG = Application.Current.TryFindResource("DarkBG");
-
- // if (colorBgKey == "")
- // {
- // var resource = Application.Current.TryFindResource("BlurMode");
-
- // if (resource is string)
- // return (SolidColorBrush)resource;
-
- // return new SolidColorBrush(Colors.DarkGray);
- // }
-
- // return null;
- //}
-
#endregion
private void MakeSureThemeDirectoriesExist()
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index ae1f5d04ca3..e4c92b936f5 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -509,7 +509,7 @@ public void WindowAnimator()
var WindowMotion = new DoubleAnimation
{
- From = Top + 10,
+ From = Top,
To = Top,
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
From 758717848c5f52456aa4294b650b67b23faa43ba Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 13:33:36 +0900
Subject: [PATCH 0404/1335] Adjust Hide function for fix blink issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 42 ++++++++++++++++++++----
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index fa64348cf00..71bc36b2d81 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -26,6 +26,7 @@
using Flow.Launcher.Infrastructure.Image;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
+using System.Windows.Threading;
namespace Flow.Launcher.ViewModel
{
@@ -1392,7 +1393,7 @@ public void Show()
});
}
- public void Hide()
+ public async void Hide()
{
lastHistoryIndex = 1;
@@ -1407,18 +1408,47 @@ public void Hide()
SelectedResults = Results;
}
- // 텍스트 초기화 즉시 적용
- if (Settings.LastQueryMode == LastQueryMode.Empty)
+ // 📌 모든 LastQueryMode에서 텍스트 필드 즉시 업데이트 + 강제 UI 갱신
+ Application.Current.Dispatcher.Invoke(() =>
{
- ChangeQueryText(string.Empty);
- }
+ switch (Settings.LastQueryMode)
+ {
+ case LastQueryMode.Empty:
+ ChangeQueryText(string.Empty);
+ break;
+
+ case LastQueryMode.Preserved:
+ LastQuerySelected = true;
+ break;
+
+ case LastQueryMode.Selected:
+ LastQuerySelected = false;
+ break;
- // 즉시 창 숨김
+ case LastQueryMode.ActionKeywordPreserved:
+ case LastQueryMode.ActionKeywordSelected:
+ var newQuery = _lastQuery.ActionKeyword;
+ if (!string.IsNullOrEmpty(newQuery))
+ newQuery += " ";
+ ChangeQueryText(newQuery);
+
+ if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected)
+ LastQuerySelected = false;
+ break;
+ }
+
+ // 📌 UI 강제 갱신
+ Application.Current.MainWindow.UpdateLayout();
+ }, DispatcherPriority.Render); // UI 스레드에서 즉시 실행
+
+ // 📌 창 숨김 처리 (텍스트 변경 후)
MainWindowVisibilityStatus = false;
MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
}
+
+
///
/// Checks if Flow Launcher should ignore any hotkeys
///
From 4042231fb354c7fa0e0d97f60823cc434e76197f Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 14:14:25 +0900
Subject: [PATCH 0405/1335] Fix blink issue when fast trigering show/hide
---
Flow.Launcher/MainWindow.xaml.cs | 63 ++++++++++++++++++------
Flow.Launcher/ViewModel/MainViewModel.cs | 16 +++---
2 files changed, 58 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e4c92b936f5..a661041035d 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -27,6 +27,9 @@
using System.Windows.Media;
using System.Windows.Interop;
using Windows.Win32;
+using Microsoft.VisualBasic.Devices;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement;
+using Window = System.Windows.Window;
namespace Flow.Launcher
{
@@ -46,6 +49,11 @@ public partial class MainWindow
private MediaPlayer animationSoundWMP;
private SoundPlayer animationSoundWPF;
+ //For Window Animations
+ private Storyboard clocksb;
+ private Storyboard iconsb;
+ private Storyboard windowsb;
+
#endregion
public MainWindow(Settings settings, MainViewModel mainVM)
@@ -476,6 +484,19 @@ private void InitProgressbarAnimation()
isProgressBarStoryboardPaused = true;
}
+ public void ResetAnimation()
+ {
+ // 애니메이션 중지
+ clocksb?.Stop(ClockPanel);
+ iconsb?.Stop(SearchIcon);
+ windowsb?.Stop(FlowMainWindow);
+
+ // UI 요소 상태 초기화
+ ClockPanel.Margin = new Thickness(0, 0, ClockPanel.Margin.Right, 0);
+ ClockPanel.Opacity = 0;
+ SearchIcon.Opacity = 0;
+ }
+
public void WindowAnimator()
{
if (_animating)
@@ -485,11 +506,10 @@ public void WindowAnimator()
_animating = true;
UpdatePosition();
- Storyboard windowsb = new Storyboard();
- Storyboard clocksb = new Storyboard();
- Storyboard iconsb = new Storyboard();
- CircleEase easing = new CircleEase();
- easing.EasingMode = EasingMode.EaseInOut;
+ windowsb = new Storyboard();
+ clocksb = new Storyboard();
+ iconsb = new Storyboard();
+ CircleEase easing = new CircleEase { EasingMode = EasingMode.EaseInOut };
var animationLength = _settings.AnimationSpeed switch
{
@@ -501,19 +521,21 @@ public void WindowAnimator()
var WindowOpacity = new DoubleAnimation
{
- From = 0,
+ From = 1,
To = 1,
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
};
+ // 📌 항상 같은 위치에서 시작하도록 `_originalTop`을 사용
var WindowMotion = new DoubleAnimation
{
- From = Top,
- To = Top,
+ From = Top + 10, // 원래 위치에서 10px 내려온 후
+ To = Top, // 다시 원래 위치로 이동
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
};
+
var IconMotion = new DoubleAnimation
{
From = 12,
@@ -529,16 +551,17 @@ public void WindowAnimator()
To = 1,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd
};
- double TargetIconOpacity = SearchIcon.Opacity; // Animation Target Opacity from Style
+
+ double TargetIconOpacity = SearchIcon.Opacity;
var IconOpacity = new DoubleAnimation
{
From = 0,
- To = TargetIconOpacity,
+ To = 1,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd
};
double right = ClockPanel.Margin.Right;
@@ -548,18 +571,29 @@ public void WindowAnimator()
To = new Thickness(0, 0, right, 0),
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
- FillBehavior = FillBehavior.Stop
+ FillBehavior = FillBehavior.HoldEnd
};
+ // 애니메이션 타겟 설정
Storyboard.SetTargetProperty(ClockOpacity, new PropertyPath(OpacityProperty));
+ Storyboard.SetTarget(ClockOpacity, ClockPanel);
+
Storyboard.SetTargetName(thicknessAnimation, "ClockPanel");
Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(MarginProperty));
+
Storyboard.SetTarget(WindowOpacity, this);
Storyboard.SetTargetProperty(WindowOpacity, new PropertyPath(Window.OpacityProperty));
+
+ Storyboard.SetTarget(WindowMotion, this);
Storyboard.SetTargetProperty(WindowMotion, new PropertyPath(Window.TopProperty));
+
+ Storyboard.SetTarget(IconMotion, SearchIcon);
Storyboard.SetTargetProperty(IconMotion, new PropertyPath(TopProperty));
+
+ Storyboard.SetTarget(IconOpacity, SearchIcon);
Storyboard.SetTargetProperty(IconOpacity, new PropertyPath(OpacityProperty));
+ // 스토리보드에 애니메이션 추가
clocksb.Children.Add(thicknessAnimation);
clocksb.Children.Add(ClockOpacity);
windowsb.Children.Add(WindowOpacity);
@@ -569,7 +603,6 @@ public void WindowAnimator()
windowsb.Completed += (_, _) => _animating = false;
_settings.WindowLeft = Left;
- _settings.WindowTop = Top;
isArrowKeyPressed = false;
if (QueryTextBox.Text.Length == 0)
@@ -581,6 +614,8 @@ public void WindowAnimator()
windowsb.Begin(FlowMainWindow);
}
+
+
private void InitSoundEffects()
{
if (_settings.WMPInstalled)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 71bc36b2d81..8caac5ec49d 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1393,11 +1393,15 @@ public void Show()
});
}
- public async void Hide()
+ public void Hide()
{
- lastHistoryIndex = 1;
+ // MainWindow 인스턴스를 가져와서 애니메이션 초기화
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ mainWindow.ResetAnimation(); // 애니메이션 강제 리셋
+ }
- // Trick for no delay
+ lastHistoryIndex = 1;
MainWindowOpacity = 0;
if (ExternalPreviewVisible)
@@ -1408,7 +1412,6 @@ public async void Hide()
SelectedResults = Results;
}
- // 📌 모든 LastQueryMode에서 텍스트 필드 즉시 업데이트 + 강제 UI 갱신
Application.Current.Dispatcher.Invoke(() =>
{
switch (Settings.LastQueryMode)
@@ -1437,11 +1440,9 @@ public async void Hide()
break;
}
- // 📌 UI 강제 갱신
Application.Current.MainWindow.UpdateLayout();
- }, DispatcherPriority.Render); // UI 스레드에서 즉시 실행
+ }, DispatcherPriority.Render);
- // 📌 창 숨김 처리 (텍스트 변경 후)
MainWindowVisibilityStatus = false;
MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
@@ -1449,6 +1450,7 @@ public async void Hide()
+
///
/// Checks if Flow Launcher should ignore any hotkeys
///
From a65dc65224e67d8f3fce73d944809f992d0ed35b Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 14:57:02 +0900
Subject: [PATCH 0406/1335] Change Show/Hide function to using DWM
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 100 +++++++++++++++--------
2 files changed, 66 insertions(+), 36 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index a661041035d..588acbdf826 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -530,7 +530,7 @@ public void WindowAnimator()
// 📌 항상 같은 위치에서 시작하도록 `_originalTop`을 사용
var WindowMotion = new DoubleAnimation
{
- From = Top + 10, // 원래 위치에서 10px 내려온 후
+ From = Top, // 원래 위치에서 10px 내려온 후
To = Top, // 다시 원래 위치로 이동
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
FillBehavior = FillBehavior.Stop
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8caac5ec49d..aa3682810e6 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -27,6 +27,8 @@
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using System.Windows.Threading;
+using System.Runtime.InteropServices;
+using System.Windows.Interop;
namespace Flow.Launcher.ViewModel
{
@@ -1381,28 +1383,46 @@ public void ToggleFlowLauncher()
}
}
+ // DWM 관련 상수
+ private const int DWMWA_CLOAK = 14;
+ private const int SW_HIDE = 0;
+ private const int SW_SHOW = 5;
+
+ [DllImport("user32.dll")]
+ private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
+
+ [DllImport("dwmapi.dll")]
+ private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute);
+
public void Show()
{
Application.Current.Dispatcher.Invoke(() =>
{
- MainWindowVisibility = Visibility.Visible;
- MainWindowOpacity = 1;
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle;
+ // 📌 창을 먼저 보이게 설정
+ ShowWindow(hWnd, SW_SHOW);
+
+ // 📌 DWM Cloak 해제 (즉시 표시)
+ int cloak = 0;
+ DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int));
+ }
+
+ // WPF 속성 업데이트
+ //MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
- public void Hide()
+ public async void Hide()
{
- // MainWindow 인스턴스를 가져와서 애니메이션 초기화
- if (Application.Current.MainWindow is MainWindow mainWindow)
- {
- mainWindow.ResetAnimation(); // 애니메이션 강제 리셋
- }
-
lastHistoryIndex = 1;
- MainWindowOpacity = 0;
+
+ // Trick for no delay
+ //MainWindowOpacity = 0;
if (ExternalPreviewVisible)
CloseExternalPreview();
@@ -1412,45 +1432,55 @@ public void Hide()
SelectedResults = Results;
}
- Application.Current.Dispatcher.Invoke(() =>
+ // 📌 텍스트 초기화 즉시 적용 + UI 강제 업데이트
+ if (Settings.LastQueryMode == LastQueryMode.Empty)
{
- switch (Settings.LastQueryMode)
+ ChangeQueryText(string.Empty);
+ await Task.Delay(1); // 한 프레임 후 UI가 반영되도록 대기
+ Application.Current.Dispatcher.Invoke(() =>
{
- case LastQueryMode.Empty:
- ChangeQueryText(string.Empty);
- break;
+ Application.Current.MainWindow.UpdateLayout(); // UI 강제 업데이트
+ });
+ }
- case LastQueryMode.Preserved:
- LastQuerySelected = true;
- break;
+ switch (Settings.LastQueryMode)
+ {
+ case LastQueryMode.Preserved:
+ case LastQueryMode.Selected:
+ LastQuerySelected = (Settings.LastQueryMode == LastQueryMode.Preserved);
+ break;
+
+ case LastQueryMode.ActionKeywordPreserved:
+ case LastQueryMode.ActionKeywordSelected:
+ var newQuery = _lastQuery.ActionKeyword;
+ if (!string.IsNullOrEmpty(newQuery))
+ newQuery += " ";
+ ChangeQueryText(newQuery);
- case LastQueryMode.Selected:
+ if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected)
LastQuerySelected = false;
- break;
+ break;
+ }
- case LastQueryMode.ActionKeywordPreserved:
- case LastQueryMode.ActionKeywordSelected:
- var newQuery = _lastQuery.ActionKeyword;
- if (!string.IsNullOrEmpty(newQuery))
- newQuery += " ";
- ChangeQueryText(newQuery);
+ // 📌 DWM Cloak을 사용하여 창 숨김
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle;
- if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected)
- LastQuerySelected = false;
- break;
- }
+ // 📌 DWM Cloak 활성화
+ int cloak = 1;
+ DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int));
- Application.Current.MainWindow.UpdateLayout();
- }, DispatcherPriority.Render);
+ // 📌 창을 완전히 숨김 (잔상 방지)
+ ShowWindow(hWnd, SW_HIDE);
+ }
+ // WPF 속성 업데이트
MainWindowVisibilityStatus = false;
- MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
}
-
-
///
/// Checks if Flow Launcher should ignore any hotkeys
///
From 1bfec0a90e94be5588c41af4654ffb537aca64e4 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 20:02:27 +0900
Subject: [PATCH 0407/1335] Fix Animation
---
Flow.Launcher/ViewModel/MainViewModel.cs | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index aa3682810e6..55e1e38cd0a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1404,7 +1404,8 @@ public void Show()
// 📌 창을 먼저 보이게 설정
ShowWindow(hWnd, SW_SHOW);
-
+ mainWindow.ClockPanel.Visibility = Visibility.Visible;
+ mainWindow.SearchIcon.Visibility = Visibility.Visible;
// 📌 DWM Cloak 해제 (즉시 표시)
int cloak = 0;
DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int));
@@ -1465,6 +1466,21 @@ public async void Hide()
// 📌 DWM Cloak을 사용하여 창 숨김
if (Application.Current.MainWindow is MainWindow mainWindow)
{
+ // 📌 아이콘과 시계 Opacity를 0으로 강제 설정하고 Visibility.Hidden 적용
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ mainWindow.ClockPanel.Opacity = 0;
+ mainWindow.SearchIcon.Opacity = 0;
+ mainWindow.ClockPanel.Visibility = Visibility.Hidden;
+ mainWindow.SearchIcon.Visibility = Visibility.Hidden;
+
+ // 강제 UI 업데이트
+ mainWindow.ClockPanel.UpdateLayout();
+ mainWindow.SearchIcon.UpdateLayout();
+ }, DispatcherPriority.Render);
+
+ await Task.Delay(10); // UI 반영 대기
+
IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle;
// 📌 DWM Cloak 활성화
From 624fa0eec376b3e2990030fb9a05fc9e60e12e9a Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 20:18:12 +0900
Subject: [PATCH 0408/1335] Fix Hide
---
Flow.Launcher/ViewModel/MainViewModel.cs | 42 +++++++++++-------------
1 file changed, 20 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 55e1e38cd0a..3249fd2217e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1422,9 +1422,6 @@ public async void Hide()
{
lastHistoryIndex = 1;
- // Trick for no delay
- //MainWindowOpacity = 0;
-
if (ExternalPreviewVisible)
CloseExternalPreview();
@@ -1433,6 +1430,24 @@ public async void Hide()
SelectedResults = Results;
}
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ // 📌 아이콘과 시계 Opacity를 0으로 강제 설정하고 Visibility.Hidden 적용 (쿼리 상태와 관계없이 실행)
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ mainWindow.ClockPanel.Opacity = 0;
+ mainWindow.SearchIcon.Opacity = 0;
+ mainWindow.ClockPanel.Visibility = Visibility.Hidden;
+ mainWindow.SearchIcon.Visibility = Visibility.Hidden;
+
+ // 강제 UI 업데이트
+ mainWindow.ClockPanel.UpdateLayout();
+ mainWindow.SearchIcon.UpdateLayout();
+ }, DispatcherPriority.Render);
+
+ await Task.Delay(10); // UI 반영 대기
+ }
+
// 📌 텍스트 초기화 즉시 적용 + UI 강제 업데이트
if (Settings.LastQueryMode == LastQueryMode.Empty)
{
@@ -1463,25 +1478,9 @@ public async void Hide()
break;
}
- // 📌 DWM Cloak을 사용하여 창 숨김
- if (Application.Current.MainWindow is MainWindow mainWindow)
+ if (Application.Current.MainWindow is MainWindow mainWindow2)
{
- // 📌 아이콘과 시계 Opacity를 0으로 강제 설정하고 Visibility.Hidden 적용
- Application.Current.Dispatcher.Invoke(() =>
- {
- mainWindow.ClockPanel.Opacity = 0;
- mainWindow.SearchIcon.Opacity = 0;
- mainWindow.ClockPanel.Visibility = Visibility.Hidden;
- mainWindow.SearchIcon.Visibility = Visibility.Hidden;
-
- // 강제 UI 업데이트
- mainWindow.ClockPanel.UpdateLayout();
- mainWindow.SearchIcon.UpdateLayout();
- }, DispatcherPriority.Render);
-
- await Task.Delay(10); // UI 반영 대기
-
- IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle;
+ IntPtr hWnd = new WindowInteropHelper(mainWindow2).Handle;
// 📌 DWM Cloak 활성화
int cloak = 1;
@@ -1496,7 +1495,6 @@ public async void Hide()
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
}
-
///
/// Checks if Flow Launcher should ignore any hotkeys
///
From ce3a3e912aac6bfb74e684aa4320cd193272f2bd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Mar 2025 19:43:16 +0800
Subject: [PATCH 0409/1335] Fix plugin settings delete issue
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 37 ++++++++++++++++------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index ce3f1ac6d73..4d8bf76b7e6 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -72,15 +72,20 @@ public static async ValueTask DisposePluginsAsync()
{
foreach (var pluginPair in AllPlugins)
{
- switch (pluginPair.Plugin)
- {
- case IDisposable disposable:
- disposable.Dispose();
- break;
- case IAsyncDisposable asyncDisposable:
- await asyncDisposable.DisposeAsync();
- break;
- }
+ await DisposePluginAsync(pluginPair);
+ }
+ }
+
+ private static async Task DisposePluginAsync(PluginPair pluginPair)
+ {
+ switch (pluginPair.Plugin)
+ {
+ case IDisposable disposable:
+ disposable.Dispose();
+ break;
+ case IAsyncDisposable asyncDisposable:
+ await asyncDisposable.DisposeAsync();
+ break;
}
}
@@ -565,13 +570,25 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
}
}
- internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
+ internal static async void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}
+ if (removePluginFromSettings)
+ {
+ // If we want to remove plugin from AllPlugins,
+ // we need to dispose them so that they can release file handles
+ // which can help FL to delete the plugin settings & cache folders successfully
+ var pluginPairs = AllPlugins.FindAll(p => p.Metadata.ID == plugin.ID);
+ foreach (var pluginPair in pluginPairs)
+ {
+ await DisposePluginAsync(pluginPair);
+ }
+ }
+
if (removePluginSettings)
{
// For dotnet plugins, we need to remove their PluginJsonStorage instance
From 1b22d9cdfba60ef052277c75c18a7889433f1602 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 20:49:14 +0900
Subject: [PATCH 0410/1335] Fix Clock Animation
---
Flow.Launcher/MainWindow.xaml.cs | 87 ++++++++++++++++++++++++++++++++
Flow.Launcher/Themes/Base.xaml | 23 ---------
2 files changed, 87 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 588acbdf826..19f928621d0 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -309,6 +309,18 @@ private void OnLoaded(object sender, RoutedEventArgs _)
break;
}
};
+ // ✅ QueryTextBox.Text 변경 감지 (글자 수 1 이상일 때만 동작하도록 수정)
+ QueryTextBox.TextChanged += (sender, e) => UpdateClockPanelVisibility();
+
+ // ✅ ContextMenu.Visibility 변경 감지
+ DependencyPropertyDescriptor
+ .FromProperty(UIElement.VisibilityProperty, typeof(ContextMenu))
+ .AddValueChanged(ContextMenu, (s, e) => UpdateClockPanelVisibility());
+
+ // ✅ History.Visibility 변경 감지
+ DependencyPropertyDescriptor
+ .FromProperty(UIElement.VisibilityProperty, typeof(StackPanel)) // History는 StackPanel이라고 가정
+ .AddValueChanged(History, (s, e) => UpdateClockPanelVisibility());
}
private void InitializePosition()
@@ -614,6 +626,81 @@ public void WindowAnimator()
windowsb.Begin(FlowMainWindow);
}
+ private bool _isClockPanelAnimating = false; // 애니메이션 실행 중인지 여부
+
+ private void UpdateClockPanelVisibility()
+ {
+ if (QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null)
+ return;
+
+ // ✅ `WindowAnimator`와 동일한 애니메이션 속도 설정 참조
+ var animationLength = _settings.AnimationSpeed switch
+ {
+ AnimationSpeeds.Slow => 560,
+ AnimationSpeeds.Medium => 360,
+ AnimationSpeeds.Fast => 160,
+ _ => _settings.CustomAnimationLength
+ };
+
+ var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3); // ✅ 같은 비율 적용
+
+ // ✅ 글자 수가 1 이상이면 애니메이션 추가 실행 방지
+ if (QueryTextBox.Text.Length > 0 ||
+ ContextMenu.Visibility != Visibility.Collapsed ||
+ History.Visibility != Visibility.Collapsed)
+ {
+ if (ClockPanel.Visibility == Visibility.Hidden || _isClockPanelAnimating)
+ return; // ✅ 이미 숨겨져 있거나 애니메이션 실행 중이면 다시 실행하지 않음
+
+ _isClockPanelAnimating = true;
+
+ // Opacity 애니메이션 적용 후 Visibility.Hidden 처리
+ var fadeOut = new DoubleAnimation
+ {
+ From = 1.0,
+ To = 0.0,
+ Duration = animationDuration,
+ FillBehavior = FillBehavior.Stop
+ };
+
+ fadeOut.Completed += (s, e) =>
+ {
+ ClockPanel.Visibility = Visibility.Hidden;
+ _isClockPanelAnimating = false;
+ };
+
+ ClockPanel.BeginAnimation(UIElement.OpacityProperty, fadeOut);
+ }
+ else
+ {
+ if (ClockPanel.Visibility == Visibility.Visible || _isClockPanelAnimating)
+ return; // ✅ 이미 표시 중이거나 애니메이션 실행 중이면 다시 실행하지 않음
+
+ _isClockPanelAnimating = true;
+
+ // ✅ Dispatcher를 사용하여 UI 업데이트 후 `ClockPanel` 표시
+ System.Windows.Application.Current.Dispatcher.Invoke(() =>
+ {
+ ClockPanel.Visibility = Visibility.Visible;
+
+ // Opacity 애니메이션 적용
+ var fadeIn = new DoubleAnimation
+ {
+ From = 0.0,
+ To = 1.0,
+ Duration = animationDuration,
+ FillBehavior = FillBehavior.HoldEnd
+ };
+
+ fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
+ ClockPanel.BeginAnimation(UIElement.OpacityProperty, fadeIn);
+ }, DispatcherPriority.Render);
+ }
+ }
+
+
+
+
private void InitSoundEffects()
diff --git a/Flow.Launcher/Themes/Base.xaml b/Flow.Launcher/Themes/Base.xaml
index b96cb661e5e..44850e94ea5 100644
--- a/Flow.Launcher/Themes/Base.xaml
+++ b/Flow.Launcher/Themes/Base.xaml
@@ -165,29 +165,6 @@
BasedOn="{StaticResource BaseClockPanel}"
TargetType="{x:Type StackPanel}">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 69b7aeadeb09cebd6e576c4817e01fe324522af4 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Thu, 6 Mar 2025 20:07:01 +0800
Subject: [PATCH 0411/1335] Update dependabot.yml
---
.github/dependabot.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d9b39eb89e5..da4231f74c9 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -8,7 +8,8 @@ updates:
- package-ecosystem: "nuget" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
- interval: "weekly"
+ interval: "daily"
+ open-pull-requests-limit: 3
ignore:
- dependency-name: "squirrel-windows"
reviewers:
From 486cc6ac4985bbdd7360332b718a77e4f015278a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Mar 2025 20:15:49 +0800
Subject: [PATCH 0412/1335] Fix async task issue
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 10 +++++-----
.../PluginsManager.cs | 12 ++++++------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 4d8bf76b7e6..456f0a699e6 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -469,10 +469,10 @@ public static bool PluginModified(string uuid)
/// Update a plugin to new version, from a zip file. By default will remove the zip file if update is via url,
/// unless it's a local path installation
///
- public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
+ public static async Task UpdatePluginAsync(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
- UninstallPlugin(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false);
+ await UninstallPluginAsync(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}
@@ -487,9 +487,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath)
///
/// Uninstall a plugin.
///
- public static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false)
+ public static async Task UninstallPluginAsync(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false)
{
- UninstallPlugin(plugin, removePluginFromSettings, removePluginSettings, true);
+ await UninstallPluginAsync(plugin, removePluginFromSettings, removePluginSettings, true);
}
#endregion
@@ -570,7 +570,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
}
}
- internal static async void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
+ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index f4c8a66da31..07bbfdaa0c1 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -341,7 +341,7 @@ await DownloadFileAsync(
}
else
{
- PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ await PluginManager.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
@@ -433,7 +433,7 @@ await DownloadFileAsync(
if (cts.IsCancellationRequested)
return;
else
- PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
+ await PluginManager.UpdatePluginAsync(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
downloadToFilePath);
}
catch (Exception ex)
@@ -681,7 +681,7 @@ internal List RequestUninstall(string search)
Title = $"{x.Metadata.Name} by {x.Metadata.Author}",
SubTitle = x.Metadata.Description,
IcoPath = x.Metadata.IcoPath,
- Action = e =>
+ AsyncAction = async e =>
{
string message;
if (Settings.AutoRestartAfterChanging)
@@ -704,7 +704,7 @@ internal List RequestUninstall(string search)
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Context.API.HideMainWindow();
- Uninstall(x.Metadata);
+ await UninstallAsync(x.Metadata);
if (Settings.AutoRestartAfterChanging)
{
Context.API.RestartApp();
@@ -729,7 +729,7 @@ internal List RequestUninstall(string search)
return Search(results, search);
}
- private void Uninstall(PluginMetadata plugin)
+ private async Task UninstallAsync(PluginMetadata plugin)
{
try
{
@@ -737,7 +737,7 @@ private void Uninstall(PluginMetadata plugin)
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"),
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"),
button: MessageBoxButton.YesNo) == MessageBoxResult.No;
- PluginManager.UninstallPlugin(plugin, removePluginFromSettings: true, removePluginSettings: removePluginSettings);
+ await PluginManager.UninstallPluginAsync(plugin, removePluginFromSettings: true, removePluginSettings: removePluginSettings);
}
catch (ArgumentException e)
{
From 2710de1fbcc20d82a3b58d471add4029e1947eac Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 6 Mar 2025 21:19:09 +0900
Subject: [PATCH 0413/1335] Fix Search Icon Opacity
---
Flow.Launcher/MainWindow.xaml.cs | 24 ++++++++++++++++++++++--
Flow.Launcher/Themes/Base.xaml | 23 +++++++++++++++++++++++
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 19f928621d0..fc8a9f19281 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -566,11 +566,14 @@ public void WindowAnimator()
FillBehavior = FillBehavior.HoldEnd
};
- double TargetIconOpacity = SearchIcon.Opacity;
+ double TargetIconOpacity = GetOpacityFromStyle(SearchIcon, SearchIcon.Style, 1.0); // 스타일에서 Opacity 가져오기
+
+ System.Diagnostics.Debug.WriteLine("스타일에서 가져온 투명도: " + TargetIconOpacity);
+
var IconOpacity = new DoubleAnimation
{
From = 0,
- To = 1,
+ To = TargetIconOpacity,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(animationLength),
FillBehavior = FillBehavior.HoldEnd
@@ -626,6 +629,23 @@ public void WindowAnimator()
windowsb.Begin(FlowMainWindow);
}
+ private double GetOpacityFromStyle(UIElement element, Style style, double defaultOpacity = 1.0)
+ {
+ if (style == null)
+ return defaultOpacity;
+
+ foreach (Setter setter in style.Setters)
+ {
+ if (setter.Property == UIElement.OpacityProperty)
+ {
+ return setter.Value is double opacity ? opacity : defaultOpacity;
+ }
+ }
+
+ return defaultOpacity;
+ }
+
+
private bool _isClockPanelAnimating = false; // 애니메이션 실행 중인지 여부
private void UpdateClockPanelVisibility()
diff --git a/Flow.Launcher/Themes/Base.xaml b/Flow.Launcher/Themes/Base.xaml
index 44850e94ea5..9df935b8d7a 100644
--- a/Flow.Launcher/Themes/Base.xaml
+++ b/Flow.Launcher/Themes/Base.xaml
@@ -165,6 +165,29 @@
BasedOn="{StaticResource BaseClockPanel}"
TargetType="{x:Type StackPanel}">
+
+
From af3b3916764f355568ac6117b123287ef255d54f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 6 Mar 2025 20:20:30 +0800
Subject: [PATCH 0414/1335] Fix dispose
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 456f0a699e6..76d83cbcf4a 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -577,7 +577,7 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}
- if (removePluginFromSettings)
+ if (removePluginSettings || removePluginFromSettings)
{
// If we want to remove plugin from AllPlugins,
// we need to dispose them so that they can release file handles
From f2c30347a762f3a29b176d6730081be3d64e3e14 Mon Sep 17 00:00:00 2001
From: Yusyuriv
Date: Sat, 8 Mar 2025 12:24:47 +0600
Subject: [PATCH 0415/1335] Add new sponsor to README
---
README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 02ffc79328a..6611f55dc0b 100644
--- a/README.md
+++ b/README.md
@@ -334,11 +334,14 @@ Or download the [early access version](https://github.com/Flow-Launcher/Prerelea
-
-
+
+
+
+
+
From 46cdb2a2731f3489ccf5f6978c94d9757cbe25b5 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 8 Mar 2025 16:12:57 +0900
Subject: [PATCH 0416/1335] Fix Blink issue when hidestartup mode (hide on)
---
Flow.Launcher.Core/Resource/Theme.cs | 8 ++++--
Flow.Launcher/MainWindow.xaml.cs | 13 ++++++++-
Flow.Launcher/Themes/Pink.xaml | 6 ++--
Flow.Launcher/ViewModel/MainViewModel.cs | 35 ++++++++++++------------
4 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index edf1da05e8b..c4e56e813d3 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -140,6 +140,7 @@ public void RefreshFrame()
if (mainWindowSrc == null)
return;
+
ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
margins.cxLeftWidth = -1;
margins.cxRightWidth = -1;
@@ -153,8 +154,7 @@ public void RefreshFrame()
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
- if (BlurEnabled)
+ // The timing of adding the shadow effect should vary depending on whether the theme is transparent. if (BlurEnabled)
{
AutoDropShadow();
}
@@ -164,6 +164,7 @@ public void RefreshFrame()
{
AutoDropShadow();
}
+
}
public void AutoDropShadow()
@@ -248,6 +249,7 @@ public void SetBlurForWindow()
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
if (windowBorderStyle == null)
return;
+
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
if (BlurEnabled)
{
@@ -255,9 +257,9 @@ public void SetBlurForWindow()
//BlurColor(BlurMode());
Debug.WriteLine("~~~~~~~~~~~~~~~~~~~~");
Debug.WriteLine(BlurMode());
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
//SetWindowCornerPreference("Round");
}
else
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index fc8a9f19281..4757b1fb43b 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -815,12 +815,23 @@ private void OnLocationChanged(object sender, EventArgs e)
public void HideStartup()
{
UpdatePosition();
+
if (_settings.HideOnStartup)
{
- _viewModel.Hide();
+ // 📌 최초 실행 시 창이 깜빡이는 문제 방지 (완전히 숨긴 상태로 시작)
+ System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden;
+
+ Dispatcher.BeginInvoke((Action)(() =>
+ {
+ _viewModel.Hide();
+ System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed;
+ }), DispatcherPriority.Background);
}
else
{
+ // 📌 최초 실행 시 그림자 효과를 미리 적용하여 Show() 할 때 렌더링이 느려지지 않도록 함
+ ThemeManager.Instance.SetBlurForWindow();
+ //ThemeManager.Instance.AutoDropShadow();
_viewModel.Show();
}
}
diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml
index a8b04d64025..3d8792a080a 100644
--- a/Flow.Launcher/Themes/Pink.xaml
+++ b/Flow.Launcher/Themes/Pink.xaml
@@ -8,8 +8,8 @@
True
Light
RoundSmall
- #DDFEC7D7
- #DDFEC7D7
+ #4BFEC7D7
+ #53FEC7D7
0 0 0 0
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 3249fd2217e..6b225ae06a5 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1402,22 +1402,22 @@ public void Show()
{
IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle;
- // 📌 창을 먼저 보이게 설정
- ShowWindow(hWnd, SW_SHOW);
+ // 📌 창을 보이도록 설정 (Cloak 사용 안 함)
+ //ShowWindow(hWnd, SW_SHOW);
+
+ // 📌 UI 요소 복원
mainWindow.ClockPanel.Visibility = Visibility.Visible;
mainWindow.SearchIcon.Visibility = Visibility.Visible;
- // 📌 DWM Cloak 해제 (즉시 표시)
- int cloak = 0;
- DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int));
}
// WPF 속성 업데이트
- //MainWindowOpacity = 1;
+ MainWindowVisibility = Visibility.Visible;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
});
}
+
public async void Hide()
{
lastHistoryIndex = 1;
@@ -1432,7 +1432,7 @@ public async void Hide()
if (Application.Current.MainWindow is MainWindow mainWindow)
{
- // 📌 아이콘과 시계 Opacity를 0으로 강제 설정하고 Visibility.Hidden 적용 (쿼리 상태와 관계없이 실행)
+ // 📌 아이콘과 시계 Opacity를 0으로 설정하고 Visibility.Hidden 적용
Application.Current.Dispatcher.Invoke(() =>
{
mainWindow.ClockPanel.Opacity = 0;
@@ -1445,7 +1445,7 @@ public async void Hide()
mainWindow.SearchIcon.UpdateLayout();
}, DispatcherPriority.Render);
- await Task.Delay(10); // UI 반영 대기
+ //await Task.Delay(10); // UI 반영 대기
}
// 📌 텍스트 초기화 즉시 적용 + UI 강제 업데이트
@@ -1478,23 +1478,22 @@ public async void Hide()
break;
}
- if (Application.Current.MainWindow is MainWindow mainWindow2)
- {
- IntPtr hWnd = new WindowInteropHelper(mainWindow2).Handle;
+ //if (Application.Current.MainWindow is MainWindow mainWindow2)
+ //{
+ // IntPtr hWnd = new WindowInteropHelper(mainWindow2).Handle;
- // 📌 DWM Cloak 활성화
- int cloak = 1;
- DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int));
-
- // 📌 창을 완전히 숨김 (잔상 방지)
- ShowWindow(hWnd, SW_HIDE);
- }
+ // // 📌 Cloak을 사용하지 않고 일반적인 `ShowWindow(SW_HIDE)` 사용 → Mica/Acrylic 유지됨
+ // ShowWindow(hWnd, SW_HIDE);
+ //}
// WPF 속성 업데이트
MainWindowVisibilityStatus = false;
+ MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
}
+
+
///
/// Checks if Flow Launcher should ignore any hotkeys
///
From 01d081d74057bb22fc43036876cca4a8542fbe15 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 8 Mar 2025 18:30:17 +0900
Subject: [PATCH 0417/1335] Revert Startup Blinking
---
Flow.Launcher.Core/Resource/Theme.cs | 3 ++-
Flow.Launcher/MainWindow.xaml.cs | 17 +++++++++--------
Flow.Launcher/Themes/Pink.xaml | 2 +-
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index c4e56e813d3..3fb4ea1d6a2 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -154,7 +154,8 @@ public void RefreshFrame()
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
//Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- // The timing of adding the shadow effect should vary depending on whether the theme is transparent. if (BlurEnabled)
+ // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
+ if (BlurEnabled)
{
AutoDropShadow();
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 4757b1fb43b..75c851ab3b9 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -819,18 +819,19 @@ public void HideStartup()
if (_settings.HideOnStartup)
{
// 📌 최초 실행 시 창이 깜빡이는 문제 방지 (완전히 숨긴 상태로 시작)
- System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden;
-
- Dispatcher.BeginInvoke((Action)(() =>
- {
- _viewModel.Hide();
- System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed;
- }), DispatcherPriority.Background);
+ //System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden;
+
+ //Dispatcher.BeginInvoke((Action)(() =>
+ //{
+ // _viewModel.Hide();
+ // System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed;
+ //}), DispatcherPriority.Background);
+ _viewModel.Hide();
}
else
{
// 📌 최초 실행 시 그림자 효과를 미리 적용하여 Show() 할 때 렌더링이 느려지지 않도록 함
- ThemeManager.Instance.SetBlurForWindow();
+ //ThemeManager.Instance.SetBlurForWindow();
//ThemeManager.Instance.AutoDropShadow();
_viewModel.Show();
}
diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml
index 3d8792a080a..90592bb99ff 100644
--- a/Flow.Launcher/Themes/Pink.xaml
+++ b/Flow.Launcher/Themes/Pink.xaml
@@ -8,7 +8,7 @@
True
Light
RoundSmall
- #4BFEC7D7
+ #B6C8C7FE
#53FEC7D7
0 0 0 0
+
From f24d64afec925923a81b1e2735f06be761e6d5de Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 13:06:25 +0800
Subject: [PATCH 0455/1335] Add log level glyph
---
Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index 3ca8e163af5..75c51341133 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -123,7 +123,7 @@
-
+
Date: Thu, 13 Mar 2025 13:13:14 +0800
Subject: [PATCH 0456/1335] Fix strings
---
Flow.Launcher/Languages/en.xaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 2ead21cf5b3..a3f87cd30d4 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -104,9 +104,6 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
- Log level
- Debug
- Info
Search Plugin
@@ -303,6 +300,9 @@
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
Open Folder
+ Log Level
+ Debug
+ Info
Select File Manager
From dd1f439b64f9f3a8bb19ef9a3b29c36283eb4cbc Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 13 Mar 2025 14:39:15 +0900
Subject: [PATCH 0457/1335] Adjust strings and icon
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml | 9 +++------
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 17838ed8713..1275570c648 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -104,6 +104,7 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
+ Backdrop Type
None
Acrylic
Mica
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index e4349cf5607..ec068cb5c1b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -461,11 +461,9 @@
-
+ Icon="">
+ Icon="">
Date: Thu, 13 Mar 2025 14:48:08 +0900
Subject: [PATCH 0458/1335] Remove duplicated strings
---
Flow.Launcher/Languages/en.xaml | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 2aebebd6f35..8bcfd97152f 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -109,9 +109,6 @@
Acrylic
Mica
Mica Alt
- Log level
- Debug
- Info
Search Plugin
From fa465130c6141af48345a30b12cb5e11c1d4b841 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 14:01:02 +0800
Subject: [PATCH 0459/1335] Use PInvoke to replace DllImport
---
.../Main.cs | 4 +-
.../NativeMethods.txt | 7 ++-
.../ProcessHelper.cs | 52 ++++++++++---------
3 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
index 03b563c9bf1..098e668cb9f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -6,7 +6,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
public class Main : IPlugin, IPluginI18n, IContextMenu
{
- private ProcessHelper processHelper = new ProcessHelper();
+ private readonly ProcessHelper processHelper = new();
private static PluginInitContext _context;
@@ -66,7 +66,7 @@ private List CreateResultsFromQuery(Query query)
{
string termToSearch = query.Search;
var processList = processHelper.GetMatchingProcesses(termToSearch);
- var processWithNonEmptyMainWindowTitleList = processHelper.GetProcessesWithNonEmptyWindowTitle();
+ var processWithNonEmptyMainWindowTitleList = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
if (!processList.Any())
{
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
index 7fa794755e1..13bf27932ae 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/NativeMethods.txt
@@ -1,2 +1,7 @@
QueryFullProcessImageName
-OpenProcess
\ No newline at end of file
+OpenProcess
+EnumWindows
+GetWindowTextLength
+GetWindowText
+IsWindowVisible
+GetWindowThreadProcessId
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index d8873bc20f3..5f58dc6b11e 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -13,21 +13,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
internal class ProcessHelper
{
- [DllImport("user32.dll")]
- private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
-
- private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
-
- [DllImport("user32.dll", CharSet = CharSet.Unicode)]
- private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
-
- [DllImport("user32.dll")]
- private static extern bool IsWindowVisible(IntPtr hWnd);
-
- [DllImport("user32.dll")]
- private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
-
- private readonly HashSet _systemProcessList = new HashSet()
+ private readonly HashSet _systemProcessList = new()
{
"conhost",
"svchost",
@@ -79,22 +65,25 @@ public List GetMatchingProcesses(string searchTerm)
///
/// Returns a dictionary of process IDs and their window titles for processes that have a visible main window with a non-empty title.
///
- public Dictionary GetProcessesWithNonEmptyWindowTitle()
+ public static unsafe Dictionary GetProcessesWithNonEmptyWindowTitle()
{
var processDict = new Dictionary();
- EnumWindows((hWnd, lParam) =>
+ PInvoke.EnumWindows((hWnd, lParam) =>
{
- StringBuilder windowTitle = new StringBuilder();
- GetWindowText(hWnd, windowTitle, windowTitle.Capacity);
-
- if (!string.IsNullOrWhiteSpace(windowTitle.ToString()) && IsWindowVisible(hWnd))
+ var windowTitle = GetWindowTitle(hWnd);
+ if (!string.IsNullOrWhiteSpace(windowTitle) && PInvoke.IsWindowVisible(hWnd))
{
- GetWindowThreadProcessId(hWnd, out var processId);
- var process = Process.GetProcessById((int)processId);
+ uint processId = 0;
+ var result = PInvoke.GetWindowThreadProcessId(hWnd, &processId);
+ if (result == 0u || processId == 0u)
+ {
+ return false;
+ }
+ var process = Process.GetProcessById((int)processId);
if (!processDict.ContainsKey((int)processId))
{
- processDict.Add((int)processId, windowTitle.ToString());
+ processDict.Add((int)processId, windowTitle);
}
}
@@ -104,6 +93,21 @@ public Dictionary GetProcessesWithNonEmptyWindowTitle()
return processDict;
}
+ private static unsafe string GetWindowTitle(HWND hwnd)
+ {
+ var capacity = PInvoke.GetWindowTextLength(hwnd) + 1;
+ int length;
+ Span buffer = capacity < 1024 ? stackalloc char[capacity] : new char[capacity];
+ fixed (char* pBuffer = buffer)
+ {
+ // If the window has no title bar or text, if the title bar is empty,
+ // or if the window or control handle is invalid, the return value is zero.
+ length = PInvoke.GetWindowText(hwnd, pBuffer, capacity);
+ }
+
+ return buffer[..length].ToString();
+ }
+
///
/// Returns all non-system processes whose file path matches the given processPath
///
From b7694d31300a3b62a298d605e52a813e0e04f5bf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 14:09:13 +0800
Subject: [PATCH 0460/1335] Clean up codes
---
Flow.Launcher.Infrastructure/FileExplorerHelper.cs | 2 --
Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
index b97c096c363..1085cc83313 100644
--- a/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
+++ b/Flow.Launcher.Infrastructure/FileExplorerHelper.cs
@@ -67,8 +67,6 @@ private static dynamic GetActiveExplorer()
return explorerWindows.Zip(zOrders).MinBy(x => x.Second).First;
}
- private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
-
///
/// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1.
///
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index 5f58dc6b11e..c603fba09fb 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -68,7 +68,7 @@ public List GetMatchingProcesses(string searchTerm)
public static unsafe Dictionary GetProcessesWithNonEmptyWindowTitle()
{
var processDict = new Dictionary();
- PInvoke.EnumWindows((hWnd, lParam) =>
+ PInvoke.EnumWindows((hWnd, _) =>
{
var windowTitle = GetWindowTitle(hWnd);
if (!string.IsNullOrWhiteSpace(windowTitle) && PInvoke.IsWindowVisible(hWnd))
From d12cde7c44dc37e54d42fd35c42c958702122e2a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 14:16:38 +0800
Subject: [PATCH 0461/1335] Do not close window when killed processes
---
Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
index 098e668cb9f..aec60757543 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -91,9 +91,8 @@ private List CreateResultsFromQuery(Query query)
Action = (c) =>
{
processHelper.TryKill(p);
- // Re-query to refresh process list
- _context.API.ChangeQuery(query.RawQuery, true);
- return true;
+ _context.API.ReQuery();
+ return false;
}
});
}
@@ -120,9 +119,8 @@ private List CreateResultsFromQuery(Query query)
{
processHelper.TryKill(p.Process);
}
- // Re-query to refresh process list
- _context.API.ChangeQuery(query.RawQuery, true);
- return true;
+ _context.API.ReQuery();
+ return false;
}
});
}
From bc0cde289c2af505f1ea7890173dc2226486dbb9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 18:20:25 +0800
Subject: [PATCH 0462/1335] Add translations for system plugin command column
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 28747cc7cf1..05687701db7 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -28,8 +28,12 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
public Control CreateSettingPanel()
{
- var results = Commands();
- return new SysSettings(results);
+ var commands = Commands();
+ foreach (var c in commands)
+ {
+ c.Title = GetDynamicTitle(null, c);
+ }
+ return new SysSettings(commands);
}
public List Query(Query query)
@@ -73,6 +77,11 @@ private string GetDynamicTitle(Query query, Result result)
var translatedTitle = context.API.GetTranslation(translationKey);
+ if (query == null)
+ {
+ return translatedTitle;
+ }
+
if (result.Title == translatedTitle)
{
return result.Title;
From 01e8be779ce47dea22ae8d6a959baadb3aa2df46 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 19:30:51 +0800
Subject: [PATCH 0463/1335] Fix FL settings issue
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 38619cbbc2c..e67b4e5c5c8 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -2,7 +2,7 @@
using System.Linq;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure.UserSettings;
+using FLSettings = Flow.Launcher.Infrastructure.UserSettings.Settings;
namespace Flow.Launcher.Plugin.Sys
{
@@ -10,7 +10,7 @@ public class ThemeSelector
{
public const string Keyword = "fltheme";
- private readonly Settings _settings;
+ private readonly FLSettings _settings;
private readonly Theme _theme;
private readonly PluginInitContext _context;
@@ -43,7 +43,7 @@ public ThemeSelector(PluginInitContext context)
{
_context = context;
_theme = Ioc.Default.GetRequiredService();
- _settings = Ioc.Default.GetRequiredService();
+ _settings = Ioc.Default.GetRequiredService();
}
public List Query(Query query)
From 8335821ad080818586f3a09d23a72b4c09da0edc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 22:02:45 +0800
Subject: [PATCH 0464/1335] Clean up codes
---
.../SettingsViewModel.cs | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsViewModel.cs
index a2538893bc9..e07e30cb2b6 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsViewModel.cs
@@ -1,21 +1,12 @@
-using Flow.Launcher.Infrastructure.Storage;
-
-namespace Flow.Launcher.Plugin.WebSearch
+namespace Flow.Launcher.Plugin.WebSearch
{
public class SettingsViewModel
{
- private readonly PluginJsonStorage _storage;
-
public SettingsViewModel(Settings settings)
{
Settings = settings;
}
public Settings Settings { get; }
-
- public void Save()
- {
- _storage.Save();
- }
}
-}
\ No newline at end of file
+}
From e0f02a0d7bc62ba0b2c84359cf952545c963ec14 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 22:34:50 +0800
Subject: [PATCH 0465/1335] Initialize localized grid & Edit button
---
Plugins/Flow.Launcher.Plugin.Sys/Command.cs | 17 +++
.../Languages/en.xaml | 5 +-
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 103 +++++++++-----
Plugins/Flow.Launcher.Plugin.Sys/Settings.cs | 127 ++++++++++++++++++
.../SettingsViewModel.cs | 12 ++
.../Flow.Launcher.Plugin.Sys/SysSettings.xaml | 38 +++++-
.../SysSettings.xaml.cs | 44 ++++--
7 files changed, 301 insertions(+), 45 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/Command.cs
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/Settings.cs
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/SettingsViewModel.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Command.cs b/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
new file mode 100644
index 00000000000..84f5f046fb9
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization;
+
+namespace Flow.Launcher.Plugin.Sys
+{
+ public class Command : BaseModel
+ {
+ public string Key { get; set; }
+
+ [JsonIgnore]
+ public string Name { get; set; }
+
+ [JsonIgnore]
+ public string Description { get; set; }
+
+ public string Keyword { get; set; }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index 2a266f8f651..e1d83fa382b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -4,8 +4,9 @@
xmlns:system="clr-namespace:System;assembly=mscorlib">
- Command
+ Name
Description
+ Command
Shutdown
Restart
@@ -29,6 +30,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Edit
+
Shutdown Computer
Restart Computer
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 05687701db7..ef9da27192d 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -19,8 +19,36 @@ namespace Flow.Launcher.Plugin.Sys
public class Main : IPlugin, ISettingProvider, IPluginI18n
{
private PluginInitContext context;
+ private Settings settings;
private ThemeSelector themeSelector;
- private Dictionary KeywordTitleMappings = new Dictionary();
+
+ private readonly Dictionary KeywordTitleMappings = new()
+ {
+ {"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
+ {"Restart", "flowlauncher_plugin_sys_restart_computer_cmd"},
+ {"Restart With Advanced Boot Options", "flowlauncher_plugin_sys_restart_advanced_cmd"},
+ {"Log Off/Sign Out", "flowlauncher_plugin_sys_log_off_cmd"},
+ {"Lock", "flowlauncher_plugin_sys_lock_cmd"},
+ {"Sleep", "flowlauncher_plugin_sys_sleep_cmd"},
+ {"Hibernate", "flowlauncher_plugin_sys_hibernate_cmd"},
+ {"Index Option", "flowlauncher_plugin_sys_indexoption_cmd"},
+ {"Empty Recycle Bin", "flowlauncher_plugin_sys_emptyrecyclebin_cmd"},
+ {"Open Recycle Bin", "flowlauncher_plugin_sys_openrecyclebin_cmd"},
+ {"Exit", "flowlauncher_plugin_sys_exit_cmd"},
+ {"Save Settings", "flowlauncher_plugin_sys_save_all_settings_cmd"},
+ {"Restart Flow Launcher", "flowlauncher_plugin_sys_restart_cmd"},
+ {"Settings", "flowlauncher_plugin_sys_setting_cmd"},
+ {"Reload Plugin Data", "flowlauncher_plugin_sys_reload_plugin_data_cmd"},
+ {"Check For Update", "flowlauncher_plugin_sys_check_for_update_cmd"},
+ {"Open Log Location", "flowlauncher_plugin_sys_open_log_location_cmd"},
+ {"Flow Launcher Tips", "flowlauncher_plugin_sys_open_docs_tips_cmd"},
+ {"Flow Launcher UserData Folder", "flowlauncher_plugin_sys_open_userdata_location_cmd"},
+ {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"},
+ {"Set Flow Launcher Theme", "flowlauncher_plugin_sys_theme_selector_cmd"}
+ };
+ private readonly Dictionary KeywordDescriptionMappings = new();
+
+ private SettingsViewModel _viewModel;
// SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
@@ -28,12 +56,8 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
public Control CreateSettingPanel()
{
- var commands = Commands();
- foreach (var c in commands)
- {
- c.Title = GetDynamicTitle(null, c);
- }
- return new SysSettings(commands);
+ UpdateLocalizedNameDescription(false);
+ return new SysSettings(_viewModel);
}
public List Query(Query query)
@@ -67,6 +91,29 @@ public List Query(Query query)
return results;
}
+ private string GetTitle(string key)
+ {
+ if (!KeywordTitleMappings.TryGetValue(key, out var translationKey))
+ {
+ Log.Error("Flow.Launcher.Plugin.Sys.Main", $"Title not found for: {key}");
+ return "Title Not Found";
+ }
+
+ return context.API.GetTranslation(translationKey);
+ }
+
+ private string GetDescription(string key)
+ {
+ if (!KeywordDescriptionMappings.TryGetValue(key, out var translationKey))
+ {
+ Log.Error("Flow.Launcher.Plugin.Sys.Main", $"Description not found for: {key}");
+ return "Description Not Found";
+ }
+
+ return context.API.GetTranslation(translationKey);
+ }
+
+ [Obsolete]
private string GetDynamicTitle(Query query, Result result)
{
if (!KeywordTitleMappings.TryGetValue(result.Title, out var translationKey))
@@ -96,30 +143,26 @@ private string GetDynamicTitle(Query query, Result result)
public void Init(PluginInitContext context)
{
this.context = context;
+ settings = context.API.LoadSettingJsonStorage();
+ _viewModel = new SettingsViewModel(settings);
themeSelector = new ThemeSelector(context);
- KeywordTitleMappings = new Dictionary{
- {"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
- {"Restart", "flowlauncher_plugin_sys_restart_computer_cmd"},
- {"Restart With Advanced Boot Options", "flowlauncher_plugin_sys_restart_advanced_cmd"},
- {"Log Off/Sign Out", "flowlauncher_plugin_sys_log_off_cmd"},
- {"Lock", "flowlauncher_plugin_sys_lock_cmd"},
- {"Sleep", "flowlauncher_plugin_sys_sleep_cmd"},
- {"Hibernate", "flowlauncher_plugin_sys_hibernate_cmd"},
- {"Index Option", "flowlauncher_plugin_sys_indexoption_cmd"},
- {"Empty Recycle Bin", "flowlauncher_plugin_sys_emptyrecyclebin_cmd"},
- {"Open Recycle Bin", "flowlauncher_plugin_sys_openrecyclebin_cmd"},
- {"Exit", "flowlauncher_plugin_sys_exit_cmd"},
- {"Save Settings", "flowlauncher_plugin_sys_save_all_settings_cmd"},
- {"Restart Flow Launcher", "flowlauncher_plugin_sys_restart_cmd"},
- {"Settings", "flowlauncher_plugin_sys_setting_cmd"},
- {"Reload Plugin Data", "flowlauncher_plugin_sys_reload_plugin_data_cmd"},
- {"Check For Update", "flowlauncher_plugin_sys_check_for_update_cmd"},
- {"Open Log Location", "flowlauncher_plugin_sys_open_log_location_cmd"},
- {"Flow Launcher Tips", "flowlauncher_plugin_sys_open_docs_tips_cmd"},
- {"Flow Launcher UserData Folder", "flowlauncher_plugin_sys_open_userdata_location_cmd"},
- {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"},
- {"Set Flow Launcher Theme", "flowlauncher_plugin_sys_theme_selector_cmd"}
- };
+ foreach (string key in KeywordTitleMappings.Keys)
+ {
+ // Remove _cmd in the last of the strings
+ KeywordDescriptionMappings[key] = KeywordTitleMappings[key][..^4];
+ }
+ }
+
+ private void UpdateLocalizedNameDescription(bool force)
+ {
+ if (string.IsNullOrEmpty(settings.Commands[0].Name) || force)
+ {
+ foreach (var c in settings.Commands)
+ {
+ c.Name = GetTitle(c.Key);
+ c.Description = GetDescription(c.Key);
+ }
+ }
}
private static unsafe bool EnableShutdownPrivilege()
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Settings.cs b/Plugins/Flow.Launcher.Plugin.Sys/Settings.cs
new file mode 100644
index 00000000000..f39e6d65fe0
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Settings.cs
@@ -0,0 +1,127 @@
+using System.Collections.ObjectModel;
+using System.Text.Json.Serialization;
+
+namespace Flow.Launcher.Plugin.Sys;
+
+public class Settings : BaseModel
+{
+ public Settings()
+ {
+ if (Commands.Count > 0)
+ {
+ SelectedCommand = Commands[0];
+ }
+ }
+
+ public ObservableCollection Commands { get; set; } = new ObservableCollection
+ {
+ new()
+ {
+ Key = "Shutdown",
+ Keyword = "Shutdown"
+ },
+ new()
+ {
+ Key = "Restart",
+ Keyword = "Restart"
+ },
+ new()
+ {
+ Key = "Restart With Advanced Boot Options",
+ Keyword = "Restart With Advanced Boot Options"
+ },
+ new()
+ {
+ Key = "Log Off/Sign Out",
+ Keyword = "Log Off/Sign Out"
+ },
+ new()
+ {
+ Key = "Lock",
+ Keyword = "Lock"
+ },
+ new()
+ {
+ Key = "Sleep",
+ Keyword = "Sleep"
+ },
+ new()
+ {
+ Key = "Hibernate",
+ Keyword = "Hibernate"
+ },
+ new()
+ {
+ Key = "Index Option",
+ Keyword = "Index Option"
+ },
+ new()
+ {
+ Key = "Empty Recycle Bin",
+ Keyword = "Empty Recycle Bin"
+ },
+ new()
+ {
+ Key = "Open Recycle Bin",
+ Keyword = "Open Recycle Bin"
+ },
+ new()
+ {
+ Key = "Exit",
+ Keyword = "Exit"
+ },
+ new()
+ {
+ Key = "Save Settings",
+ Keyword = "Save Settings"
+ },
+ new()
+ {
+ Key = "Restart Flow Launcher",
+ Keyword = "Restart Flow Launcher"
+ },
+ new()
+ {
+ Key = "Settings",
+ Keyword = "Settings"
+ },
+ new()
+ {
+ Key = "Reload Plugin Data",
+ Keyword = "Reload Plugin Data"
+ },
+ new()
+ {
+ Key = "Check For Update",
+ Keyword = "Check For Update"
+ },
+ new()
+ {
+ Key = "Open Log Location",
+ Keyword = "Open Log Location"
+ },
+ new()
+ {
+ Key = "Flow Launcher Tips",
+ Keyword = "Flow Launcher Tips"
+ },
+ new()
+ {
+ Key = "Flow Launcher UserData Folder",
+ Keyword = "Flow Launcher UserData Folder"
+ },
+ new()
+ {
+ Key = "Toggle Game Mode",
+ Keyword = "Toggle Game Mode"
+ },
+ new()
+ {
+ Key = "Set Flow Launcher Theme",
+ Keyword = "Set Flow Launcher Theme"
+ }
+ };
+
+ [JsonIgnore]
+ public Command SelectedCommand { get; set; }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Sys/SettingsViewModel.cs
new file mode 100644
index 00000000000..0755dffa923
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SettingsViewModel.cs
@@ -0,0 +1,12 @@
+namespace Flow.Launcher.Plugin.Sys
+{
+ public class SettingsViewModel
+ {
+ public SettingsViewModel(Settings settings)
+ {
+ Settings = settings;
+ }
+
+ public Settings Settings { get; }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
index f806900dedc..67e840e5358 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml
@@ -4,36 +4,66 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:vm="clr-namespace:Flow.Launcher.Plugin.Sys"
+ d:DataContext="{d:DesignInstance vm:SettingsViewModel}"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
-
+
+
+
+
+
+
-
+
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
index feb30821a55..539801a0b1c 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
@@ -1,28 +1,28 @@
-using System.Collections.Generic;
-using System.Windows;
+using System.Windows;
using System.Windows.Controls;
namespace Flow.Launcher.Plugin.Sys
{
public partial class SysSettings : UserControl
{
- public SysSettings(List Results)
+ private readonly Settings _settings;
+
+ public SysSettings(SettingsViewModel viewModel)
{
InitializeComponent();
-
- foreach (var Result in Results)
- {
- lbxCommands.Items.Add(Result);
- }
+ _settings = viewModel.Settings;
+ DataContext = viewModel;
}
+
private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView listView = sender as ListView;
GridView gView = listView.View as GridView;
var workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
- var col1 = 0.3;
- var col2 = 0.7;
+ var col1 = 0.2;
+ var col2 = 0.6;
+ var col3 = 0.2;
if (workingWidth <= 0)
{
@@ -31,6 +31,30 @@ private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
gView.Columns[0].Width = workingWidth * col1;
gView.Columns[1].Width = workingWidth * col2;
+ gView.Columns[2].Width = workingWidth * col3;
+ }
+
+ public void OnEditCommandKeywordClick(object sender, RoutedEventArgs e)
+ {
+ /*var webSearch = new SearchSourceSettingWindow
+ (
+ _settings.SearchSources, _context, _settings.SelectedSearchSource
+ );
+
+ webSearch.ShowDialog();*/
+ }
+
+ private void MouseDoubleClickItem(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (((FrameworkElement)e.OriginalSource).DataContext is Command && _settings.SelectedCommand != null)
+ {
+ /*var webSearch = new SearchSourceSettingWindow
+ (
+ _settings.SearchSources, _context, _settings.SelectedSearchSource
+ );
+
+ webSearch.ShowDialog();*/
+ }
}
}
}
From 2a5b22b93862ba2799b81a90602dfa5f14ba1ba1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 23:29:00 +0800
Subject: [PATCH 0466/1335] Add command keyword change dialog & Support culture
change
---
Plugins/Flow.Launcher.Plugin.Sys/Command.cs | 33 +++-
.../CommandKeywordSetting.xaml | 121 ++++++++++++++
.../CommandKeywordSetting.xaml.cs | 45 ++++++
.../Languages/en.xaml | 9 ++
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 151 +++++++++---------
.../SysSettings.xaml.cs | 20 +--
6 files changed, 291 insertions(+), 88 deletions(-)
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml
create mode 100644 Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Command.cs b/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
index 84f5f046fb9..6c3a99f3e20 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Command.cs
@@ -6,12 +6,39 @@ public class Command : BaseModel
{
public string Key { get; set; }
+ private string name;
[JsonIgnore]
- public string Name { get; set; }
+ public string Name
+ {
+ get => name;
+ set
+ {
+ name = value;
+ OnPropertyChanged();
+ }
+ }
+ private string description;
[JsonIgnore]
- public string Description { get; set; }
+ public string Description
+ {
+ get => description;
+ set
+ {
+ description = value;
+ OnPropertyChanged();
+ }
+ }
- public string Keyword { get; set; }
+ private string keyword;
+ public string Keyword
+ {
+ get => keyword;
+ set
+ {
+ keyword = value;
+ OnPropertyChanged();
+ }
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml b/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml
new file mode 100644
index 00000000000..a848f2f1f52
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml.cs
new file mode 100644
index 00000000000..8797bf2201e
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/CommandKeywordSetting.xaml.cs
@@ -0,0 +1,45 @@
+using System.Windows;
+
+namespace Flow.Launcher.Plugin.Sys
+{
+ public partial class CommandKeywordSettingWindow
+ {
+ private readonly Command _oldSearchSource;
+ private readonly PluginInitContext _context;
+
+ public CommandKeywordSettingWindow(PluginInitContext context, Command old)
+ {
+ _context = context;
+ _oldSearchSource = old;
+ InitializeComponent();
+ CommandKeyword.Text = old.Keyword;
+ CommandKeywordTips.Text = string.Format(_context.API.GetTranslation("flowlauncher_plugin_sys_custom_command_keyword_tip"), old.Name);
+ }
+
+ private void OnCancelButtonClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void OnConfirmButtonClick(object sender, RoutedEventArgs e)
+ {
+ var keyword = CommandKeyword.Text;
+ if (string.IsNullOrEmpty(keyword))
+ {
+ var warning = _context.API.GetTranslation("flowlauncher_plugin_sys_input_command_keyword");
+ _context.API.ShowMsgBox(warning);
+ }
+ else
+ {
+ _oldSearchSource.Keyword = keyword;
+ Close();
+ }
+ }
+
+ private void OnResetButtonClick(object sender, RoutedEventArgs e)
+ {
+ // Key is the default value of this command
+ CommandKeyword.Text = _oldSearchSource.Key;
+ }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index e1d83fa382b..ad3f8553bab 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -64,6 +64,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Cancel
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index ef9da27192d..fd72ddcaffc 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
@@ -18,10 +19,6 @@ namespace Flow.Launcher.Plugin.Sys
{
public class Main : IPlugin, ISettingProvider, IPluginI18n
{
- private PluginInitContext context;
- private Settings settings;
- private ThemeSelector themeSelector;
-
private readonly Dictionary KeywordTitleMappings = new()
{
{"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
@@ -48,23 +45,28 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n
};
private readonly Dictionary KeywordDescriptionMappings = new();
- private SettingsViewModel _viewModel;
-
- // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
+ // SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure,
+ // software updates, or other predefined reasons.
// SHTDN_REASON_FLAG_PLANNED marks the shutdown as planned rather than an unexpected shutdown or failure
- private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER | SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
+ private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER |
+ SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
+
+ private PluginInitContext _context;
+ private Settings _settings;
+ private ThemeSelector _themeSelector;
+ private SettingsViewModel _viewModel;
public Control CreateSettingPanel()
{
UpdateLocalizedNameDescription(false);
- return new SysSettings(_viewModel);
+ return new SysSettings(_context, _viewModel);
}
public List Query(Query query)
{
if(query.Search.StartsWith(ThemeSelector.Keyword))
{
- return themeSelector.Query(query);
+ return _themeSelector.Query(query);
}
var commands = Commands();
@@ -99,7 +101,7 @@ private string GetTitle(string key)
return "Title Not Found";
}
- return context.API.GetTranslation(translationKey);
+ return _context.API.GetTranslation(translationKey);
}
private string GetDescription(string key)
@@ -110,7 +112,7 @@ private string GetDescription(string key)
return "Description Not Found";
}
- return context.API.GetTranslation(translationKey);
+ return _context.API.GetTranslation(translationKey);
}
[Obsolete]
@@ -122,7 +124,7 @@ private string GetDynamicTitle(Query query, Result result)
return "Title Not Found";
}
- var translatedTitle = context.API.GetTranslation(translationKey);
+ var translatedTitle = _context.API.GetTranslation(translationKey);
if (query == null)
{
@@ -142,10 +144,10 @@ private string GetDynamicTitle(Query query, Result result)
public void Init(PluginInitContext context)
{
- this.context = context;
- settings = context.API.LoadSettingJsonStorage();
- _viewModel = new SettingsViewModel(settings);
- themeSelector = new ThemeSelector(context);
+ _context = context;
+ _settings = context.API.LoadSettingJsonStorage();
+ _viewModel = new SettingsViewModel(_settings);
+ _themeSelector = new ThemeSelector(context);
foreach (string key in KeywordTitleMappings.Keys)
{
// Remove _cmd in the last of the strings
@@ -155,9 +157,9 @@ public void Init(PluginInitContext context)
private void UpdateLocalizedNameDescription(bool force)
{
- if (string.IsNullOrEmpty(settings.Commands[0].Name) || force)
+ if (string.IsNullOrEmpty(_settings.Commands[0].Name) || force)
{
- foreach (var c in settings.Commands)
+ foreach (var c in _settings.Commands)
{
c.Name = GetTitle(c.Key);
c.Description = GetDescription(c.Key);
@@ -214,14 +216,14 @@ private List Commands()
new Result
{
Title = "Shutdown",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe7e8"),
IcoPath = "Images\\shutdown.png",
Action = c =>
{
- var result = context.API.ShowMsgBox(
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
- context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
+ var result = _context.API.ShowMsgBox(
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_shutdown_computer"),
+ _context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
@@ -236,14 +238,14 @@ private List Commands()
new Result
{
Title = "Restart",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe777"),
IcoPath = "Images\\restart.png",
Action = c =>
{
- var result = context.API.ShowMsgBox(
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
- context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
+ var result = _context.API.ShowMsgBox(
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer"),
+ _context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
@@ -258,14 +260,14 @@ private List Commands()
new Result
{
Title = "Restart With Advanced Boot Options",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xecc5"),
IcoPath = "Images\\restart_advanced.png",
Action = c =>
{
- var result = context.API.ShowMsgBox(
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer_advanced"),
- context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
+ var result = _context.API.ShowMsgBox(
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_restart_computer_advanced"),
+ _context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
@@ -280,14 +282,14 @@ private List Commands()
new Result
{
Title = "Log Off/Sign Out",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe77b"),
IcoPath = "Images\\logoff.png",
Action = c =>
{
- var result = context.API.ShowMsgBox(
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_logoff_computer"),
- context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
+ var result = _context.API.ShowMsgBox(
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_logoff_computer"),
+ _context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
@@ -299,7 +301,7 @@ private List Commands()
new Result
{
Title = "Lock",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_lock"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_lock"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe72e"),
IcoPath = "Images\\lock.png",
Action = c =>
@@ -311,7 +313,7 @@ private List Commands()
new Result
{
Title = "Sleep",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
Action = c =>
@@ -323,7 +325,7 @@ private List Commands()
new Result
{
Title = "Hibernate",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_hibernate"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_hibernate"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe945"),
IcoPath = "Images\\hibernate.png",
Action= c =>
@@ -335,7 +337,7 @@ private List Commands()
new Result
{
Title = "Index Option",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_indexoption"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_indexoption"),
IcoPath = "Images\\indexoption.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
Action = c =>
@@ -347,7 +349,7 @@ private List Commands()
new Result
{
Title = "Empty Recycle Bin",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin"),
IcoPath = "Images\\recyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
Action = c =>
@@ -358,7 +360,7 @@ private List Commands()
var result = PInvoke.SHEmptyRecycleBin(new(), string.Empty, 0);
if (result != HRESULT.S_OK && result != HRESULT.E_UNEXPECTED)
{
- context.API.ShowMsgBox("Failed to empty the recycle bin. This might happen if:\n" +
+ _context.API.ShowMsgBox("Failed to empty the recycle bin. This might happen if:\n" +
"- A file in the recycle bin is in use\n" +
"- You don't have permission to delete some items\n" +
"Please close any applications that might be using these files and try again.",
@@ -372,7 +374,7 @@ private List Commands()
new Result
{
Title = "Open Recycle Bin",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
CopyText = recycleBinFolder,
@@ -385,7 +387,7 @@ private List Commands()
new Result
{
Title = "Exit",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -396,52 +398,52 @@ private List Commands()
new Result
{
Title = "Save Settings",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings"),
IcoPath = "Images\\app.png",
Action = c =>
{
- context.API.SaveAppAllSettings();
- context.API.ShowMsg(context.API.GetTranslation("flowlauncher_plugin_sys_dlgtitle_success"),
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_all_settings_saved"));
+ _context.API.SaveAppAllSettings();
+ _context.API.ShowMsg(_context.API.GetTranslation("flowlauncher_plugin_sys_dlgtitle_success"),
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_all_settings_saved"));
return true;
}
},
new Result
{
Title = "Restart Flow Launcher",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
IcoPath = "Images\\app.png",
Action = c =>
{
- context.API.RestartApp();
+ _context.API.RestartApp();
return false;
}
},
new Result
{
Title = "Settings",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
IcoPath = "Images\\app.png",
Action = c =>
{
- context.API.OpenSettingDialog();
+ _context.API.OpenSettingDialog();
return true;
}
},
new Result
{
Title = "Reload Plugin Data",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data"),
IcoPath = "Images\\app.png",
Action = c =>
{
// Hide the window first then show msg after done because sometimes the reload could take a while, so not to make user think it's frozen.
- context.API.HideMainWindow();
+ _context.API.HideMainWindow();
- _ = context.API.ReloadAllPluginData().ContinueWith(_ =>
- context.API.ShowMsg(
- context.API.GetTranslation("flowlauncher_plugin_sys_dlgtitle_success"),
- context.API.GetTranslation(
+ _ = _context.API.ReloadAllPluginData().ContinueWith(_ =>
+ _context.API.ShowMsg(
+ _context.API.GetTranslation("flowlauncher_plugin_sys_dlgtitle_success"),
+ _context.API.GetTranslation(
"flowlauncher_plugin_sys_dlgtext_all_applicableplugins_reloaded")),
System.Threading.Tasks.TaskScheduler.Current);
@@ -451,75 +453,75 @@ private List Commands()
new Result
{
Title = "Check For Update",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update"),
IcoPath = "Images\\checkupdate.png",
Action = c =>
{
- context.API.HideMainWindow();
- context.API.CheckForNewUpdate();
+ _context.API.HideMainWindow();
+ _context.API.CheckForNewUpdate();
return true;
}
},
new Result
{
Title = "Open Log Location",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
CopyText = logPath,
AutoCompleteText = logPath,
Action = c =>
{
- context.API.OpenDirectory(logPath);
+ _context.API.OpenDirectory(logPath);
return true;
}
},
new Result
{
Title = "Flow Launcher Tips",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
CopyText = Constant.Documentation,
AutoCompleteText = Constant.Documentation,
Action = c =>
{
- context.API.OpenUrl(Constant.Documentation);
+ _context.API.OpenUrl(Constant.Documentation);
return true;
}
},
new Result
{
Title = "Flow Launcher UserData Folder",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
CopyText = userDataPath,
AutoCompleteText = userDataPath,
Action = c =>
{
- context.API.OpenDirectory(userDataPath);
+ _context.API.OpenDirectory(userDataPath);
return true;
}
},
new Result
{
Title = "Toggle Game Mode",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_toggle_game_mode"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_toggle_game_mode"),
IcoPath = "Images\\app.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
Action = c =>
{
- context.API.ToggleGameMode();
+ _context.API.ToggleGameMode();
return true;
}
},
new Result
{
Title = "Set Flow Launcher Theme",
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_theme_selector"),
+ SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_theme_selector"),
IcoPath = "Images\\app.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
Action = c =>
{
- context.API.ChangeQuery($"{ThemeSelector.Keyword} ");
+ _context.API.ChangeQuery($"{ThemeSelector.Keyword} ");
return false;
}
}
@@ -530,12 +532,17 @@ private List Commands()
public string GetTranslatedPluginTitle()
{
- return context.API.GetTranslation("flowlauncher_plugin_sys_plugin_name");
+ return _context.API.GetTranslation("flowlauncher_plugin_sys_plugin_name");
}
public string GetTranslatedPluginDescription()
{
- return context.API.GetTranslation("flowlauncher_plugin_sys_plugin_description");
+ return _context.API.GetTranslation("flowlauncher_plugin_sys_plugin_description");
+ }
+
+ public void OnCultureInfoChanged(CultureInfo _)
+ {
+ UpdateLocalizedNameDescription(true);
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
index 539801a0b1c..0a38fda0432 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
@@ -5,11 +5,13 @@ namespace Flow.Launcher.Plugin.Sys
{
public partial class SysSettings : UserControl
{
+ private readonly PluginInitContext _context;
private readonly Settings _settings;
- public SysSettings(SettingsViewModel viewModel)
+ public SysSettings(PluginInitContext context, SettingsViewModel viewModel)
{
InitializeComponent();
+ _context = context;
_settings = viewModel.Settings;
DataContext = viewModel;
}
@@ -36,24 +38,16 @@ private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
public void OnEditCommandKeywordClick(object sender, RoutedEventArgs e)
{
- /*var webSearch = new SearchSourceSettingWindow
- (
- _settings.SearchSources, _context, _settings.SelectedSearchSource
- );
-
- webSearch.ShowDialog();*/
+ var commandKeyword = new CommandKeywordSettingWindow(_context, _settings.SelectedCommand);
+ commandKeyword.ShowDialog();
}
private void MouseDoubleClickItem(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (((FrameworkElement)e.OriginalSource).DataContext is Command && _settings.SelectedCommand != null)
{
- /*var webSearch = new SearchSourceSettingWindow
- (
- _settings.SearchSources, _context, _settings.SelectedSearchSource
- );
-
- webSearch.ShowDialog();*/
+ var commandKeyword = new CommandKeywordSettingWindow(_context, _settings.SelectedCommand);
+ commandKeyword.ShowDialog();
}
}
}
From e196d7cfa947aafc41f6ed78eb3f006e9eb52c0c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 23:43:01 +0800
Subject: [PATCH 0467/1335] Improve keyword search
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 61 ++----------------------
1 file changed, 5 insertions(+), 56 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index fd72ddcaffc..5a250576916 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using Flow.Launcher.Infrastructure;
@@ -73,19 +74,15 @@ public List Query(Query query)
var results = new List();
foreach (var c in commands)
{
- c.Title = GetDynamicTitle(query, c);
+ var command = _settings.Commands.First(x => x.Key == c.Title);
+ c.Title = command.Name;
+ c.SubTitle = command.Description;
- var titleMatch = StringMatcher.FuzzySearch(query.Search, c.Title);
- var subTitleMatch = StringMatcher.FuzzySearch(query.Search, c.SubTitle);
-
- var score = Math.Max(titleMatch.Score, subTitleMatch.Score);
+ var score = _context.API.FuzzySearch(query.Search, command.Keyword).Score;
if (score > 0)
{
c.Score = score;
- if (score == titleMatch.Score)
- c.TitleHighlightData = titleMatch.MatchData;
-
results.Add(c);
}
}
@@ -115,33 +112,6 @@ private string GetDescription(string key)
return _context.API.GetTranslation(translationKey);
}
- [Obsolete]
- private string GetDynamicTitle(Query query, Result result)
- {
- if (!KeywordTitleMappings.TryGetValue(result.Title, out var translationKey))
- {
- Log.Error("Flow.Launcher.Plugin.Sys.Main", $"Dynamic Title not found for: {result.Title}");
- return "Title Not Found";
- }
-
- var translatedTitle = _context.API.GetTranslation(translationKey);
-
- if (query == null)
- {
- return translatedTitle;
- }
-
- if (result.Title == translatedTitle)
- {
- return result.Title;
- }
-
- var englishTitleMatch = StringMatcher.FuzzySearch(query.Search, result.Title);
- var translatedTitleMatch = StringMatcher.FuzzySearch(query.Search, translatedTitle);
-
- return englishTitleMatch.Score >= translatedTitleMatch.Score ? result.Title : translatedTitle;
- }
-
public void Init(PluginInitContext context)
{
_context = context;
@@ -216,7 +186,6 @@ private List Commands()
new Result
{
Title = "Shutdown",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_shutdown_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe7e8"),
IcoPath = "Images\\shutdown.png",
Action = c =>
@@ -238,7 +207,6 @@ private List Commands()
new Result
{
Title = "Restart",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart_computer"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe777"),
IcoPath = "Images\\restart.png",
Action = c =>
@@ -260,7 +228,6 @@ private List Commands()
new Result
{
Title = "Restart With Advanced Boot Options",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart_advanced"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xecc5"),
IcoPath = "Images\\restart_advanced.png",
Action = c =>
@@ -282,7 +249,6 @@ private List Commands()
new Result
{
Title = "Log Off/Sign Out",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_log_off"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe77b"),
IcoPath = "Images\\logoff.png",
Action = c =>
@@ -301,7 +267,6 @@ private List Commands()
new Result
{
Title = "Lock",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_lock"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe72e"),
IcoPath = "Images\\lock.png",
Action = c =>
@@ -313,7 +278,6 @@ private List Commands()
new Result
{
Title = "Sleep",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_sleep"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xec46"),
IcoPath = "Images\\sleep.png",
Action = c =>
@@ -325,7 +289,6 @@ private List Commands()
new Result
{
Title = "Hibernate",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_hibernate"),
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe945"),
IcoPath = "Images\\hibernate.png",
Action= c =>
@@ -337,7 +300,6 @@ private List Commands()
new Result
{
Title = "Index Option",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_indexoption"),
IcoPath = "Images\\indexoption.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe773"),
Action = c =>
@@ -349,7 +311,6 @@ private List Commands()
new Result
{
Title = "Empty Recycle Bin",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_emptyrecyclebin"),
IcoPath = "Images\\recyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
Action = c =>
@@ -374,7 +335,6 @@ private List Commands()
new Result
{
Title = "Open Recycle Bin",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_openrecyclebin"),
IcoPath = "Images\\openrecyclebin.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe74d"),
CopyText = recycleBinFolder,
@@ -387,7 +347,6 @@ private List Commands()
new Result
{
Title = "Exit",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_exit"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -398,7 +357,6 @@ private List Commands()
new Result
{
Title = "Save Settings",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_save_all_settings"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -411,7 +369,6 @@ private List Commands()
new Result
{
Title = "Restart Flow Launcher",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_restart"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -422,7 +379,6 @@ private List Commands()
new Result
{
Title = "Settings",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_setting"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -433,7 +389,6 @@ private List Commands()
new Result
{
Title = "Reload Plugin Data",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_reload_plugin_data"),
IcoPath = "Images\\app.png",
Action = c =>
{
@@ -453,7 +408,6 @@ private List Commands()
new Result
{
Title = "Check For Update",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_check_for_update"),
IcoPath = "Images\\checkupdate.png",
Action = c =>
{
@@ -465,7 +419,6 @@ private List Commands()
new Result
{
Title = "Open Log Location",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_log_location"),
IcoPath = "Images\\app.png",
CopyText = logPath,
AutoCompleteText = logPath,
@@ -478,7 +431,6 @@ private List Commands()
new Result
{
Title = "Flow Launcher Tips",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_docs_tips"),
IcoPath = "Images\\app.png",
CopyText = Constant.Documentation,
AutoCompleteText = Constant.Documentation,
@@ -491,7 +443,6 @@ private List Commands()
new Result
{
Title = "Flow Launcher UserData Folder",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_open_userdata_location"),
IcoPath = "Images\\app.png",
CopyText = userDataPath,
AutoCompleteText = userDataPath,
@@ -504,7 +455,6 @@ private List Commands()
new Result
{
Title = "Toggle Game Mode",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_toggle_game_mode"),
IcoPath = "Images\\app.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
Action = c =>
@@ -516,7 +466,6 @@ private List Commands()
new Result
{
Title = "Set Flow Launcher Theme",
- SubTitle = _context.API.GetTranslation("flowlauncher_plugin_sys_theme_selector"),
IcoPath = "Images\\app.png",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
Action = c =>
From 0f279df8d307006018cad1ed72df5ead5b488004 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 13 Mar 2025 23:57:52 +0800
Subject: [PATCH 0468/1335] Add title & subtitle search
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 5a250576916..d716484bb27 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -78,7 +78,23 @@ public List Query(Query query)
c.Title = command.Name;
c.SubTitle = command.Description;
- var score = _context.API.FuzzySearch(query.Search, command.Keyword).Score;
+ // Firstly, we will search the localized title & subtitle
+ var titleMatch = _context.API.FuzzySearch(query.Search, c.Title);
+ var subTitleMatch = _context.API.FuzzySearch(query.Search, c.SubTitle);
+
+ var score = Math.Max(titleMatch.Score, subTitleMatch.Score);
+ if (score > 0)
+ {
+ c.Score = score;
+
+ if (score == titleMatch.Score)
+ c.TitleHighlightData = titleMatch.MatchData;
+
+ results.Add(c);
+ }
+
+ // If no match found, we will search the keyword
+ score = _context.API.FuzzySearch(query.Search, command.Keyword).Score;
if (score > 0)
{
c.Score = score;
From 2cd769b1e9552a4e74e951204644dc0aa30fdc1d Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 14 Mar 2025 10:00:31 +0900
Subject: [PATCH 0469/1335] Fix UI thread issue and preview
---
Flow.Launcher.Core/Resource/Theme.cs | 501 +++++++-----------
Flow.Launcher/MainWindow.xaml.cs | 1 +
.../ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
Flow.Launcher/Themes/BlurBlack Darker.xaml | 6 +-
Flow.Launcher/Themes/BlurBlack.xaml | 6 +-
Flow.Launcher/Themes/BlurWhite.xaml | 6 +-
Flow.Launcher/Themes/Circle System.xaml | 6 +-
Flow.Launcher/Themes/Win10System.xaml | 4 +
Flow.Launcher/Themes/Win11Light.xaml | 6 +-
9 files changed, 221 insertions(+), 317 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 36b63a9c207..da3f9f7080c 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -132,50 +132,64 @@ public static int SetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIB
=> DwmSetWindowAttribute(hwnd, attribute, ref parameter, Marshal.SizeOf());
}
- System.Windows.Window mainWindow = Application.Current.MainWindow;
+ private System.Windows.Window GetMainWindow()
+ {
+ return Application.Current.Dispatcher.Invoke(() => Application.Current.MainWindow);
+ }
+
public void RefreshFrame()
{
- IntPtr mainWindowPtr = new WindowInteropHelper(mainWindow).Handle;
- if (mainWindowPtr == IntPtr.Zero)
- return;
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ System.Windows.Window mainWindow = Application.Current.MainWindow;
+ if (mainWindow == null)
+ return;
- HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
- if (mainWindowSrc == null)
- return;
+ IntPtr mainWindowPtr = new WindowInteropHelper(mainWindow).Handle;
+ if (mainWindowPtr == IntPtr.Zero)
+ return;
- ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
- margins.cxLeftWidth = -1;
- margins.cxRightWidth = -1;
- margins.cyTopHeight = -1;
- margins.cyBottomHeight = -1;
- Methods.ExtendFrame(mainWindowSrc.Handle, margins);
+ HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
+ if (mainWindowSrc == null)
+ return;
- // Remove OS minimizing/maximizing animation
- // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
+ ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS();
+ margins.cxLeftWidth = -1;
+ margins.cxRightWidth = -1;
+ margins.cyTopHeight = -1;
+ margins.cyBottomHeight = -1;
+ Methods.ExtendFrame(mainWindowSrc.Handle, margins);
- // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
- // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
+ // Remove OS minimizing/maximizing animation
+ // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
- // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
- if (BlurEnabled)
- {
- AutoDropShadow();
- }
- SetBlurForWindow();
+ // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000);
+ // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- if (!BlurEnabled)
- {
- AutoDropShadow();
- }
+ // The timing of adding the shadow effect should vary depending on whether the theme is transparent.
+ if (BlurEnabled)
+ {
+ AutoDropShadow();
+ }
+ SetBlurForWindow();
+
+ if (!BlurEnabled)
+ {
+ AutoDropShadow();
+ }
+ }, DispatcherPriority.Normal);
}
+
public void AutoDropShadow()
{
+ SetWindowCornerPreference("Default");
+ RemoveDropShadowEffectFromCurrentTheme();
if (_settings.UseDropShadowEffect)
{
- RemoveDropShadowEffectFromCurrentTheme();
+ //RemoveDropShadowEffectFromCurrentTheme();
if (BlurEnabled)
{
SetWindowCornerPreference("Round");
@@ -188,7 +202,7 @@ public void AutoDropShadow()
}
else
{
- RemoveDropShadowEffectFromCurrentTheme();
+ //RemoveDropShadowEffectFromCurrentTheme();
if (BlurEnabled)
{
SetWindowCornerPreference("Default");
@@ -202,108 +216,130 @@ public void AutoDropShadow()
public void SetWindowCornerPreference(string cornerType)
{
- DWM_WINDOW_CORNER_PREFERENCE preference = cornerType switch
+ Application.Current.Dispatcher.Invoke(() =>
{
- "DoNotRound" => DWM_WINDOW_CORNER_PREFERENCE.DoNotRound,
- "Round" => DWM_WINDOW_CORNER_PREFERENCE.Round,
- "RoundSmall" => DWM_WINDOW_CORNER_PREFERENCE.RoundSmall,
- "Default" => DWM_WINDOW_CORNER_PREFERENCE.Default,
- _ => DWM_WINDOW_CORNER_PREFERENCE.Default,
- };
-
- SetWindowCornerPreference(mainWindow, preference);
- }
+ System.Windows.Window mainWindow = GetMainWindow();
+ if (mainWindow == null)
+ return;
- public void SetCornerForWindow()
- {
- var dict = GetThemeResourceDictionary(_settings.Theme);
- if (dict == null)
- return;
- if (dict.Contains("CornerType") && dict["CornerType"] is string cornerMode)
- {
- DWM_WINDOW_CORNER_PREFERENCE preference = cornerMode switch
+ DWM_WINDOW_CORNER_PREFERENCE preference = cornerType switch
{
"DoNotRound" => DWM_WINDOW_CORNER_PREFERENCE.DoNotRound,
"Round" => DWM_WINDOW_CORNER_PREFERENCE.Round,
"RoundSmall" => DWM_WINDOW_CORNER_PREFERENCE.RoundSmall,
+ "Default" => DWM_WINDOW_CORNER_PREFERENCE.Default,
_ => DWM_WINDOW_CORNER_PREFERENCE.Default,
};
SetWindowCornerPreference(mainWindow, preference);
-
- }
- else
+ }, DispatcherPriority.Normal);
+ }
+
+
+ public void SetCornerForWindow()
+ {
+ Application.Current.Dispatcher.Invoke(() =>
{
- SetWindowCornerPreference(mainWindow, DWM_WINDOW_CORNER_PREFERENCE.Default);
-
- }
+ var dict = GetThemeResourceDictionary(_settings.Theme);
+ if (dict == null)
+ return;
+
+ System.Windows.Window mainWindow = Application.Current.MainWindow;
+ if (mainWindow == null)
+ return;
+
+ if (dict.Contains("CornerType") && dict["CornerType"] is string cornerMode)
+ {
+ DWM_WINDOW_CORNER_PREFERENCE preference = cornerMode switch
+ {
+ "DoNotRound" => DWM_WINDOW_CORNER_PREFERENCE.DoNotRound,
+ "Round" => DWM_WINDOW_CORNER_PREFERENCE.Round,
+ "RoundSmall" => DWM_WINDOW_CORNER_PREFERENCE.RoundSmall,
+ _ => DWM_WINDOW_CORNER_PREFERENCE.Default,
+ };
+
+ SetWindowCornerPreference(mainWindow, preference);
+ }
+ else
+ {
+ SetWindowCornerPreference(mainWindow, DWM_WINDOW_CORNER_PREFERENCE.Default);
+ }
+ }, DispatcherPriority.Normal);
}
+
///
/// Sets the blur for a window via SetWindowCompositionAttribute
///
public void SetBlurForWindow()
{
- var dict = GetThemeResourceDictionary(_settings.Theme);
- if (dict == null)
- return;
-
- var windowBorderStyle = dict["WindowBorderStyle"] as Style;
- if (windowBorderStyle == null)
- return;
-
- // ✅ 설정된 BackdropType 확인
- int backdropValue = _settings.BackdropType switch
+ Application.Current.Dispatcher.Invoke(() =>
{
- BackdropTypes.Acrylic => 3, // Acrylic (DWM_SYSTEMBACKDROP_TYPE = 2)
- BackdropTypes.Mica => 2, // Mica (DWM_SYSTEMBACKDROP_TYPE = 3)
- BackdropTypes.MicaAlt => 4, // MicaAlt (DWM_SYSTEMBACKDROP_TYPE = 4)
- _ => 0 // None (DWM_SYSTEMBACKDROP_TYPE = 0)
- };
-
- Debug.WriteLine("~~~~~~~~~~~~~~~~~~~~");
- Debug.WriteLine($"Backdrop Mode: {BlurMode()}, DWM Value: {backdropValue}");
+ var dict = GetThemeResourceDictionary(_settings.Theme);
+ if (dict == null)
+ return;
+ var windowBorderStyle = dict.Contains("WindowBorderStyle") ? dict["WindowBorderStyle"] as Style : null;
+ if (windowBorderStyle == null)
+ return;
+ System.Windows.Window mainWindow = GetMainWindow();
+ if (mainWindow == null)
+ return;
- if (BlurEnabled)
- {
- // ✅ Mica 또는 MicaAlt인 경우 배경을 투명하게 설정
- if (_settings.BackdropType == BackdropTypes.Mica || _settings.BackdropType == BackdropTypes.MicaAlt)
+ // ✅ 테마가 블러를 지원하는지 확인
+ bool hasBlur = dict.Contains("ThemeBlurEnabled") && dict["ThemeBlurEnabled"] is bool b && b;
+ if (!hasBlur)
{
- windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
- windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Color.FromArgb(1, 0, 0, 0)))); // 드래그 가능 투명색
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
- ThemeModeColorforMica(BlurMode()); // ✅ 테마 모드 적용
+ _settings.BackdropType = BackdropTypes.None; // 🔥 블러가 없는 테마는 강제 None 처리
}
- else if (_settings.BackdropType == BackdropTypes.Acrylic)
+
+ // ✅ 설정된 BackdropType 확인
+ int backdropValue = _settings.BackdropType switch
{
- windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
- windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
- //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
- ThemeModeColor(BlurMode()); // ✅ 테마 모드 적용
+ BackdropTypes.Acrylic => 3, // Acrylic
+ BackdropTypes.Mica => 2, // Mica
+ BackdropTypes.MicaAlt => 4, // MicaAlt
+ _ => 0 // None
+ };
+
+ if (BlurEnabled && hasBlur)
+ {
+ // ✅ Mica 또는 MicaAlt인 경우 배경을 투명하게 설정
+ if (_settings.BackdropType == BackdropTypes.Mica || _settings.BackdropType == BackdropTypes.MicaAlt)
+ {
+ windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
+ windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Color.FromArgb(1, 0, 0, 0))));
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
+ ColorizeWindow(GetSystemBG());
+ }
+ else if (_settings.BackdropType == BackdropTypes.Acrylic)
+ {
+ windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
+ windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
+ ColorizeWindow(GetSystemBG());
+ }
+ else
+ {
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
+ ColorizeWindow(GetSystemBG());
+ }
}
else
{
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, backdropValue);
- ThemeModeColor(BlurMode()); // ✅ 테마 모드 적용
- //windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType().FirstOrDefault(x => x.Property.Name == "Background"));
- //windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
+ // ✅ Blur가 비활성화되면 기본 스타일 적용
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 0);
+ ColorizeWindow(GetSystemBG());
}
- }
- else
- {
- // ✅ Blur가 비활성화되면 기본 스타일 적용
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 0);
- ThemeModeColor(BlurMode());
- }
-
- UpdateResourceDictionary(dict);
+ UpdateResourceDictionary(dict);
+ }, DispatcherPriority.Normal);
}
+
+
// Get Background Color from WindowBorderStyle when there not color for BG.
private Color GetWindowBorderStyleBackground()
{
@@ -347,249 +383,112 @@ private Color GetWindowBorderStyleBackground()
return Colors.Transparent; // Default is transparent
}
- private void ApplyPreviewBackground(Color bgColor)
+ private void ApplyPreviewBackground(Color? bgColor = null)
{
+ if (bgColor == null) return;
+
Application.Current.Dispatcher.Invoke(() =>
{
- Style baseStyle = null;
-
- // ✅ `WindowBorderStyle`이 존재하면 가져오기
+ // 1. 기존 WindowBorderStyle을 복사
+ var previewStyle = new Style(typeof(Border));
if (Application.Current.Resources.Contains("WindowBorderStyle"))
{
- baseStyle = Application.Current.Resources["WindowBorderStyle"] as Style;
- }
-
- // ✅ `WindowBorderStyle`이 없으면 `Base.xaml`의 기본 스타일 사용
- if (baseStyle == null && Application.Current.Resources.Contains("BaseWindowBorderStyle"))
- {
- baseStyle = Application.Current.Resources["BaseWindowBorderStyle"] as Style;
- }
-
- // ✅ 투명도가 존재하면 불투명한 색상으로 변경
- if (bgColor.A < 255)
- {
- bgColor = Color.FromRgb(bgColor.R, bgColor.G, bgColor.B); // 알파값 제거
- }
-
- // ✅ 기존 스타일이 존재하면 복사하여 새로운 스타일 생성
- if (baseStyle != null)
- {
- var newStyle = new Style(typeof(Border));
-
- // ✅ 기존 스타일의 Setter를 복사 (Background 제외)
- foreach (var setter in baseStyle.Setters.OfType())
+ var originalStyle = Application.Current.Resources["WindowBorderStyle"] as Style;
+ if (originalStyle != null)
{
- if (setter.Property != Border.BackgroundProperty) // Background는 새 값으로 대체
+ foreach (var setter in originalStyle.Setters.OfType())
{
- newStyle.Setters.Add(new Setter(setter.Property, setter.Value));
+ previewStyle.Setters.Add(new Setter(setter.Property, setter.Value));
}
}
+ }
- // ✅ 새로운 Background Setter 추가
- newStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(bgColor)));
+ // 2. 투명도 제거 후 background 적용
+ Color backgroundColor = Color.FromRgb(bgColor.Value.R, bgColor.Value.G, bgColor.Value.B);
+ previewStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(backgroundColor)));
- // ✅ 새 스타일을 `PreviewWindowBorderStyle`로 적용
- Application.Current.Resources["PreviewWindowBorderStyle"] = newStyle;
- }
- else
- {
- // ✅ `WindowBorderStyle`이 없으면 기본 스타일 생성
- var defaultStyle = new Style(typeof(Border));
- defaultStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(bgColor)));
- defaultStyle.Setters.Add(new Setter(Border.BorderThicknessProperty, new Thickness(0)));
- defaultStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(5)));
- defaultStyle.Setters.Add(new Setter(Border.UseLayoutRoundingProperty, true));
- defaultStyle.Setters.Add(new Setter(Border.SnapsToDevicePixelsProperty, true));
+ // 3. 기타 설정 추가
+ previewStyle.Setters.Add(new Setter(Border.BorderThicknessProperty, new Thickness(0)));
+ previewStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(5)));
+ previewStyle.Setters.Add(new Setter(Border.UseLayoutRoundingProperty, true));
+ previewStyle.Setters.Add(new Setter(Border.SnapsToDevicePixelsProperty, true));
- Application.Current.Resources["PreviewWindowBorderStyle"] = defaultStyle;
- }
+ Application.Current.Resources["PreviewWindowBorderStyle"] = previewStyle;
}, DispatcherPriority.Render);
}
-
-
- public void ThemeModeColor(string Mode)
+ public void ColorizeWindow(string Mode)
{
- var dict = GetThemeResourceDictionary(_settings.Theme);
-
- Color lightBG;
- Color darkBG;
-
- // get lightBG value. if not, get windowborderstyle's background.
- try
- {
- lightBG = dict.Contains("lightBG") ? (Color)dict["lightBG"] : GetWindowBorderStyleBackground();
- }
- catch (Exception)
+ Application.Current.Dispatcher.Invoke(() =>
{
- // if not lightBG, use windowborderstyle's background.
- lightBG = GetWindowBorderStyleBackground();
- }
+ var dict = GetThemeResourceDictionary(_settings.Theme);
+ if (dict == null) return;
- // get darkBG value, (if not, use lightBG)
- try
- {
- darkBG = dict.Contains("darkBG") ? (Color)dict["darkBG"] : lightBG;
- }
- catch (Exception)
- {
- darkBG = lightBG; // if not darkBG, use lightBG
- }
+ var mainWindow = Application.Current.MainWindow;
+ if (mainWindow == null) return;
- if (Mode == "Auto")
- {
- int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
- string colorScheme = _settings.ColorScheme;
- bool isDarkMode = themeValue == 0; // 0 is dark mode.
+ // ✅ 블러 테마인지 확인
+ bool hasBlur = dict.Contains("ThemeBlurEnabled") && dict["ThemeBlurEnabled"] is bool b && b;
+
+ Color LightBG;
+ Color DarkBG;
- if (colorScheme == "System")
+ // LightBG 값 가져오기 (없으면 WindowBorderStyle의 배경색 사용)
+ try
{
- if (isDarkMode)
- {
- ApplyPreviewBackground(darkBG);
- mainWindow.Background = new SolidColorBrush(darkBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
- }
- else
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(lightBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
- }
+ LightBG = dict.Contains("LightBG") ? (Color)dict["LightBG"] : GetWindowBorderStyleBackground();
}
- else
+ catch (Exception)
{
- if (colorScheme == "Dark")
- {
- ApplyPreviewBackground(darkBG);
- mainWindow.Background = new SolidColorBrush(darkBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
- }
- else if (colorScheme == "Light")
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(lightBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
- }
+ LightBG = GetWindowBorderStyleBackground();
}
- }
- else if (Mode == "Dark")
- {
- mainWindow.Background = new SolidColorBrush(darkBG);
- ApplyPreviewBackground(darkBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
- }
- else if (Mode == "Light")
- {
- mainWindow.Background = new SolidColorBrush(lightBG);
- ApplyPreviewBackground(lightBG);
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
- }
- else
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- }
- }
- public void ThemeModeColorforMica(string Mode)
- {
- var dict = GetThemeResourceDictionary(_settings.Theme);
-
- Color lightBG;
- Color darkBG;
-
- // get lightBG value. if not, get windowborderstyle's background.
- try
- {
- lightBG = dict.Contains("lightBG") ? (Color)dict["lightBG"] : GetWindowBorderStyleBackground();
- }
- catch (Exception)
- {
- // if not lightBG, use windowborderstyle's background.
- lightBG = GetWindowBorderStyleBackground();
- }
-
- // get darkBG value, (if not, use lightBG)
- try
- {
- darkBG = dict.Contains("darkBG") ? (Color)dict["darkBG"] : lightBG;
- }
- catch (Exception)
- {
- darkBG = lightBG; // if not darkBG, use lightBG
- }
+ // DarkBG 값 가져오기 (없으면 LightBG 사용)
+ try
+ {
+ DarkBG = dict.Contains("DarkBG") ? (Color)dict["DarkBG"] : LightBG;
+ }
+ catch (Exception)
+ {
+ DarkBG = LightBG;
+ }
- if (Mode == "Auto")
- {
+ // ✅ 설정의 ColorScheme을 우선 사용
int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
- string colorScheme = _settings.ColorScheme;
- bool isDarkMode = themeValue == 0; // 0 is dark mode.
+ bool isSystemDark = themeValue == 0;
+ bool useDarkMode = Mode == "Dark" || (Mode == "Auto" && _settings.ColorScheme == "System" && isSystemDark) || (_settings.ColorScheme == "Dark");
- if (colorScheme == "System")
+ Color selectedBG = useDarkMode ? DarkBG : LightBG;
+ ApplyPreviewBackground(selectedBG);
+
+ // ✅ Windows 10 테마(HasBlur=False)는 mainWindow.Background를 설정하지 않음
+ if (!hasBlur)
{
- if (isDarkMode)
- {
- ApplyPreviewBackground(darkBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
- }
- else
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
- }
+ mainWindow.Background = Brushes.Transparent;
}
else
{
- if (colorScheme == "Dark")
+ // ✅ 블러 테마일 경우만 배경을 투명하게 설정
+ if (_settings.BackdropType == BackdropTypes.Mica || _settings.BackdropType == BackdropTypes.MicaAlt)
{
- ApplyPreviewBackground(darkBG);
mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
}
- else if (colorScheme == "Light")
+ else
{
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
+ mainWindow.Background = new SolidColorBrush(selectedBG);
}
}
- }
- else if (Mode == "Dark")
- {
- ApplyPreviewBackground(darkBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
- return;
- }
- else if (Mode == "Light")
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
- return;
- }
- else
- {
- ApplyPreviewBackground(lightBG);
- mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
- }
+
+ // ✅ DWM 다크 모드 적용
+ Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, useDarkMode ? 1 : 0);
+ }, DispatcherPriority.Normal);
}
+
+
+
public bool IsBlurTheme()
{
if (Environment.OSVersion.Version >= new Version(6, 2))
@@ -604,11 +503,11 @@ public bool IsBlurTheme()
return false;
}
- public string BlurMode()
+ public string GetSystemBG()
{
if (Environment.OSVersion.Version >= new Version(6, 2))
{
- var resource = Application.Current.TryFindResource("BlurMode");
+ var resource = Application.Current.TryFindResource("SystemBG");
if (resource is string)
return (string)resource;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 37f8e6262a5..9f8063a87d4 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -193,6 +193,7 @@ private void OnLoaded(object sender, RoutedEventArgs _)
{
ThemeManager.Instance.RefreshFrame();
}), DispatcherPriority.Background);
+
// MouseEventHandler
PreviewMouseMove += MainPreviewMouseMove;
CheckFirstLaunch();
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 5c668d5ab39..2f8332684ec 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -41,7 +41,7 @@ public Theme.ThemeData SelectedTheme
DropShadowEffect = true;
OnPropertyChanged(nameof(IsDropShadowEnabled));
ThemeManager.Instance.RefreshFrame();
- //uThemeManager.Instance.SetBlurForWindow();
+ //ThemeManager.Instance.SetBlurForWindow();
}
}
public bool IsBackdropEnabled => SelectedTheme?.HasBlur ?? false;
diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml
index f4d5f9908fd..99cd9af0e4f 100644
--- a/Flow.Launcher/Themes/BlurBlack Darker.xaml
+++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml
@@ -12,10 +12,10 @@
True
- Dark
+ Dark
DoNotRound
- #C7000000
- #C7000000
+ #C7000000
+ #C7000000
From aeb3f22f7d56417d70f4936d9e207ff597009762 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 15 Mar 2025 15:02:07 +0900
Subject: [PATCH 0490/1335] - rollback pin theme to legacy
---
Flow.Launcher/Themes/Pink.xaml | 75 +++++++++++++++-------------------
1 file changed, 32 insertions(+), 43 deletions(-)
diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml
index 90592bb99ff..d7de4e2467d 100644
--- a/Flow.Launcher/Themes/Pink.xaml
+++ b/Flow.Launcher/Themes/Pink.xaml
@@ -1,55 +1,46 @@
-
+
- True
- Light
- RoundSmall
- #B6C8C7FE
- #53FEC7D7
- 0 0 0 0
+ 0 0 0 4
- #0e172c
+ #cc1081
\ No newline at end of file
From 9b60eac42b0dcc4865475bd672d0812fd3666da2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 15 Mar 2025 21:50:10 +0800
Subject: [PATCH 0491/1335] Code cleanup
---
Flow.Launcher/MainWindow.xaml.cs | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 6836d9b3a53..1d4a2610104 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -62,7 +62,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
DataObject.AddPastingHandler(QueryTextBox, OnPaste);
- this.Loaded += (_, _) =>
+ Loaded += (_, _) =>
{
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
@@ -70,11 +70,6 @@ public MainWindow(Settings settings, MainViewModel mainVM)
};
}
- public MainWindow()
- {
- InitializeComponent();
- }
-
private int _initialWidth;
private int _initialHeight;
From b1a46817f01439beab05e1fc59d7ff19fe80d2bd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 15 Mar 2025 21:58:55 +0800
Subject: [PATCH 0492/1335] Support search delay
---
.../UserSettings/Settings.cs | 3 +
Flow.Launcher/Flow.Launcher.csproj | 1 +
Flow.Launcher/MainWindow.xaml.cs | 174 +++++++++++++-----
Flow.Launcher/ViewModel/MainViewModel.cs | 3 +-
4 files changed, 130 insertions(+), 51 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 93f6db111a2..66da9f59a5a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -275,6 +275,9 @@ public bool HideNotifyIcon
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
+ public bool SearchQueryResultsWithDelay { get; set; } = false;
+ public int SearchInputDelay { get; set; } = 150;
+
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 1e305d3d9cf..d4508ad67f3 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -104,6 +104,7 @@
+
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 3616e4c59ca..2f1b2ce660d 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -5,7 +5,6 @@
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Controls;
-using System.Windows.Forms;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@@ -27,6 +26,7 @@
using System.Windows.Media;
using System.Windows.Interop;
using Windows.Win32;
+using System.Reactive.Linq;
namespace Flow.Launcher
{
@@ -68,6 +68,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
+ SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay);
};
}
@@ -204,63 +205,63 @@ private void OnLoaded(object sender, RoutedEventArgs _)
switch (e.PropertyName)
{
case nameof(MainViewModel.MainWindowVisibilityStatus):
- {
- Dispatcher.Invoke(() =>
{
- if (_viewModel.MainWindowVisibilityStatus)
+ Dispatcher.Invoke(() =>
{
- if (_settings.UseSound)
+ if (_viewModel.MainWindowVisibilityStatus)
{
- SoundPlay();
+ if (_settings.UseSound)
+ {
+ SoundPlay();
+ }
+
+ UpdatePosition();
+ PreviewReset();
+ Activate();
+ QueryTextBox.Focus();
+ _settings.ActivateTimes++;
+ if (!_viewModel.LastQuerySelected)
+ {
+ QueryTextBox.SelectAll();
+ _viewModel.LastQuerySelected = true;
+ }
+
+ if (_viewModel.ProgressBarVisibility == Visibility.Visible &&
+ isProgressBarStoryboardPaused)
+ {
+ _progressBarStoryboard.Begin(ProgressBar, true);
+ isProgressBarStoryboardPaused = false;
+ }
+
+ if (_settings.UseAnimation)
+ WindowAnimator();
}
-
- UpdatePosition();
- PreviewReset();
- Activate();
- QueryTextBox.Focus();
- _settings.ActivateTimes++;
- if (!_viewModel.LastQuerySelected)
+ else if (!isProgressBarStoryboardPaused)
{
- QueryTextBox.SelectAll();
- _viewModel.LastQuerySelected = true;
+ _progressBarStoryboard.Stop(ProgressBar);
+ isProgressBarStoryboardPaused = true;
}
-
- if (_viewModel.ProgressBarVisibility == Visibility.Visible &&
- isProgressBarStoryboardPaused)
+ });
+ break;
+ }
+ case nameof(MainViewModel.ProgressBarVisibility):
+ {
+ Dispatcher.Invoke(() =>
+ {
+ if (_viewModel.ProgressBarVisibility == Visibility.Hidden && !isProgressBarStoryboardPaused)
+ {
+ _progressBarStoryboard.Stop(ProgressBar);
+ isProgressBarStoryboardPaused = true;
+ }
+ else if (_viewModel.MainWindowVisibilityStatus &&
+ isProgressBarStoryboardPaused)
{
_progressBarStoryboard.Begin(ProgressBar, true);
isProgressBarStoryboardPaused = false;
}
-
- if (_settings.UseAnimation)
- WindowAnimator();
- }
- else if (!isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Stop(ProgressBar);
- isProgressBarStoryboardPaused = true;
- }
- });
- break;
- }
- case nameof(MainViewModel.ProgressBarVisibility):
- {
- Dispatcher.Invoke(() =>
- {
- if (_viewModel.ProgressBarVisibility == Visibility.Hidden && !isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Stop(ProgressBar);
- isProgressBarStoryboardPaused = true;
- }
- else if (_viewModel.MainWindowVisibilityStatus &&
- isProgressBarStoryboardPaused)
- {
- _progressBarStoryboard.Begin(ProgressBar, true);
- isProgressBarStoryboardPaused = false;
- }
- });
- break;
- }
+ });
+ break;
+ }
case nameof(MainViewModel.QueryTextCursorMovedToEnd):
if (_viewModel.QueryTextCursorMovedToEnd)
{
@@ -415,10 +416,10 @@ private void InitializeNotifyIcon()
{
switch (e.Button)
{
- case MouseButtons.Left:
+ case System.Windows.Forms.MouseButtons.Left:
_viewModel.ToggleFlowLauncher();
break;
- case MouseButtons.Right:
+ case System.Windows.Forms.MouseButtons.Right:
contextMenu.IsOpen = true;
// Get context menu handle and bring it to the foreground
@@ -857,5 +858,78 @@ private void QueryTextBox_KeyUp(object sender, KeyEventArgs e)
be.UpdateSource();
}
}
+
+ #region Search Delay
+
+ // Edited from: https://github.com/microsoft/PowerToys
+
+ private IDisposable _reactiveSubscription;
+
+ private void SetupSearchTextBoxReactiveness(bool showResultsWithDelay)
+ {
+ if (_reactiveSubscription != null)
+ {
+ _reactiveSubscription.Dispose();
+ _reactiveSubscription = null;
+ }
+
+ QueryTextBox.TextChanged -= QueryTextBox_TextChanged;
+
+ if (showResultsWithDelay)
+ {
+ _reactiveSubscription = Observable.FromEventPattern(
+ conversion => (sender, eventArg) => conversion(sender, eventArg),
+ add => QueryTextBox.TextChanged += add,
+ remove => QueryTextBox.TextChanged -= remove)
+ .Do(@event => ClearAutoCompleteText((TextBox)@event.Sender))
+ .Throttle(TimeSpan.FromMilliseconds(_settings.SearchInputDelay))
+ .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery((TextBox)@event.Sender)))
+ .Subscribe();
+ }
+ else
+ {
+ QueryTextBox.TextChanged += QueryTextBox_TextChanged;
+ }
+ }
+
+ private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ var textBox = (TextBox)sender;
+ ClearAutoCompleteText(textBox);
+ PerformSearchQuery(textBox);
+ }
+
+ private void ClearAutoCompleteText(TextBox textBox)
+ {
+ var text = textBox.Text;
+ var autoCompleteText = QueryTextSuggestionBox.Text;
+
+ if (ShouldAutoCompleteTextBeEmpty(text, autoCompleteText))
+ {
+ QueryTextSuggestionBox.Text = string.Empty;
+ }
+ }
+
+ private static bool ShouldAutoCompleteTextBeEmpty(string queryText, string autoCompleteText)
+ {
+ if (string.IsNullOrEmpty(autoCompleteText))
+ {
+ return false;
+ }
+ else
+ {
+ // Using Ordinal this is internal
+ return string.IsNullOrEmpty(queryText) || !autoCompleteText.StartsWith(queryText, StringComparison.Ordinal);
+ }
+ }
+
+ private void PerformSearchQuery(TextBox textBox)
+ {
+ var text = textBox.Text;
+ _viewModel.QueryText = text;
+ _viewModel.Query();
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6b0144a0384..373ecdece15 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -569,7 +569,6 @@ public string QueryText
{
_queryText = value;
OnPropertyChanged();
- Query();
}
}
@@ -631,6 +630,7 @@ public void ChangeQueryText(string queryText, bool isReQuery = false)
{
// re-query is done in QueryText's setter method
QueryText = queryText;
+ Query();
// set to false so the subsequent set true triggers
// PropertyChanged and MoveQueryTextToEnd is called
QueryTextCursorMovedToEnd = false;
@@ -695,6 +695,7 @@ private ResultsViewModel SelectedResults
else
{
QueryText = string.Empty;
+ Query();
}
}
From 3abcebd02b6a0321c963fdd53e6067d30a10c153 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 15 Mar 2025 22:35:51 +0800
Subject: [PATCH 0493/1335] Add settings ui
---
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher/Languages/en.xaml | 4 ++++
Flow.Launcher/MainWindow.xaml.cs | 2 +-
.../SettingsPaneGeneralViewModel.cs | 16 ++++++++++++++
.../Views/SettingsPaneGeneral.xaml | 22 +++++++++++++++++++
5 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 66da9f59a5a..97ee49ef29c 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -276,7 +276,7 @@ public bool HideNotifyIcon
public bool HideWhenDeactivated { get; set; } = true;
public bool SearchQueryResultsWithDelay { get; set; } = false;
- public int SearchInputDelay { get; set; } = 150;
+ public int SearchInputDelay { get; set; } = 120;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index a3f87cd30d4..454dffd2415 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -94,6 +94,10 @@
Flow Launcher search window is hidden in the tray after starting up.
Hide tray icon
When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Search Delay Time
+ Delay time which search results appear when typing is stopped. Default is 120ms.
Query Search Precision
Changes minimum match score required for results.
None
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 2f1b2ce660d..9e7b380ed5c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -865,7 +865,7 @@ private void QueryTextBox_KeyUp(object sender, KeyEventArgs e)
private IDisposable _reactiveSubscription;
- private void SetupSearchTextBoxReactiveness(bool showResultsWithDelay)
+ public void SetupSearchTextBoxReactiveness(bool showResultsWithDelay)
{
if (_reactiveSubscription != null)
{
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index de4f158ad04..72bdb609bea 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -139,6 +139,22 @@ public bool PortableMode
}
}
+ public bool SearchQueryResultsWithDelay
+ {
+ get => Settings.SearchQueryResultsWithDelay;
+ set
+ {
+ Settings.SearchQueryResultsWithDelay = value;
+
+ ((MainWindow)System.Windows.Application.Current.MainWindow).SetupSearchTextBoxReactiveness(value);
+ }
+ }
+
+ public IEnumerable SearchInputDelayRange => new List()
+ {
+ 30, 60, 90, 120, 150, 180, 210, 240, 270, 300
+ };
+
public List LastQueryModes { get; } =
DropdownDataGeneric.GetValues("LastQuery");
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index a80e618e8b4..986e822e2a2 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -172,6 +172,28 @@
OnContent="{DynamicResource enable}" />
+
+
+
+
+
+
+
+
+
+
Date: Sat, 15 Mar 2025 22:44:42 +0800
Subject: [PATCH 0494/1335] Improve strings
---
Flow.Launcher/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 454dffd2415..2426d90af00 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -97,7 +97,7 @@
Search Delay
Delay for a while to search when typing. This reduces interface jumpiness and result load.
Search Delay Time
- Delay time which search results appear when typing is stopped. Default is 120ms.
+ Delay time after which search results appear when typing is stopped. Default is 120ms.
Query Search Precision
Changes minimum match score required for results.
None
From 53d647f2d06bd31233cac3308969c8cce414da67 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 16 Mar 2025 10:15:38 +0900
Subject: [PATCH 0495/1335] Adjust Themes for fluent
---
Flow.Launcher/Resources/Dark.xaml | 16 ++++++++--------
Flow.Launcher/Resources/Light.xaml | 14 +++++++-------
Flow.Launcher/Themes/BlurBlack Darker.xaml | 4 ++--
Flow.Launcher/Themes/BlurBlack.xaml | 4 ++--
Flow.Launcher/Themes/BlurWhite.xaml | 20 ++++++++++++++------
Flow.Launcher/Themes/Circle System.xaml | 9 +++++----
Flow.Launcher/Themes/Darker.xaml | 6 ++++--
Flow.Launcher/Themes/Win10System.xaml | 4 ++--
8 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml
index ed031c939e0..25cc8e878e3 100644
--- a/Flow.Launcher/Resources/Dark.xaml
+++ b/Flow.Launcher/Resources/Dark.xaml
@@ -7,17 +7,17 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib">
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
#198F8F8F
diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml
index 8fe84588f5e..b9f65ce9650 100644
--- a/Flow.Launcher/Resources/Light.xaml
+++ b/Flow.Launcher/Resources/Light.xaml
@@ -7,18 +7,18 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib">
-
+
-
-
+
+
-
-
-
- #198F8F8F
+
+
+
+ #0C000000
diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml
index 99cd9af0e4f..4cd8408fab2 100644
--- a/Flow.Launcher/Themes/BlurBlack Darker.xaml
+++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml
@@ -143,8 +143,8 @@
BasedOn="{StaticResource BaseSearchIconStyle}"
TargetType="{x:Type Path}">
-
-
+
+
+
@@ -79,7 +87,7 @@
x:Key="ItemSubTitleStyle"
BasedOn="{StaticResource BaseItemSubTitleStyle}"
TargetType="{x:Type TextBlock}">
-
+
+ Opacity="0.6"
+ Color="#33000000" />
@@ -79,7 +80,7 @@
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
TargetType="{x:Type Rectangle}">
-
+
diff --git a/Flow.Launcher/Themes/Darker.xaml b/Flow.Launcher/Themes/Darker.xaml
index d1abbe9789f..7d2614be897 100644
--- a/Flow.Launcher/Themes/Darker.xaml
+++ b/Flow.Launcher/Themes/Darker.xaml
@@ -29,7 +29,9 @@
+ TargetType="{x:Type Border}">
+
+
@@ -123,7 +125,7 @@
Date: Sun, 16 Mar 2025 10:33:06 +0800
Subject: [PATCH 0499/1335] Improve code quality
---
Flow.Launcher/MainWindow.xaml.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index a7dc8c1d197..06e19e05133 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -68,7 +68,6 @@ public MainWindow(Settings settings, MainViewModel mainVM)
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
win.AddHook(WndProc);
- SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay);
};
}
@@ -196,6 +195,8 @@ private void OnLoaded(object sender, RoutedEventArgs _)
InitializePosition();
InitializePosition();
PreviewReset();
+ // Setup search text box reactiveness
+ SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay);
// since the default main window visibility is visible
// so we need set focus during startup
QueryTextBox.Focus();
From ce55303e9e2c46aded0e928321a4b1da1de91667 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 16 Mar 2025 12:04:11 +0900
Subject: [PATCH 0500/1335] - Fix Logic for dwmBG - Remove Cornertypes in
themes
---
Flow.Launcher.Core/Resource/Theme.cs | 19 ++++++++++++++-----
.../ViewModels/SettingsPaneThemeViewModel.cs | 4 +---
Flow.Launcher/Themes/BlurBlack Darker.xaml | 1 -
Flow.Launcher/Themes/BlurBlack.xaml | 1 -
Flow.Launcher/Themes/BlurWhite.xaml | 1 -
Flow.Launcher/Themes/Circle System.xaml | 1 -
6 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 0dd1d5bbb9b..1ae755bd1ba 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -396,19 +396,26 @@ public void ColorizeWindow(string Mode)
// Final decision on whether to use dark mode
bool useDarkMode = false;
- if (colorScheme == "Dark" || systemBG == "Dark")
+ // If systemBG is not "Auto", prioritize it over ColorScheme and set the mode based on systemBG value
+ if (systemBG == "Dark")
{
useDarkMode = true; // Dark
}
- else if (colorScheme == "Light" || systemBG == "Light")
+ else if (systemBG == "Light")
{
useDarkMode = false; // Light
}
- else if (colorScheme == "System" || systemBG == "Auto")
+ else if (systemBG == "Auto")
{
- useDarkMode = isSystemDark; // Auto
+ // If systemBG is "Auto", decide based on ColorScheme
+ if (colorScheme == "Dark")
+ useDarkMode = true;
+ else if (colorScheme == "Light")
+ useDarkMode = false;
+ else
+ useDarkMode = isSystemDark; // Auto (based on system setting)
}
-
+
// Apply DWM Dark Mode
Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, useDarkMode ? 1 : 0);
@@ -458,6 +465,8 @@ public void ColorizeWindow(string Mode)
}, DispatcherPriority.Normal);
}
+
+
public bool IsBlurTheme()
{
if (Environment.OSVersion.Version >= new Version(6, 2))
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index dc9beec1cdf..87f5ed9229a 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -134,10 +134,8 @@ public string ColorScheme
Constant.System => null,
_ => ThemeManagerForColorSchemeSwitch.Current.ApplicationTheme
};
-
- ThemeManager.Instance.RefreshFrame();
-
Settings.ColorScheme = value;
+ ThemeManager.Instance.RefreshFrame();
}
}
diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml
index 4cd8408fab2..9f7e6f5b0bb 100644
--- a/Flow.Launcher/Themes/BlurBlack Darker.xaml
+++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml
@@ -13,7 +13,6 @@
True
Dark
- DoNotRound
#C7000000
#C7000000
diff --git a/Flow.Launcher/Themes/BlurBlack.xaml b/Flow.Launcher/Themes/BlurBlack.xaml
index 0e2f0e245ea..c45827074e1 100644
--- a/Flow.Launcher/Themes/BlurBlack.xaml
+++ b/Flow.Launcher/Themes/BlurBlack.xaml
@@ -12,7 +12,6 @@
True
Dark
- DoNotRound
#B0000000
#B6000000
diff --git a/Flow.Launcher/Themes/BlurWhite.xaml b/Flow.Launcher/Themes/BlurWhite.xaml
index e5f310c5a84..8bf1f06e2ac 100644
--- a/Flow.Launcher/Themes/BlurWhite.xaml
+++ b/Flow.Launcher/Themes/BlurWhite.xaml
@@ -12,7 +12,6 @@
True
Light
- DoNotRound
#BFFAFAFA
#BFFAFAFA
-
-
@@ -68,7 +141,7 @@
-
+
+
-
-
+
-
+
-
+
-
+
-
-
+
-
+
+
+
- #49443c
+ #36363d
-
+
-
+
@@ -149,7 +149,7 @@
x:Key="ClockPanel"
BasedOn="{StaticResource ClockPanel}"
TargetType="{x:Type StackPanel}">
-
+
-
-
+ TargetType="{x:Type Window}" />
+
+
- #545454
+ #2e436e
+ TargetType="{x:Type ScrollBar}" />
+
-
+
+
+ 8
+ 10 0 10 0
+ 0 0 0 10
+
-
-
\ No newline at end of file
+
From 3f0c142d3d7c9f672ede65d346496fd7f2342a20 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 11:56:44 +0800
Subject: [PATCH 0705/1335] Fix hide window startup issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2bfc9587c6e..192f8b48194 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -638,8 +638,13 @@ public void ChangeQueryText(string queryText, bool isReQuery = false)
///
private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false)
{
- await Application.Current.Dispatcher.InvokeAsync(async () =>
+ // Must check access so that we will not block the UI thread which cause window visibility issue
+ if (!Application.Current.Dispatcher.CheckAccess())
{
+ await Application.Current.Dispatcher.InvokeAsync(() => ChangeQueryText(queryText, isReQuery));
+ return;
+ }
+
BackToQueryResults();
if (QueryText != queryText)
@@ -656,7 +661,6 @@ await Application.Current.Dispatcher.InvokeAsync(async () =>
}
QueryTextCursorMovedToEnd = true;
- });
}
public bool LastQuerySelected { get; set; }
From 7d39c5259604cb7e83088f46b6959e2644db62cc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 12:00:23 +0800
Subject: [PATCH 0706/1335] Code quality
---
Flow.Launcher/MainWindow.xaml.cs | 62 ++++++++++++----
Flow.Launcher/ViewModel/MainViewModel.cs | 91 ++++++------------------
2 files changed, 70 insertions(+), 83 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 25d9c5d2dbe..89d4f0847e5 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -161,24 +161,67 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
{
if (_viewModel.MainWindowVisibilityStatus)
{
+ // Set clock and search icon opacity
+ var opacity = _settings.UseAnimation ? 0.0 : 1.0;
+ ClockPanel.Opacity = opacity;
+ SearchIcon.Opacity = opacity;
+
+ // Set clock and search icon visibility
+ ClockPanel.Visibility = string.IsNullOrEmpty(_viewModel.QueryText) ? Visibility.Visible : Visibility.Collapsed;
+ if (_viewModel.PluginIconSource != null)
+ {
+ SearchIcon.Opacity = 0.0;
+ }
+ else
+ {
+ _viewModel.SearchIconVisibility = Visibility.Visible;
+ }
+
+ // Play sound effect before activing the window
if (_settings.UseSound)
{
SoundPlay();
}
+ // Update position & Activate
UpdatePosition();
- _viewModel.ResetPreview();
Activate();
- QueryTextBox.Focus();
- _settings.ActivateTimes++;
+
+ // Reset preview
+ _viewModel.ResetPreview();
+
+ // Select last query if need
if (!_viewModel.LastQuerySelected)
{
QueryTextBox.SelectAll();
_viewModel.LastQuerySelected = true;
}
+ // Focus query box
+ QueryTextBox.Focus();
+
+ // Play window animation
if (_settings.UseAnimation)
+ {
WindowAnimation();
+ }
+
+ _settings.ActivateTimes++;
+ }
+ else
+ {
+ // Set clock and search icon opacity
+ var opacity = _settings.UseAnimation ? 0.0 : 1.0;
+ ClockPanel.Opacity = opacity;
+ SearchIcon.Opacity = opacity;
+
+ // Set clock and search icon visibility
+ ClockPanel.Visibility = Visibility.Hidden;
+ _viewModel.SearchIconVisibility = Visibility.Hidden;
+
+ // Force UI update
+ ClockPanel.UpdateLayout();
+ SearchIcon.UpdateLayout();
}
});
break;
@@ -191,7 +234,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
Dispatcher.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length);
_viewModel.QueryTextCursorMovedToEnd = false;
}
-
break;
case nameof(MainViewModel.GameModeStatus):
_notifyIcon.Icon = _viewModel.GameModeStatus
@@ -280,8 +322,8 @@ private async void OnDeactivated(object sender, EventArgs e)
_settings.WindowLeft = Left;
_settings.WindowTop = Top;
- ClockPanel.Opacity = 0;
- SearchIcon.Opacity = 0;
+ ClockPanel.Opacity = 0.0;
+ SearchIcon.Opacity = 0.0;
// This condition stops extra hide call when animator is on,
// which causes the toggling to occasional hide instead of show.
@@ -291,7 +333,9 @@ private async void OnDeactivated(object sender, EventArgs e)
// This also stops the mainwindow from flickering occasionally after Settings window is opened
// and always after Settings window is closed.
if (_settings.UseAnimation)
+ {
await Task.Delay(100);
+ }
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
{
@@ -765,12 +809,6 @@ private void WindowAnimation()
{
_isArrowKeyPressed = true;
- UpdatePosition();
-
- var opacity = _settings.UseAnimation ? 0.0 : 1.0;
- ClockPanel.Opacity = opacity;
- SearchIcon.Opacity = opacity;
-
var clocksb = new Storyboard();
var iconsb = new Storyboard();
var easing = new CircleEase { EasingMode = EasingMode.EaseInOut };
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 192f8b48194..9e63244f429 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -10,7 +10,6 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
-using System.Windows.Threading;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
@@ -645,22 +644,22 @@ private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false
return;
}
- BackToQueryResults();
+ BackToQueryResults();
- if (QueryText != queryText)
- {
- // re-query is done in QueryText's setter method
- QueryText = queryText;
- // set to false so the subsequent set true triggers
- // PropertyChanged and MoveQueryTextToEnd is called
- QueryTextCursorMovedToEnd = false;
- }
- else if (isReQuery)
- {
- await QueryAsync(isReQuery: true);
- }
+ if (QueryText != queryText)
+ {
+ // re-query is done in QueryText's setter method
+ QueryText = queryText;
+ // set to false so the subsequent set true triggers
+ // PropertyChanged and MoveQueryTextToEnd is called
+ QueryTextCursorMovedToEnd = false;
+ }
+ else if (isReQuery)
+ {
+ await QueryAsync(isReQuery: true);
+ }
- QueryTextCursorMovedToEnd = true;
+ QueryTextCursorMovedToEnd = true;
}
public bool LastQuerySelected { get; set; }
@@ -1448,43 +1447,10 @@ public bool ShouldIgnoreHotkeys()
#pragma warning disable VSTHRD100 // Avoid async void methods
- public async void Show()
+ public void Show()
{
- await Application.Current.Dispatcher.InvokeAsync(() =>
- {
- if (Application.Current.MainWindow is MainWindow mainWindow)
- {
- // 📌 Remove DWM Cloak (Make the window visible normally)
- Win32Helper.DWMSetCloakForWindow(mainWindow, false);
-
- // Clock and SearchIcon hide when show situation
- var opacity = Settings.UseAnimation ? 0.0 : 1.0;
- mainWindow.ClockPanel.Opacity = opacity;
- mainWindow.SearchIcon.Opacity = opacity;
-
- // QueryText sometimes is null when it is just initialized
- if (QueryText != null && QueryText.Length != 0)
- {
- mainWindow.ClockPanel.Visibility = Visibility.Collapsed;
- }
- else
- {
- mainWindow.ClockPanel.Visibility = Visibility.Visible;
- }
-
- if (PluginIconSource != null)
- {
- mainWindow.SearchIcon.Opacity = 0;
- }
- else
- {
- SearchIconVisibility = Visibility.Visible;
- }
-
- // 📌 Restore UI elements
- //mainWindow.SearchIcon.Visibility = Visibility.Visible;
- }
- }, DispatcherPriority.Render);
+ // 📌 Remove DWM Cloak (Make the window visible normally)
+ Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, false);
// Update WPF properties
MainWindowVisibility = Visibility.Visible;
@@ -1500,6 +1466,9 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
public async void Hide()
{
+ // 📌 Apply DWM Cloak (Completely hide the window)
+ Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, true);
+
lastHistoryIndex = 1;
if (ExternalPreviewVisible)
@@ -1534,26 +1503,6 @@ public async void Hide()
break;
}
- await Application.Current.Dispatcher.InvokeAsync(() =>
- {
- if (Application.Current.MainWindow is MainWindow mainWindow)
- {
- // 📌 Set Opacity of icon and clock to 0 and apply Visibility.Hidden
- var opacity = Settings.UseAnimation ? 0.0 : 1.0;
- mainWindow.ClockPanel.Opacity = opacity;
- mainWindow.SearchIcon.Opacity = opacity;
- mainWindow.ClockPanel.Visibility = Visibility.Hidden;
- SearchIconVisibility = Visibility.Hidden;
-
- // Force UI update
- mainWindow.ClockPanel.UpdateLayout();
- mainWindow.SearchIcon.UpdateLayout();
-
- // 📌 Apply DWM Cloak (Completely hide the window)
- Win32Helper.DWMSetCloakForWindow(mainWindow, true);
- }
- });
-
if (StartWithEnglishMode)
{
Win32Helper.RestorePreviousKeyboardLayout();
From de5803482c3509f11d5c911c1e888ee40fdbd848 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 12:33:07 +0800
Subject: [PATCH 0707/1335] Code quality
---
Flow.Launcher/MainWindow.xaml.cs | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 89d4f0847e5..a44b3a3050e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -101,11 +101,16 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
// Check first launch
if (_settings.FirstLaunch)
{
+ // Set First Launch to false
_settings.FirstLaunch = false;
+
+ // Set Backdrop Type to Acrylic for Windows 11 when First Launch. Default is None
+ if (Win32Helper.IsBackdropSupported()) _settings.BackdropType = BackdropTypes.Acrylic;
+
+ // Save settings
App.API.SaveAppAllSettings();
- /* Set Backdrop Type to Acrylic for Windows 11 when First Launch. Default is None. */
- if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000))
- _settings.BackdropType = BackdropTypes.Acrylic;
+
+ // Show Welcome Window
var WelcomeWindow = new WelcomeWindow();
WelcomeWindow.Show();
}
@@ -206,6 +211,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
WindowAnimation();
}
+ // Update activate times
_settings.ActivateTimes++;
}
else
From 589fefce3c307db30c0cf404ee0352f8a31f8f87 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 13:50:36 +0800
Subject: [PATCH 0708/1335] Adjust blank lines
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index a44b3a3050e..9eb1271ecbf 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -948,6 +948,7 @@ private void UpdateClockPanelVisibility()
ClockPanel.BeginAnimation(OpacityProperty, fadeOut);
}
+
// ✅ 4. When showing ClockPanel (apply fade-in animation)
else if (shouldShowClock && ClockPanel.Visibility != Visibility.Visible && !_isClockPanelAnimating)
{
@@ -971,7 +972,6 @@ private void UpdateClockPanelVisibility()
}
}
-
private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1.0)
{
if (style == null)
From 40d2d58406a62d2d66f1ec49c329cf2040b24306 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 14:31:46 +0800
Subject: [PATCH 0709/1335] Fix InvalidOperationException
---
Flow.Launcher/MainWindow.xaml.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 9eb1271ecbf..7b3814c874c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -296,7 +296,8 @@ private async void OnClosing(object sender, CancelEventArgs e)
Notification.Uninstall();
// After plugins are all disposed, we can close the main window
_canClose = true;
- Close();
+ // Use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event
+ Application.Current.Shutdown();
}
}
From b519313c25f8b74f8577c89f1a15d907bde961ba Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 14:32:03 +0800
Subject: [PATCH 0710/1335] Adjust log debug location
---
Flow.Launcher/App.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 833c63ddff8..1270d16bf21 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,13 +138,13 @@ private async void OnStartup(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
- Log.SetLogLevel(_settings.LogLevel);
-
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
+ Log.SetLogLevel(_settings.LogLevel);
+
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
From 8269304f4e48dc28bef83ef7a6d9568279bef214 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 14:45:52 +0800
Subject: [PATCH 0711/1335] Check disposed for result view update ending
---
Flow.Launcher/ViewModel/MainViewModel.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 9e63244f429..6bfde42c51a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -212,7 +212,8 @@ async Task UpdateActionAsync()
queue.Clear();
}
- Log.Error("MainViewModel", "Unexpected ResultViewUpdate ends");
+ if (!_disposed)
+ Log.Error("MainViewModel", "Unexpected ResultViewUpdate ends");
}
void continueAction(Task t)
From 91e2366c499cebae354f0aa3d0b62dbc3e4ad900 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 14:49:28 +0800
Subject: [PATCH 0712/1335] Revert "Adjust log debug location"
This reverts commit b519313c25f8b74f8577c89f1a15d907bde961ba.
---
Flow.Launcher/App.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 1270d16bf21..833c63ddff8 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,13 +138,13 @@ private async void OnStartup(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ Log.SetLogLevel(_settings.LogLevel);
+
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
- Log.SetLogLevel(_settings.LogLevel);
-
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
From 8a08e03cf95173b8c6c84166190832e5199b4118 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 15:52:31 +0800
Subject: [PATCH 0713/1335] Bind to vm
---
Flow.Launcher/MainWindow.xaml | 5 ++++-
Flow.Launcher/ViewModel/MainViewModel.cs | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 087b2e9985f..34b376cc9af 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -290,7 +290,9 @@
+ Opacity="{Binding ClockPanelOpacity}"
+ Style="{DynamicResource ClockPanel}"
+ Visibility="{Binding ClockPanelVisibility}">
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6bfde42c51a..1631ff7c3eb 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -760,7 +760,10 @@ private ResultsViewModel SelectedResults
public event VisibilityChangedEventHandler VisibilityChanged;
+ public Visibility ClockPanelVisibility { get; set; }
public Visibility SearchIconVisibility { get; set; }
+ public double ClockPanelOpacity { get; set; } = 1;
+ public double SearchIconOpacity { get; set; } = 1;
public double MainWindowWidth
{
From 693ba52fbc3e83775840e2f5591d88372b4dff4b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 16:13:02 +0800
Subject: [PATCH 0714/1335] Fix first-time window flicker & clock panel flicker
issue
---
Flow.Launcher/MainWindow.xaml.cs | 53 +++++------------------
Flow.Launcher/ViewModel/MainViewModel.cs | 55 +++++++++++++++++++++---
2 files changed, 61 insertions(+), 47 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 7b3814c874c..86b65386eed 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -166,22 +166,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
{
if (_viewModel.MainWindowVisibilityStatus)
{
- // Set clock and search icon opacity
- var opacity = _settings.UseAnimation ? 0.0 : 1.0;
- ClockPanel.Opacity = opacity;
- SearchIcon.Opacity = opacity;
-
- // Set clock and search icon visibility
- ClockPanel.Visibility = string.IsNullOrEmpty(_viewModel.QueryText) ? Visibility.Visible : Visibility.Collapsed;
- if (_viewModel.PluginIconSource != null)
- {
- SearchIcon.Opacity = 0.0;
- }
- else
- {
- _viewModel.SearchIconVisibility = Visibility.Visible;
- }
-
// Play sound effect before activing the window
if (_settings.UseSound)
{
@@ -214,21 +198,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
// Update activate times
_settings.ActivateTimes++;
}
- else
- {
- // Set clock and search icon opacity
- var opacity = _settings.UseAnimation ? 0.0 : 1.0;
- ClockPanel.Opacity = opacity;
- SearchIcon.Opacity = opacity;
-
- // Set clock and search icon visibility
- ClockPanel.Visibility = Visibility.Hidden;
- _viewModel.SearchIconVisibility = Visibility.Hidden;
-
- // Force UI update
- ClockPanel.UpdateLayout();
- SearchIcon.UpdateLayout();
- }
});
break;
}
@@ -329,8 +298,8 @@ private async void OnDeactivated(object sender, EventArgs e)
_settings.WindowLeft = Left;
_settings.WindowTop = Top;
- ClockPanel.Opacity = 0.0;
- SearchIcon.Opacity = 0.0;
+ _viewModel.ClockPanelOpacity = 0.0;
+ _viewModel.SearchIconOpacity = 0.0;
// This condition stops extra hide call when animator is on,
// which causes the toggling to occasional hide instead of show.
@@ -908,28 +877,28 @@ private void UpdateClockPanelVisibility()
var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
- bool shouldShowClock = QueryTextBox.Text.Length == 0 &&
+ var shouldShowClock = QueryTextBox.Text.Length == 0 &&
ContextMenu.Visibility != Visibility.Visible &&
History.Visibility != Visibility.Visible;
// ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation)
if (ContextMenu.Visibility == Visibility.Visible)
{
- ClockPanel.Visibility = Visibility.Hidden;
- ClockPanel.Opacity = 0.0; // Set to 0 in case Opacity animation affects it
+ _viewModel.ClockPanelVisibility = Visibility.Hidden;
+ _viewModel.ClockPanelOpacity = 0.0; // Set to 0 in case Opacity animation affects it
return;
}
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
{
- ClockPanel.Visibility = Visibility.Hidden;
- ClockPanel.Opacity = 0.0;
+ _viewModel.ClockPanelVisibility = Visibility.Hidden;
+ _viewModel.ClockPanelOpacity = 0.0;
return;
}
// ✅ 3. When hiding ClockPanel (apply fade-out animation)
- if ((!shouldShowClock) && ClockPanel.Visibility == Visibility.Visible && !_isClockPanelAnimating)
+ if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
{
_isClockPanelAnimating = true;
@@ -943,7 +912,7 @@ private void UpdateClockPanelVisibility()
fadeOut.Completed += (s, e) =>
{
- ClockPanel.Visibility = Visibility.Hidden; // ✅ Completely hide after animation
+ _viewModel.ClockPanelVisibility = Visibility.Hidden; // ✅ Completely hide after animation
_isClockPanelAnimating = false;
};
@@ -951,13 +920,13 @@ private void UpdateClockPanelVisibility()
}
// ✅ 4. When showing ClockPanel (apply fade-in animation)
- else if (shouldShowClock && ClockPanel.Visibility != Visibility.Visible && !_isClockPanelAnimating)
+ else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
{
_isClockPanelAnimating = true;
Application.Current.Dispatcher.Invoke(() =>
{
- ClockPanel.Visibility = Visibility.Visible; // ✅ Set Visibility to Visible first
+ _viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
var fadeIn = new DoubleAnimation
{
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 1631ff7c3eb..18ee2cb5b65 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -10,6 +10,7 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
+using System.Windows.Threading;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
@@ -1453,8 +1454,30 @@ public bool ShouldIgnoreHotkeys()
public void Show()
{
- // 📌 Remove DWM Cloak (Make the window visible normally)
- Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, false);
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ // 📌 Remove DWM Cloak (Make the window visible normally)
+ Win32Helper.DWMSetCloakForWindow(mainWindow, false);
+
+ // Set clock and search icon opacity
+ var opacity = Settings.UseAnimation ? 0.0 : 1.0;
+ ClockPanelOpacity = opacity;
+ SearchIconOpacity = opacity;
+
+ // Set clock and search icon visibility
+ ClockPanelVisibility = string.IsNullOrEmpty(QueryText) ? Visibility.Visible : Visibility.Collapsed;
+ if (PluginIconSource != null)
+ {
+ SearchIconOpacity = 0.0;
+ }
+ else
+ {
+ SearchIconVisibility = Visibility.Visible;
+ }
+ }
+ }, DispatcherPriority.Render);
// Update WPF properties
MainWindowVisibility = Visibility.Visible;
@@ -1470,9 +1493,6 @@ public void Show()
public async void Hide()
{
- // 📌 Apply DWM Cloak (Completely hide the window)
- Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, true);
-
lastHistoryIndex = 1;
if (ExternalPreviewVisible)
@@ -1507,11 +1527,36 @@ public async void Hide()
break;
}
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (Application.Current.MainWindow is MainWindow mainWindow)
+ {
+ // Set clock and search icon opacity
+ var opacity = Settings.UseAnimation ? 0.0 : 1.0;
+ ClockPanelOpacity = opacity;
+ SearchIconOpacity = opacity;
+
+ // Set clock and search icon visibility
+ ClockPanelVisibility = Visibility.Hidden;
+ SearchIconVisibility = Visibility.Hidden;
+
+ // Force UI update
+ mainWindow.ClockPanel.UpdateLayout();
+ mainWindow.SearchIcon.UpdateLayout();
+
+ // 📌 Apply DWM Cloak (Completely hide the window)
+ Win32Helper.DWMSetCloakForWindow(mainWindow, true);
+ }
+ }, DispatcherPriority.Render);
+
if (StartWithEnglishMode)
{
Win32Helper.RestorePreviousKeyboardLayout();
}
+ // Delay for a while to make sure clock will not flicker
+ await Task.Delay(50);
+
// Update WPF properties
//MainWindowOpacity = 0;
MainWindowVisibilityStatus = false;
From 82909cd9fa81e3f8855bfe8c0f5c1ddda390c756 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 21:39:25 +0800
Subject: [PATCH 0715/1335] Fix application null exception & Remove unused
MainWindowOpacity
---
Flow.Launcher/MainWindow.xaml | 1 -
Flow.Launcher/ViewModel/MainViewModel.cs | 15 +++++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 34b376cc9af..533819d1730 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -24,7 +24,6 @@
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
LocationChanged="OnLocationChanged"
- Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnKeyDown"
PreviewKeyUp="OnKeyUp"
PreviewMouseMove="OnPreviewMouseMove"
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 18ee2cb5b65..c69fc4484a2 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -753,8 +753,7 @@ private ResultsViewModel SelectedResults
public Visibility ProgressBarVisibility { get; set; }
public Visibility MainWindowVisibility { get; set; }
- public double MainWindowOpacity { get; set; } = 1;
-
+
// This is to be used for determining the visibility status of the mainwindow instead of MainWindowVisibility
// because it is more accurate and reliable representation than using Visibility as a condition check
public bool MainWindowVisibilityStatus { get; set; } = true;
@@ -1454,9 +1453,11 @@ public bool ShouldIgnoreHotkeys()
public void Show()
{
+ // Invoke on UI thread
Application.Current.Dispatcher.Invoke(() =>
{
- if (Application.Current.MainWindow is MainWindow mainWindow)
+ // When application is exitting, the Application.Current will be null
+ if (Application.Current?.MainWindow is MainWindow mainWindow)
{
// 📌 Remove DWM Cloak (Make the window visible normally)
Win32Helper.DWMSetCloakForWindow(mainWindow, false);
@@ -1481,10 +1482,10 @@ public void Show()
// Update WPF properties
MainWindowVisibility = Visibility.Visible;
- MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
+ // Switch keyboard layout
if (StartWithEnglishMode)
{
Win32Helper.SwitchToEnglishKeyboardLayout(true);
@@ -1527,9 +1528,11 @@ public async void Hide()
break;
}
+ // Invoke on UI thread
Application.Current.Dispatcher.Invoke(() =>
{
- if (Application.Current.MainWindow is MainWindow mainWindow)
+ // When application is exitting, the Application.Current will be null
+ if (Application.Current?.MainWindow is MainWindow mainWindow)
{
// Set clock and search icon opacity
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
@@ -1549,6 +1552,7 @@ public async void Hide()
}
}, DispatcherPriority.Render);
+ // Switch keyboard layout
if (StartWithEnglishMode)
{
Win32Helper.RestorePreviousKeyboardLayout();
@@ -1558,7 +1562,6 @@ public async void Hide()
await Task.Delay(50);
// Update WPF properties
- //MainWindowOpacity = 0;
MainWindowVisibilityStatus = false;
MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
From 494e947ccc4134bcf6709ae570ee5c61a7d9fb83 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 21:42:40 +0800
Subject: [PATCH 0716/1335] Code quality
---
Flow.Launcher/MainWindow.xaml.cs | 49 ++++++++++++++++++--------------
1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 86b65386eed..d8c05971ad1 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -241,7 +241,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
};
// QueryTextBox.Text change detection (modified to only work when character count is 1 or higher)
- QueryTextBox.TextChanged += (sender, e) => UpdateClockPanelVisibility();
+ QueryTextBox.TextChanged += (s, e) => UpdateClockPanelVisibility();
// Detecting ContextMenu.Visibility changes
DependencyPropertyDescriptor
@@ -351,7 +351,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
_viewModel.LoadContextMenuCommand.Execute(null);
e.Handled = true;
}
-
break;
case Key.Left:
if (!_viewModel.QueryResultsSelected() && QueryTextBox.CaretIndex == 0)
@@ -359,7 +358,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
_viewModel.EscCommand.Execute(null);
e.Handled = true;
}
-
break;
case Key.Back:
if (specialKeyState.CtrlPressed)
@@ -378,7 +376,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
}
}
}
-
break;
default:
break;
@@ -864,8 +861,11 @@ private void WindowAnimation()
private void UpdateClockPanelVisibility()
{
if (QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null)
+ {
return;
+ }
+ // ✅ Initialize animation length & duration
var animationLength = _settings.AnimationSpeed switch
{
AnimationSpeeds.Slow => 560,
@@ -873,7 +873,6 @@ private void UpdateClockPanelVisibility()
AnimationSpeeds.Fast => 160,
_ => _settings.CustomAnimationLength
};
-
var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
@@ -890,15 +889,21 @@ private void UpdateClockPanelVisibility()
}
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
- if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
+ else if (QueryTextBox.Text.Length > 0)
{
_viewModel.ClockPanelVisibility = Visibility.Hidden;
_viewModel.ClockPanelOpacity = 0.0;
return;
}
+ // ✅ Prevent multiple animations
+ if (_isClockPanelAnimating)
+ {
+ return;
+ }
+
// ✅ 3. When hiding ClockPanel (apply fade-out animation)
- if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
+ if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible)
{
_isClockPanelAnimating = true;
@@ -920,32 +925,32 @@ private void UpdateClockPanelVisibility()
}
// ✅ 4. When showing ClockPanel (apply fade-in animation)
- else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
+ else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible)
{
_isClockPanelAnimating = true;
- Application.Current.Dispatcher.Invoke(() =>
+ _viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
+
+ var fadeIn = new DoubleAnimation
{
- _viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
+ From = 0.0,
+ To = 1.0,
+ Duration = animationDuration,
+ FillBehavior = FillBehavior.HoldEnd
+ };
- var fadeIn = new DoubleAnimation
- {
- From = 0.0,
- To = 1.0,
- Duration = animationDuration,
- FillBehavior = FillBehavior.HoldEnd
- };
-
- fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
- ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
- }, DispatcherPriority.Render);
+ fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
+
+ ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
}
}
private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1.0)
{
if (style == null)
+ {
return defaultOpacity;
+ }
foreach (Setter setter in style.Setters.Cast())
{
@@ -961,7 +966,9 @@ private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1
private static Thickness GetThicknessFromStyle(Style style, Thickness defaultThickness)
{
if (style == null)
+ {
return defaultThickness;
+ }
foreach (Setter setter in style.Setters.Cast())
{
From c64e16d086366d712bb33f23485250c852934775 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 28 Mar 2025 21:46:23 +0800
Subject: [PATCH 0717/1335] Code quality
---
Flow.Launcher/MainWindow.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index d8c05971ad1..0fd802f1e13 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -111,8 +111,8 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
App.API.SaveAppAllSettings();
// Show Welcome Window
- var WelcomeWindow = new WelcomeWindow();
- WelcomeWindow.Show();
+ var welcomeWindow = new WelcomeWindow();
+ welcomeWindow.Show();
}
// Hide window if need
From 57bc886079fc213978445e32929cbc0fba3b0203 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 29 Mar 2025 00:45:46 +0900
Subject: [PATCH 0718/1335] - Add hotkey size baseon in blur themes - Add
hotkey colors and selected style
---
Flow.Launcher/Resources/Dark.xaml | 5 +++-
Flow.Launcher/Resources/Light.xaml | 3 +++
Flow.Launcher/ResultListBox.xaml | 1 +
Flow.Launcher/Themes/Base.xaml | 28 +++++++++++++++++-----
Flow.Launcher/Themes/BlurBlack Darker.xaml | 12 ++++++----
Flow.Launcher/Themes/BlurBlack.xaml | 12 ++++++----
Flow.Launcher/Themes/BlurWhite.xaml | 12 ++++++----
Flow.Launcher/Themes/Discord Dark.xaml | 12 ++++++----
Flow.Launcher/Themes/League.xaml | 20 +++++++++-------
Flow.Launcher/Themes/Nord Darker.xaml | 14 +++++++----
Flow.Launcher/Themes/Pink.xaml | 12 ++++++----
Flow.Launcher/Themes/Win11Light.xaml | 21 ++++++++++++----
12 files changed, 108 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml
index f1ebba080a2..ec089b378a6 100644
--- a/Flow.Launcher/Resources/Dark.xaml
+++ b/Flow.Launcher/Resources/Dark.xaml
@@ -58,6 +58,9 @@
+
+
+
@@ -115,7 +118,7 @@
-
+
diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml
index 12b35971d20..aa6da9fb22d 100644
--- a/Flow.Launcher/Resources/Light.xaml
+++ b/Flow.Launcher/Resources/Light.xaml
@@ -51,6 +51,9 @@
+
+
+
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index 67ba9e391cb..4c3bd1d120f 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -215,6 +215,7 @@
+
diff --git a/Flow.Launcher/Themes/Base.xaml b/Flow.Launcher/Themes/Base.xaml
index b292657e678..35d1f9a41e6 100644
--- a/Flow.Launcher/Themes/Base.xaml
+++ b/Flow.Launcher/Themes/Base.xaml
@@ -351,23 +351,41 @@
-
+
+
+
@@ -494,7 +512,6 @@
x:Key="ItemHotkeyStyle"
BasedOn="{StaticResource BaseItemHotkeyStyle}"
TargetType="{x:Type TextBlock}">
-
@@ -502,7 +519,6 @@
x:Key="ItemHotkeySelectedStyle"
BasedOn="{StaticResource BaseItemHotkeySelectedStyle}"
TargetType="{x:Type TextBlock}">
-
diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml
index 2bef1937381..143d036afa7 100644
--- a/Flow.Launcher/Themes/BlurBlack Darker.xaml
+++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml
@@ -145,13 +145,17 @@
-
-
diff --git a/Flow.Launcher/Themes/BlurBlack.xaml b/Flow.Launcher/Themes/BlurBlack.xaml
index c45827074e1..47e2b0720af 100644
--- a/Flow.Launcher/Themes/BlurBlack.xaml
+++ b/Flow.Launcher/Themes/BlurBlack.xaml
@@ -142,13 +142,17 @@
-
-
diff --git a/Flow.Launcher/Themes/BlurWhite.xaml b/Flow.Launcher/Themes/BlurWhite.xaml
index 8bf1f06e2ac..fdc3a9b4556 100644
--- a/Flow.Launcher/Themes/BlurWhite.xaml
+++ b/Flow.Launcher/Themes/BlurWhite.xaml
@@ -148,13 +148,17 @@
-
-
diff --git a/Flow.Launcher/Themes/Discord Dark.xaml b/Flow.Launcher/Themes/Discord Dark.xaml
index 46f2a91ec22..59f7adb493f 100644
--- a/Flow.Launcher/Themes/Discord Dark.xaml
+++ b/Flow.Launcher/Themes/Discord Dark.xaml
@@ -99,13 +99,17 @@
-
-
diff --git a/Flow.Launcher/Themes/League.xaml b/Flow.Launcher/Themes/League.xaml
index f1c8ba19222..b59d577f702 100644
--- a/Flow.Launcher/Themes/League.xaml
+++ b/Flow.Launcher/Themes/League.xaml
@@ -11,7 +11,7 @@
TargetType="{x:Type TextBox}">
-
+
@@ -57,7 +57,7 @@
TargetType="{x:Type Rectangle}">
-
+
-
-
F1 M12000,12000z M0,0z M10354,10962C10326,10951 10279,10927 10249,10907 10216,10886 9476,10153 8370,9046 7366,8042 6541,7220 6536,7220 6532,7220 6498,7242 6461,7268 6213,7447 5883,7619 5592,7721 5194,7860 4802,7919 4360,7906 3612,7886 2953,7647 2340,7174 2131,7013 1832,6699 1664,6465 1394,6088 1188,5618 1097,5170 1044,4909 1030,4764 1030,4470 1030,4130 1056,3914 1135,3609 1263,3110 1511,2633 1850,2235 1936,2134 2162,1911 2260,1829 2781,1395 3422,1120 4090,1045 4271,1025 4667,1025 4848,1045 5505,1120 6100,1368 6630,1789 6774,1903 7081,2215 7186,2355 7362,2588 7467,2759 7579,2990 7802,3455 7911,3937 7911,4460 7911,4854 7861,5165 7737,5542 7684,5702 7675,5724 7602,5885 7517,6071 7390,6292 7270,6460 7242,6499 7220,6533 7220,6538 7220,6542 8046,7371 9055,8380 10441,9766 10898,10229 10924,10274 10945,10308 10966,10364 10976,10408 10990,10472 10991,10493 10980,10554 10952,10717 10840,10865 10690,10937 10621,10971 10607,10974 10510,10977 10425,10980 10395,10977 10354,10962z M4685,7050C5214,7001 5694,6809 6100,6484 6209,6396 6396,6209 6484,6100 7151,5267 7246,4110 6721,3190 6369,2571 5798,2137 5100,1956 4706,1855 4222,1855 3830,1957 3448,2056 3140,2210 2838,2453 2337,2855 2010,3427 1908,4080 1877,4274 1877,4656 1908,4850 1948,5105 2028,5370 2133,5590 2459,6272 3077,6782 3810,6973 3967,7014 4085,7034 4290,7053 4371,7061 4583,7059 4685,7050z
@@ -141,7 +145,7 @@
x:Key="PreviewBorderStyle"
BasedOn="{StaticResource BasePreviewBorderStyle}"
TargetType="{x:Type Border}">
-
+
-
-
-
-
+
+
+
-
From b4c790e1ec9ee56bebd699a78ff9c12b14a3c338 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 29 Mar 2025 01:17:32 +0900
Subject: [PATCH 0720/1335] Add margin for classics
---
Flow.Launcher/Themes/BlurBlack Darker.xaml | 1 +
Flow.Launcher/Themes/BlurBlack.xaml | 1 +
Flow.Launcher/Themes/BlurWhite.xaml | 2 ++
3 files changed, 4 insertions(+)
diff --git a/Flow.Launcher/Themes/BlurBlack Darker.xaml b/Flow.Launcher/Themes/BlurBlack Darker.xaml
index 143d036afa7..b6864198443 100644
--- a/Flow.Launcher/Themes/BlurBlack Darker.xaml
+++ b/Flow.Launcher/Themes/BlurBlack Darker.xaml
@@ -15,6 +15,7 @@
Dark
#C7000000
#C7000000
+ 0 0 0 8
From f485e8605a14361bdd6417eba0b5bf2d6a92b0cc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 13:10:06 +0800
Subject: [PATCH 0724/1335] Support placeholder text
---
.../UserSettings/Settings.cs | 11 +++++
Flow.Launcher/Languages/en.xaml | 4 +-
Flow.Launcher/MainWindow.xaml | 8 ++++
Flow.Launcher/MainWindow.xaml.cs | 43 +++++++++++++++++++
.../ViewModels/SettingsPaneThemeViewModel.cs | 6 +++
.../SettingPages/Views/SettingsPaneTheme.xaml | 15 +++++--
6 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 63debfb474c..38c4fbe114d 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,6 +113,17 @@ public string Theme
public double? SettingWindowLeft { get; set; } = null;
public System.Windows.WindowState SettingWindowState { get; set; } = WindowState.Normal;
+ bool _showPlaceholder { get; set; } = true;
+ public bool ShowPlaceholder
+ {
+ get => _showPlaceholder;
+ set
+ {
+ _showPlaceholder = value;
+ OnPropertyChanged();
+ }
+ }
+
public int CustomExplorerIndex { get; set; } = 0;
[JsonIgnore]
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f0454b49633..f4e2d88afff 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -39,7 +39,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
- Reset search window position
+ Type here to search
Settings
@@ -202,6 +202,8 @@
Date
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Placeholder Text
+ Display placeholder text when query is empty
Hotkey
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 533819d1730..b9e355e2f99 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -218,6 +218,14 @@
+
Settings.SoundVolume = value;
}
+ public bool ShowPlaceholder
+ {
+ get => Settings.ShowPlaceholder;
+ set => Settings.ShowPlaceholder = value;
+ }
+
public bool UseClock
{
get => Settings.UseClock;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 6142371469d..5b92ee9b961 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -477,7 +477,6 @@
-
-
-
+
+
+
+
+
From a4dac91093960175e48aec20f9186f545ec7c228 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 13:25:00 +0800
Subject: [PATCH 0725/1335] Support resize window
---
.../UserSettings/Settings.cs | 13 ++++++++++++-
Flow.Launcher/Languages/en.xaml | 12 +++++++-----
Flow.Launcher/MainWindow.xaml.cs | 15 +++++++++++++++
.../ViewModels/SettingsPaneThemeViewModel.cs | 6 ++++++
.../SettingPages/Views/SettingsPaneTheme.xaml | 19 +++++++++++++++++--
5 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 38c4fbe114d..cae5d977f6e 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,7 +113,18 @@ public string Theme
public double? SettingWindowLeft { get; set; } = null;
public System.Windows.WindowState SettingWindowState { get; set; } = WindowState.Normal;
- bool _showPlaceholder { get; set; } = true;
+ bool _resizeWindow { get; set; } = true;
+ public bool ResizeWindow
+ {
+ get => _resizeWindow;
+ set
+ {
+ _resizeWindow = value;
+ OnPropertyChanged();
+ }
+ }
+
+ bool _showPlaceholder { get; set; } = false;
public bool ShowPlaceholder
{
get => _showPlaceholder;
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f4e2d88afff..656431e786d 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -104,11 +104,6 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
- Backdrop Type
- None
- Acrylic
- Mica
- Mica Alt
Search Plugin
@@ -200,10 +195,17 @@
Custom
Clock
Date
+ Backdrop Type
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
Placeholder Text
Display placeholder text when query is empty
+ Allow window size change
+ Allow dragging the search window edges to change its size
Hotkey
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 85eff3a576e..097ce7df4fa 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -115,6 +115,9 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
welcomeWindow.Show();
}
+ // Initialize resize mode
+ SetupResizeMode();
+
// Initialize place holder
SetupPlaceholderText();
@@ -243,6 +246,9 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
case nameof(Settings.ShowPlaceholder):
SetupPlaceholderText();
break;
+ case nameof(Settings.ResizeWindow):
+ SetupResizeMode();
+ break;
}
};
@@ -1071,6 +1077,15 @@ private void SetPlaceholderText()
#endregion
+ #region Resize Mode
+
+ private void SetupResizeMode()
+ {
+ ResizeMode = _settings.ResizeWindow ? ResizeMode.CanResize : ResizeMode.NoResize;
+ }
+
+ #endregion
+
#region IDisposable
protected virtual void Dispose(bool disposing)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 6e83d487a94..9c32e9bb94a 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -259,6 +259,12 @@ public double SoundEffectVolume
set => Settings.SoundVolume = value;
}
+ public bool ResizeWindow
+ {
+ get => Settings.ResizeWindow;
+ set => Settings.ResizeWindow = value;
+ }
+
public bool ShowPlaceholder
{
get => Settings.ShowPlaceholder;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 5b92ee9b961..3abf46f09ee 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -30,6 +30,7 @@
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.ScrollUnit="Pixel">
+
+
@@ -260,7 +262,8 @@
-
+
+
-
+
+
+
+
+
+
Date: Sat, 29 Mar 2025 14:15:24 +0800
Subject: [PATCH 0726/1335] Support change resize boarder thinkness
---
Flow.Launcher.Core/Resource/Theme.cs | 41 +++++++++++++++++++---------
Flow.Launcher/MainWindow.xaml.cs | 14 +++++++---
2 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 48900261730..44802aa916e 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -24,7 +24,7 @@ public class Theme
{
#region Properties & Fields
- public bool BlurEnabled { get; set; }
+ public bool BlurEnabled { get; private set; }
private const string ThemeMetadataNamePrefix = "Name:";
private const string ThemeMetadataIsDarkPrefix = "IsDark:";
@@ -42,6 +42,8 @@ public class Theme
private static string DirectoryPath => Path.Combine(Constant.ProgramDirectory, Folder);
private static string UserDirectoryPath => Path.Combine(DataLocation.DataDirectory(), Folder);
+ private Thickness _themeResizeBorderThickness;
+
#endregion
#region Constructor
@@ -463,7 +465,7 @@ public void AddDropShadowEffectToCurrentTheme()
var effectSetter = new Setter
{
- Property = Border.EffectProperty,
+ Property = UIElement.EffectProperty,
Value = new DropShadowEffect
{
Opacity = 0.3,
@@ -473,12 +475,12 @@ public void AddDropShadowEffectToCurrentTheme()
}
};
- if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) is not Setter marginSetter)
+ if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is not Setter marginSetter)
{
var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
marginSetter = new Setter()
{
- Property = Border.MarginProperty,
+ Property = FrameworkElement.MarginProperty,
Value = margin,
};
windowBorderStyle.Setters.Add(marginSetter);
@@ -508,12 +510,12 @@ public void RemoveDropShadowEffectFromCurrentTheme()
var dict = GetCurrentResourceDictionary();
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
- if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) is Setter effectSetter)
+ if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == UIElement.EffectProperty) is Setter effectSetter)
{
windowBorderStyle.Setters.Remove(effectSetter);
}
- if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) is Setter marginSetter)
+ if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is Setter marginSetter)
{
var currentMargin = (Thickness)marginSetter.Value;
var newMargin = new Thickness(
@@ -529,28 +531,41 @@ public void RemoveDropShadowEffectFromCurrentTheme()
UpdateResourceDictionary(dict);
}
+ public void SetResizeBoarderThickness(WindowChrome windowChrome, bool resizeWindow)
+ {
+ if (resizeWindow)
+ {
+ windowChrome.ResizeBorderThickness = _themeResizeBorderThickness;
+ }
+ else
+ {
+ windowChrome.ResizeBorderThickness = new Thickness(0);
+ }
+ }
+
// because adding drop shadow effect will change the margin of the window,
// we need to update the window chrome thickness to correct set the resize border
- private static void SetResizeBoarderThickness(Thickness? effectMargin)
+ private void SetResizeBoarderThickness(Thickness? effectMargin)
{
var window = Application.Current.MainWindow;
if (WindowChrome.GetWindowChrome(window) is WindowChrome windowChrome)
{
- Thickness thickness;
+ // Save the theme resize border thickness so that we can restore it if we change ResizeWindow setting
if (effectMargin == null)
{
- thickness = SystemParameters.WindowResizeBorderThickness;
+ _themeResizeBorderThickness = SystemParameters.WindowResizeBorderThickness;
}
else
{
- thickness = new Thickness(
+ _themeResizeBorderThickness = new Thickness(
effectMargin.Value.Left + SystemParameters.WindowResizeBorderThickness.Left,
effectMargin.Value.Top + SystemParameters.WindowResizeBorderThickness.Top,
effectMargin.Value.Right + SystemParameters.WindowResizeBorderThickness.Right,
effectMargin.Value.Bottom + SystemParameters.WindowResizeBorderThickness.Bottom);
}
- windowChrome.ResizeBorderThickness = thickness;
+ // Apply the resize border thickness to the window chrome
+ SetResizeBoarderThickness(windowChrome, _settings.ResizeWindow);
}
}
@@ -582,7 +597,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
{
AutoDropShadow(useDropShadowEffect);
}
- }, DispatcherPriority.Normal);
+ }, DispatcherPriority.Render);
}
///
@@ -596,7 +611,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
var (backdropType, _) = GetActualValue();
SetBlurForWindow(GetCurrentTheme(), backdropType);
- }, DispatcherPriority.Normal);
+ }, DispatcherPriority.Render);
}
///
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 097ce7df4fa..ce34aef1f74 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -11,6 +11,7 @@
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
+using System.Windows.Shell;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Plugin;
@@ -115,9 +116,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
welcomeWindow.Show();
}
- // Initialize resize mode
- SetupResizeMode();
-
// Initialize place holder
SetupPlaceholderText();
@@ -152,13 +150,17 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
UpdatePosition();
// Refresh frame
- await Ioc.Default.GetRequiredService().RefreshFrameAsync();
+ await _theme.RefreshFrameAsync();
+
+ // Initialize resize mode after refreshing frame
+ SetupResizeMode();
// Reset preview
_viewModel.ResetPreview();
// Since the default main window visibility is visible, so we need set focus during startup
QueryTextBox.Focus();
+
// Set the initial state of the QueryTextBoxCursorMovedToEnd property
// Without this part, when shown for the first time, switching the context menu does not move the cursor to the end.
_viewModel.QueryTextCursorMovedToEnd = false;
@@ -1082,6 +1084,10 @@ private void SetPlaceholderText()
private void SetupResizeMode()
{
ResizeMode = _settings.ResizeWindow ? ResizeMode.CanResize : ResizeMode.NoResize;
+ if (WindowChrome.GetWindowChrome(this) is WindowChrome windowChrome)
+ {
+ _theme.SetResizeBoarderThickness(windowChrome, _settings.ResizeWindow);
+ }
}
#endregion
From c74dd200886b809c709f63e13a83e52098b93b1f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 14:15:35 +0800
Subject: [PATCH 0727/1335] Remove ThemeManager.Instance
---
Flow.Launcher.Core/Resource/ThemeManager.cs | 12 ------------
Flow.Launcher/App.xaml.cs | 1 -
2 files changed, 13 deletions(-)
delete mode 100644 Flow.Launcher.Core/Resource/ThemeManager.cs
diff --git a/Flow.Launcher.Core/Resource/ThemeManager.cs b/Flow.Launcher.Core/Resource/ThemeManager.cs
deleted file mode 100644
index 3cbe8319ad3..00000000000
--- a/Flow.Launcher.Core/Resource/ThemeManager.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using CommunityToolkit.Mvvm.DependencyInjection;
-
-namespace Flow.Launcher.Core.Resource
-{
- [Obsolete("ThemeManager.Instance is obsolete. Use Ioc.Default.GetRequiredService() instead.")]
- public class ThemeManager
- {
- public static Theme Instance
- => Ioc.Default.GetRequiredService();
- }
-}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 833c63ddff8..7b1d113fbdc 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -177,7 +177,6 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
HotKeyMapper.Initialize();
// main windows needs initialized before theme change because of blur settings
- // TODO: Clean ThemeManager.Instance in future
Ioc.Default.GetRequiredService().ChangeTheme();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
From 84f2686710e937621ecdc7a864ad944fa4f89fe8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 15:08:49 +0800
Subject: [PATCH 0728/1335] Support placeholder size change
---
.../UserSettings/Settings.cs | 10 ++++++
Flow.Launcher/Languages/en.xaml | 6 ++--
Flow.Launcher/MainWindow.xaml | 2 +-
Flow.Launcher/MainWindow.xaml.cs | 4 +++
.../ViewModels/SettingsPaneThemeViewModel.cs | 6 ++++
.../SettingPages/Views/SettingsPaneTheme.xaml | 32 +++++++++++++------
Flow.Launcher/ViewModel/MainViewModel.cs | 18 +++++++++++
7 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index cae5d977f6e..7c747ae3626 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -134,6 +134,16 @@ public bool ShowPlaceholder
OnPropertyChanged();
}
}
+ string _placeholderText { get; set; } = string.Empty;
+ public string PlaceholderText
+ {
+ get => _placeholderText;
+ set
+ {
+ _placeholderText = value;
+ OnPropertyChanged();
+ }
+ }
public int CustomExplorerIndex { get; set; } = 0;
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 656431e786d..a9c5ab49fcc 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -202,8 +202,10 @@
Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
- Placeholder Text
- Display placeholder text when query is empty
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: Type here to search
Allow window size change
Allow dragging the search window edges to change its size
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index b9e355e2f99..82ac63b7da6 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -224,7 +224,7 @@
FontSize="{Binding QueryBoxFontSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="False"
Style="{DynamicResource QuerySuggestionBoxStyle}"
- Text="{DynamicResource queryTextBoxSuggestion}"
+ Text="{Binding PlaceholderText, Mode=OneWay}"
Visibility="Collapsed" />
Settings.ShowPlaceholder = value;
}
+ public string PlaceholderText
+ {
+ get => Settings.PlaceholderText;
+ set => Settings.PlaceholderText = value;
+ }
+
public bool UseClock
{
get => Settings.UseClock;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 3abf46f09ee..462ea799e8d 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -70,6 +70,7 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index c69fc4484a2..ec5b52c9dd0 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -765,6 +765,24 @@ private ResultsViewModel SelectedResults
public double ClockPanelOpacity { get; set; } = 1;
public double SearchIconOpacity { get; set; } = 1;
+ private string _placeholderText;
+ public string PlaceholderText
+ {
+ get => _placeholderText;
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ _placeholderText = App.API.GetTranslation("queryTextBoxSuggestion");
+ }
+ else
+ {
+ _placeholderText = value;
+ }
+ OnPropertyChanged();
+ }
+ }
+
public double MainWindowWidth
{
get => Settings.WindowSize;
From 91c5e84ca0f89d5ab0714ddcae86541c51b89778 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 15:27:25 +0800
Subject: [PATCH 0729/1335] Integrate resize window to fixed window height
---
Flow.Launcher.Core/Resource/Theme.cs | 10 ++--
.../UserSettings/Settings.cs | 56 +++++++++++--------
Flow.Launcher/Languages/en.xaml | 6 +-
Flow.Launcher/MainWindow.xaml.cs | 6 +-
.../ViewModels/SettingsPaneThemeViewModel.cs | 6 --
.../SettingPages/Views/SettingsPaneTheme.xaml | 22 +++-----
6 files changed, 51 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 44802aa916e..a1b2c3e0ed2 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -531,15 +531,15 @@ public void RemoveDropShadowEffectFromCurrentTheme()
UpdateResourceDictionary(dict);
}
- public void SetResizeBoarderThickness(WindowChrome windowChrome, bool resizeWindow)
+ public void SetResizeBoarderThickness(WindowChrome windowChrome, bool fixedWindowSize)
{
- if (resizeWindow)
+ if (fixedWindowSize)
{
- windowChrome.ResizeBorderThickness = _themeResizeBorderThickness;
+ windowChrome.ResizeBorderThickness = new Thickness(0);
}
else
{
- windowChrome.ResizeBorderThickness = new Thickness(0);
+ windowChrome.ResizeBorderThickness = _themeResizeBorderThickness;
}
}
@@ -565,7 +565,7 @@ private void SetResizeBoarderThickness(Thickness? effectMargin)
}
// Apply the resize border thickness to the window chrome
- SetResizeBoarderThickness(windowChrome, _settings.ResizeWindow);
+ SetResizeBoarderThickness(windowChrome, _settings.KeepMaxResults);
}
}
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 7c747ae3626..bd146f49a0b 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -68,11 +68,12 @@ public string Theme
get => _theme;
set
{
- if (value == _theme)
- return;
- _theme = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(MaxResultsToShow));
+ if (value != _theme)
+ {
+ _theme = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(MaxResultsToShow));
+ }
}
}
public bool UseDropShadowEffect { get; set; } = true;
@@ -113,25 +114,17 @@ public string Theme
public double? SettingWindowLeft { get; set; } = null;
public System.Windows.WindowState SettingWindowState { get; set; } = WindowState.Normal;
- bool _resizeWindow { get; set; } = true;
- public bool ResizeWindow
- {
- get => _resizeWindow;
- set
- {
- _resizeWindow = value;
- OnPropertyChanged();
- }
- }
-
bool _showPlaceholder { get; set; } = false;
public bool ShowPlaceholder
{
get => _showPlaceholder;
set
{
- _showPlaceholder = value;
- OnPropertyChanged();
+ if (_showPlaceholder != value)
+ {
+ _showPlaceholder = value;
+ OnPropertyChanged();
+ }
}
}
string _placeholderText { get; set; } = string.Empty;
@@ -140,8 +133,11 @@ public string PlaceholderText
get => _placeholderText;
set
{
- _placeholderText = value;
- OnPropertyChanged();
+ if (_placeholderText != value)
+ {
+ _placeholderText = value;
+ OnPropertyChanged();
+ }
}
}
@@ -273,10 +269,26 @@ public SearchPrecisionScore QuerySearchPrecision
///
public double CustomWindowTop { get; set; } = 0;
- public bool KeepMaxResults { get; set; } = false;
+ ///
+ /// Fixed window size
+ ///
+ private bool _keepMaxResults { get; set; } = false;
+ public bool KeepMaxResults
+ {
+ get => _keepMaxResults;
+ set
+ {
+ if (_keepMaxResults != value)
+ {
+ _keepMaxResults = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public int MaxResultsToShow { get; set; } = 5;
- public int ActivateTimes { get; set; }
+ public int ActivateTimes { get; set; }
public ObservableCollection CustomPluginHotkeys { get; set; } = new ObservableCollection();
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index a9c5ab49fcc..6d890dfba29 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -72,8 +72,6 @@
Empty last Query
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Maximum results shown
You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
Ignore hotkeys in fullscreen mode
@@ -206,8 +204,8 @@
Display placeholder when query is empty
Placeholder text
Change placeholder text. Input empty will use: Type here to search
- Allow window size change
- Allow dragging the search window edges to change its size
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Hotkey
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 6ffc010a6d1..3f0dcc3e190 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -252,7 +252,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
case nameof(Settings.PlaceholderText):
_viewModel.PlaceholderText = _settings.PlaceholderText;
break;
- case nameof(Settings.ResizeWindow):
+ case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
}
@@ -1087,10 +1087,10 @@ private void SetPlaceholderText()
private void SetupResizeMode()
{
- ResizeMode = _settings.ResizeWindow ? ResizeMode.CanResize : ResizeMode.NoResize;
+ ResizeMode = _settings.KeepMaxResults ? ResizeMode.NoResize : ResizeMode.CanResize;
if (WindowChrome.GetWindowChrome(this) is WindowChrome windowChrome)
{
- _theme.SetResizeBoarderThickness(windowChrome, _settings.ResizeWindow);
+ _theme.SetResizeBoarderThickness(windowChrome, _settings.KeepMaxResults);
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 64fe351fa91..099be496bb8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -259,12 +259,6 @@ public double SoundEffectVolume
set => Settings.SoundVolume = value;
}
- public bool ResizeWindow
- {
- get => Settings.ResizeWindow;
- set => Settings.ResizeWindow = value;
- }
-
public bool ShowPlaceholder
{
get => Settings.ShowPlaceholder;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 462ea799e8d..f9eef892437 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -499,28 +499,20 @@
Text="{DynamicResource browserMoreThemes}"
Uri="{Binding LinkThemeGallery}" />
-
-
-
-
-
-
+
-
+
Date: Sat, 29 Mar 2025 15:38:44 +0800
Subject: [PATCH 0730/1335] Code quality & Fix
---
Flow.Launcher/MainWindow.xaml | 2 +-
Flow.Launcher/MainWindow.xaml.cs | 25 ++++++++++++++++---------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 82ac63b7da6..2e6133df035 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -10,7 +10,7 @@
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
Name="FlowMainWindow"
Title="Flow Launcher"
- Width="{Binding MainWindowWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
+ Width="{Binding MainWindowWidth, Mode=OneWay}"
MinWidth="400"
MinHeight="30"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 3f0dcc3e190..5df1b318f39 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -455,23 +455,25 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
{
_initialWidth = (int)Width;
_initialHeight = (int)Height;
+
handled = true;
}
else if (msg == Win32Helper.WM_EXITSIZEMOVE)
{
if (_initialHeight != (int)Height)
{
- var shadowMargin = 0;
- var (_, useDropShadowEffect) = _theme.GetActualValue();
- if (useDropShadowEffect)
- {
- shadowMargin = 32;
- }
-
if (!_settings.KeepMaxResults)
{
- var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize;
+ // Get shadow margin
+ var shadowMargin = 0;
+ var (_, useDropShadowEffect) = _theme.GetActualValue();
+ if (useDropShadowEffect)
+ {
+ shadowMargin = 32;
+ }
+ // Calculate max results to show
+ var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize;
if (itemCount < 2)
{
_settings.MaxResultsToShow = 2;
@@ -483,11 +485,16 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
}
SizeToContent = SizeToContent.Height;
- _viewModel.MainWindowWidth = Width;
}
if (_initialWidth != (int)Width)
{
+ if (!_settings.KeepMaxResults)
+ {
+ // Update width
+ _viewModel.MainWindowWidth = Width;
+ }
+
SizeToContent = SizeToContent.Height;
}
From 6f32a6f098851cf3af741b394b6a91c17db0c67a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 15:48:52 +0800
Subject: [PATCH 0731/1335] Fix placeholder text issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index ec5b52c9dd0..a8425a456a1 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -768,17 +768,10 @@ private ResultsViewModel SelectedResults
private string _placeholderText;
public string PlaceholderText
{
- get => _placeholderText;
+ get => string.IsNullOrEmpty(_placeholderText) ? App.API.GetTranslation("queryTextBoxPlaceholder") : _placeholderText;
set
{
- if (string.IsNullOrEmpty(value))
- {
- _placeholderText = App.API.GetTranslation("queryTextBoxSuggestion");
- }
- else
- {
- _placeholderText = value;
- }
+ _placeholderText = value;
OnPropertyChanged();
}
}
From 78b661733d46353381af8fe25dd578a9dd7f8613 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 15:49:22 +0800
Subject: [PATCH 0732/1335] Improve placeholder text tooltip
---
Flow.Launcher/Languages/en.xaml | 4 ++--
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 5 +++++
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml | 4 ++--
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 6d890dfba29..c170c44e422 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -39,7 +39,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
- Type here to search
+ Type here to search
Settings
@@ -203,7 +203,7 @@
Show placeholder
Display placeholder when query is empty
Placeholder text
- Change placeholder text. Input empty will use: Type here to search
+ Change placeholder text. Input empty will use: {0}
Fixed Window Size
The window size is not adjustable by dragging.
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 099be496bb8..e35c978ede7 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -265,6 +265,11 @@ public bool ShowPlaceholder
set => Settings.ShowPlaceholder = value;
}
+ public string PlaceholderTextTip
+ {
+ get => string.Format(App.API.GetTranslation("PlaceholderTextTip"), App.API.GetTranslation("queryTextBoxPlaceholder"));
+ }
+
public string PlaceholderText
{
get => Settings.PlaceholderText;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index f9eef892437..5e1ba24ea96 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -549,9 +549,9 @@
+ Sub="{Binding PlaceholderTextTip}">
From 714860e416831cbdebdd7f636e3a9ecb13cae0a5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 16:03:41 +0800
Subject: [PATCH 0733/1335] Fix hotkey size change issue
---
Flow.Launcher/MainWindow.xaml | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml
index 2e6133df035..82ac63b7da6 100644
--- a/Flow.Launcher/MainWindow.xaml
+++ b/Flow.Launcher/MainWindow.xaml
@@ -10,7 +10,7 @@
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
Name="FlowMainWindow"
Title="Flow Launcher"
- Width="{Binding MainWindowWidth, Mode=OneWay}"
+ Width="{Binding MainWindowWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
MinWidth="400"
MinHeight="30"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index a8425a456a1..56de70b4785 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -584,7 +584,7 @@ public string QueryText
[RelayCommand]
private void IncreaseWidth()
{
- Settings.WindowSize += 100;
+ MainWindowWidth += 100;
Settings.WindowLeft -= 50;
OnPropertyChanged(nameof(MainWindowWidth));
}
@@ -592,14 +592,14 @@ private void IncreaseWidth()
[RelayCommand]
private void DecreaseWidth()
{
- if (MainWindowWidth - 100 < 400 || Settings.WindowSize == 400)
+ if (MainWindowWidth - 100 < 400 || MainWindowWidth == 400)
{
- Settings.WindowSize = 400;
+ MainWindowWidth = 400;
}
else
{
+ MainWindowWidth -= 100;
Settings.WindowLeft += 50;
- Settings.WindowSize -= 100;
}
OnPropertyChanged(nameof(MainWindowWidth));
From f160670d4f33068074f15a6301289ee78539fd11 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 29 Mar 2025 17:24:47 +0900
Subject: [PATCH 0734/1335] Remove QuerySuggestionBoxStyle background
---
Flow.Launcher/Themes/Discord Dark.xaml | 1 -
Flow.Launcher/Themes/League.xaml | 1 -
Flow.Launcher/Themes/Pink.xaml | 1 -
3 files changed, 3 deletions(-)
diff --git a/Flow.Launcher/Themes/Discord Dark.xaml b/Flow.Launcher/Themes/Discord Dark.xaml
index 9e39ee5bdaf..fb88da31353 100644
--- a/Flow.Launcher/Themes/Discord Dark.xaml
+++ b/Flow.Launcher/Themes/Discord Dark.xaml
@@ -28,7 +28,6 @@
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
diff --git a/Flow.Launcher/Themes/League.xaml b/Flow.Launcher/Themes/League.xaml
index f1c8ba19222..ffecf3fcbb4 100644
--- a/Flow.Launcher/Themes/League.xaml
+++ b/Flow.Launcher/Themes/League.xaml
@@ -24,7 +24,6 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
diff --git a/Flow.Launcher/Themes/Pink.xaml b/Flow.Launcher/Themes/Pink.xaml
index d7de4e2467d..5bbfa26d6e8 100644
--- a/Flow.Launcher/Themes/Pink.xaml
+++ b/Flow.Launcher/Themes/Pink.xaml
@@ -22,7 +22,6 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
From 356f229fd44e65f0975ca3f700df3e96b4a87a5c Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sat, 29 Mar 2025 16:38:54 +0800
Subject: [PATCH 0735/1335] Update Flow.Launcher.Core/Resource/Theme.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Core/Resource/Theme.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index a1b2c3e0ed2..a4cca2a1df6 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -531,7 +531,7 @@ public void RemoveDropShadowEffectFromCurrentTheme()
UpdateResourceDictionary(dict);
}
- public void SetResizeBoarderThickness(WindowChrome windowChrome, bool fixedWindowSize)
+ public void SetResizeBorderThickness(WindowChrome windowChrome, bool fixedWindowSize)
{
if (fixedWindowSize)
{
From cd01260ee91686e0ae2ca051c834bbe2a7c6e5f6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 16:41:11 +0800
Subject: [PATCH 0736/1335] Fix typos
---
Flow.Launcher.Core/Resource/Theme.cs | 2 +-
Flow.Launcher/MainWindow.xaml.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index a4cca2a1df6..e5980b62fa3 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -565,7 +565,7 @@ private void SetResizeBoarderThickness(Thickness? effectMargin)
}
// Apply the resize border thickness to the window chrome
- SetResizeBoarderThickness(windowChrome, _settings.KeepMaxResults);
+ SetResizeBorderThickness(windowChrome, _settings.KeepMaxResults);
}
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 5df1b318f39..8f22d64b8d6 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -1097,7 +1097,7 @@ private void SetupResizeMode()
ResizeMode = _settings.KeepMaxResults ? ResizeMode.NoResize : ResizeMode.CanResize;
if (WindowChrome.GetWindowChrome(this) is WindowChrome windowChrome)
{
- _theme.SetResizeBoarderThickness(windowChrome, _settings.KeepMaxResults);
+ _theme.SetResizeBorderThickness(windowChrome, _settings.KeepMaxResults);
}
}
From 9ac9ec849741194d48a964c7b3032bc174e2b923 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 29 Mar 2025 18:10:03 +0900
Subject: [PATCH 0737/1335] - Fix Preview in WelcomePage - Adjust BG Color -
Fix aspect ratio wallpaper bitmap
---
.../Helper/WallpaperPathRetrieval.cs | 99 ++++++++++++-------
.../Resources/Pages/WelcomePage1.xaml | 4 +-
.../Resources/Pages/WelcomePage2.xaml | 2 +-
.../Resources/Pages/WelcomePage5.xaml | 6 +-
4 files changed, 69 insertions(+), 42 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 151ce97dd83..47a77f398c6 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -13,7 +13,6 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
private static readonly int MAX_CACHE_SIZE = 3;
-
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
public static Brush GetWallpaperBrush()
@@ -27,46 +26,73 @@ public static Brush GetWallpaperBrush()
try
{
var wallpaperPath = Win32Helper.GetWallpaperPath();
- if (wallpaperPath is not null && File.Exists(wallpaperPath))
+ if (string.IsNullOrEmpty(wallpaperPath) || !File.Exists(wallpaperPath))
{
- // Since the wallpaper file name can be the same (TranscodedWallpaper),
- // we need to add the last modified date to differentiate them
- var dateModified = File.GetLastWriteTime(wallpaperPath);
- wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
- if (cachedWallpaper != null)
- {
- return cachedWallpaper;
- }
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Wallpaper path is invalid: {wallpaperPath}");
+ var wallpaperColor = GetWallpaperColor();
+ return new SolidColorBrush(wallpaperColor);
+ }
+
+ // Since the wallpaper file name can be the same (TranscodedWallpaper),
+ // we need to add the last modified date to differentiate them
+ var dateModified = File.GetLastWriteTime(wallpaperPath);
+ wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
+ if (cachedWallpaper != null)
+ {
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), "Using cached wallpaper");
+ return cachedWallpaper;
+ }
+
+ // We should not dispose the memory stream since the bitmap is still in use
+ var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
+ var bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ bitmap.StreamSource = memStream;
+ bitmap.EndInit();
+
+ if (bitmap.PixelWidth == 0 || bitmap.PixelHeight == 0)
+ {
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={bitmap.PixelWidth}, Height={bitmap.PixelHeight}");
+ return new SolidColorBrush(Colors.Transparent);
+ }
+
+ var originalWidth = bitmap.PixelWidth;
+ var originalHeight = bitmap.PixelHeight;
+
+ // Calculate the scaling factor to fit the image within 800x600 while preserving aspect ratio
+ double widthRatio = 800.0 / originalWidth;
+ double heightRatio = 600.0 / originalHeight;
+ double scaleFactor = Math.Min(widthRatio, heightRatio);
+
+ int decodedPixelWidth = (int)(originalWidth * scaleFactor);
+ int decodedPixelHeight = (int)(originalHeight * scaleFactor);
- // We should not dispose the memory stream since the bitmap is still in use
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.DecodePixelWidth = 800;
- bitmap.DecodePixelHeight = 600;
- bitmap.EndInit();
- bitmap.Freeze(); // Make the bitmap thread-safe
- var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
- wallpaperBrush.Freeze(); // Make the brush thread-safe
-
- // Manage cache size
- if (wallpaperCache.Count >= MAX_CACHE_SIZE)
+ // Set DecodePixelWidth and DecodePixelHeight to resize the image while preserving aspect ratio
+ bitmap = new BitmapImage();
+ bitmap.BeginInit();
+ memStream.Seek(0, SeekOrigin.Begin); // Reset stream position
+ bitmap.StreamSource = memStream;
+ bitmap.DecodePixelWidth = decodedPixelWidth;
+ bitmap.DecodePixelHeight = decodedPixelHeight;
+ bitmap.EndInit();
+ bitmap.Freeze(); // Make the bitmap thread-safe
+ var wallpaperBrush = new ImageBrush(bitmap) { Stretch = Stretch.UniformToFill };
+ wallpaperBrush.Freeze(); // Make the brush thread-safe
+
+ // Manage cache size
+ if (wallpaperCache.Count >= MAX_CACHE_SIZE)
+ {
+ // Remove the oldest wallpaper from the cache
+ var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
+ if (oldestCache != default)
{
- // Remove the oldest wallpaper from the cache
- var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
- if (oldestCache != default)
- {
- wallpaperCache.Remove(oldestCache);
- }
+ wallpaperCache.Remove(oldestCache);
}
-
- wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
- return wallpaperBrush;
}
- var wallpaperColor = GetWallpaperColor();
- return new SolidColorBrush(wallpaperColor);
+ wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ return wallpaperBrush;
+
}
catch (Exception ex)
{
@@ -86,8 +112,9 @@ private static Color GetWallpaperColor()
var parts = strResult.Trim().Split(new[] { ' ' }, 3).Select(byte.Parse).ToList();
return Color.FromRgb(parts[0], parts[1], parts[2]);
}
- catch
+ catch (Exception ex)
{
+ App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
index 1728195bde9..32fdb62fc71 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
@@ -110,8 +110,8 @@
-
-
+
+
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
index 04c76d0277f..f62cec3bf12 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml
@@ -60,7 +60,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
-
+
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
index c898ac9a02e..3df4b506ed2 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
@@ -58,10 +58,10 @@
-
+
-
-
+
+
From c685075436f904bc3142d8f7f211a123fcf762cb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 29 Mar 2025 21:01:30 +0800
Subject: [PATCH 0738/1335] Code quality & Lock & Bitmap memory & Registry
access improvement
---
.../Helper/WallpaperPathRetrieval.cs | 77 +++++++++----------
1 file changed, 38 insertions(+), 39 deletions(-)
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 47a77f398c6..77bebe2d37d 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -12,8 +12,9 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
- private static readonly int MAX_CACHE_SIZE = 3;
- private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
+ private const int MaxCacheSize = 3;
+ private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new();
+ private static readonly object CacheLock = new();
public static Brush GetWallpaperBrush()
{
@@ -36,42 +37,38 @@ public static Brush GetWallpaperBrush()
// Since the wallpaper file name can be the same (TranscodedWallpaper),
// we need to add the last modified date to differentiate them
var dateModified = File.GetLastWriteTime(wallpaperPath);
- wallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
- if (cachedWallpaper != null)
+ lock (CacheLock)
{
- App.API.LogInfo(nameof(WallpaperPathRetrieval), "Using cached wallpaper");
- return cachedWallpaper;
+ WallpaperCache.TryGetValue((wallpaperPath, dateModified), out var cachedWallpaper);
+ if (cachedWallpaper != null)
+ {
+ return cachedWallpaper;
+ }
}
-
- // We should not dispose the memory stream since the bitmap is still in use
- var memStream = new MemoryStream(File.ReadAllBytes(wallpaperPath));
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.StreamSource = memStream;
- bitmap.EndInit();
-
- if (bitmap.PixelWidth == 0 || bitmap.PixelHeight == 0)
+
+ using var fileStream = File.OpenRead(wallpaperPath);
+ var decoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
+ var frame = decoder.Frames[0];
+ var originalWidth = frame.PixelWidth;
+ var originalHeight = frame.PixelHeight;
+
+ if (originalWidth == 0 || originalHeight == 0)
{
- App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={bitmap.PixelWidth}, Height={bitmap.PixelHeight}");
+ App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}");
return new SolidColorBrush(Colors.Transparent);
}
- var originalWidth = bitmap.PixelWidth;
- var originalHeight = bitmap.PixelHeight;
-
// Calculate the scaling factor to fit the image within 800x600 while preserving aspect ratio
- double widthRatio = 800.0 / originalWidth;
- double heightRatio = 600.0 / originalHeight;
- double scaleFactor = Math.Min(widthRatio, heightRatio);
-
- int decodedPixelWidth = (int)(originalWidth * scaleFactor);
- int decodedPixelHeight = (int)(originalHeight * scaleFactor);
+ var widthRatio = 800.0 / originalWidth;
+ var heightRatio = 600.0 / originalHeight;
+ var scaleFactor = Math.Min(widthRatio, heightRatio);
+ var decodedPixelWidth = (int)(originalWidth * scaleFactor);
+ var decodedPixelHeight = (int)(originalHeight * scaleFactor);
// Set DecodePixelWidth and DecodePixelHeight to resize the image while preserving aspect ratio
- bitmap = new BitmapImage();
+ var bitmap = new BitmapImage();
bitmap.BeginInit();
- memStream.Seek(0, SeekOrigin.Begin); // Reset stream position
- bitmap.StreamSource = memStream;
+ bitmap.UriSource = new Uri(wallpaperPath);
bitmap.DecodePixelWidth = decodedPixelWidth;
bitmap.DecodePixelHeight = decodedPixelHeight;
bitmap.EndInit();
@@ -80,19 +77,21 @@ public static Brush GetWallpaperBrush()
wallpaperBrush.Freeze(); // Make the brush thread-safe
// Manage cache size
- if (wallpaperCache.Count >= MAX_CACHE_SIZE)
+ lock (CacheLock)
{
- // Remove the oldest wallpaper from the cache
- var oldestCache = wallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
- if (oldestCache != default)
+ if (WallpaperCache.Count >= MaxCacheSize)
{
- wallpaperCache.Remove(oldestCache);
+ // Remove the oldest wallpaper from the cache
+ var oldestCache = WallpaperCache.Keys.OrderBy(k => k.Item2).FirstOrDefault();
+ if (oldestCache != default)
+ {
+ WallpaperCache.Remove(oldestCache);
+ }
}
- }
-
- wallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
- return wallpaperBrush;
+ WallpaperCache.Add((wallpaperPath, dateModified), wallpaperBrush);
+ return wallpaperBrush;
+ }
}
catch (Exception ex)
{
@@ -103,7 +102,7 @@ public static Brush GetWallpaperBrush()
private static Color GetWallpaperColor()
{
- RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", true);
+ RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", false);
var result = key?.GetValue("Background", null);
if (result is string strResult)
{
@@ -114,7 +113,7 @@ private static Color GetWallpaperColor()
}
catch (Exception ex)
{
- App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
+ App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
}
}
From 9e11c9c01587ece56f04442a1d9b6393a729c1f8 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 29 Mar 2025 22:46:08 +0900
Subject: [PATCH 0739/1335] Adjust query padding
---
Flow.Launcher/Themes/Circle System.xaml | 4 ++--
Flow.Launcher/Themes/Cyan Dark.xaml | 4 ++--
Flow.Launcher/Themes/Darker Glass.xaml | 4 ++--
Flow.Launcher/Themes/Dracula.xaml | 4 ++--
Flow.Launcher/Themes/Midnight.xaml | 4 ++--
Flow.Launcher/Themes/SlimLight.xaml | 4 ++--
Flow.Launcher/Themes/Sublime.xaml | 4 ++--
Flow.Launcher/Themes/Ubuntu.xaml | 4 ++--
Flow.Launcher/Themes/Win10System.xaml | 4 ++--
9 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/Flow.Launcher/Themes/Circle System.xaml b/Flow.Launcher/Themes/Circle System.xaml
index 600b9e9dcef..24c7bd65bc8 100644
--- a/Flow.Launcher/Themes/Circle System.xaml
+++ b/Flow.Launcher/Themes/Circle System.xaml
@@ -26,7 +26,7 @@
x:Key="QueryBoxStyle"
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
@@ -36,7 +36,7 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
diff --git a/Flow.Launcher/Themes/Cyan Dark.xaml b/Flow.Launcher/Themes/Cyan Dark.xaml
index 5a9bc259568..59ebad0f63a 100644
--- a/Flow.Launcher/Themes/Cyan Dark.xaml
+++ b/Flow.Launcher/Themes/Cyan Dark.xaml
@@ -33,7 +33,7 @@
x:Key="QueryBoxStyle"
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
@@ -44,7 +44,7 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
diff --git a/Flow.Launcher/Themes/Darker Glass.xaml b/Flow.Launcher/Themes/Darker Glass.xaml
index 55f1dacc0f3..9ffaaf5660a 100644
--- a/Flow.Launcher/Themes/Darker Glass.xaml
+++ b/Flow.Launcher/Themes/Darker Glass.xaml
@@ -21,7 +21,7 @@
x:Key="QueryBoxStyle"
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
@@ -31,7 +31,7 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
-
+
diff --git a/Flow.Launcher/Themes/Dracula.xaml b/Flow.Launcher/Themes/Dracula.xaml
index eb8cc9557fb..6e3510f79b9 100644
--- a/Flow.Launcher/Themes/Dracula.xaml
+++ b/Flow.Launcher/Themes/Dracula.xaml
@@ -21,7 +21,7 @@
-
+
-
+
@@ -107,8 +107,8 @@
-
-
+
+
@@ -120,11 +120,11 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs b/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
new file mode 100644
index 00000000000..5889a1280df
--- /dev/null
+++ b/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
@@ -0,0 +1,55 @@
+using System.Linq;
+using System.Windows;
+using Flow.Launcher.Plugin;
+using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
+using static Flow.Launcher.SettingPages.ViewModels.SettingsPaneGeneralViewModel;
+
+namespace Flow.Launcher;
+
+public partial class SearchDelaySpeedWindow : Window
+{
+ private readonly PluginViewModel _pluginViewModel;
+
+ public SearchDelaySpeedWindow(PluginViewModel pluginViewModel)
+ {
+ InitializeComponent();
+ _pluginViewModel = pluginViewModel;
+ }
+
+ private void SearchDelaySpeed_OnLoaded(object sender, RoutedEventArgs e)
+ {
+ tbOldSearchDelaySpeed.Text = _pluginViewModel.SearchDelaySpeedText;
+ var searchDelaySpeeds = DropdownDataGeneric.GetValues("SearchDelaySpeed");
+ SearchDelaySpeedData selected = null;
+ // Because default value is SearchDelaySpeeds.Slow, we need to get selected value before adding default value
+ if (_pluginViewModel.PluginSearchDelay != null)
+ {
+ selected = searchDelaySpeeds.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelay);
+ }
+ // Add default value to the beginning of the list
+ // This value should be null
+ searchDelaySpeeds.Insert(0, new SearchDelaySpeedData { Display = App.API.GetTranslation(PluginViewModel.DefaultLocalizationKey), LocalizationKey = PluginViewModel.DefaultLocalizationKey });
+ selected ??= searchDelaySpeeds.FirstOrDefault();
+ tbDelay.ItemsSource = searchDelaySpeeds;
+ tbDelay.SelectedItem = selected;
+ tbDelay.Focus();
+ }
+
+ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void btnDone_OnClick(object sender, RoutedEventArgs _)
+ {
+ // Update search delay speed
+ var selected = tbDelay.SelectedItem as SearchDelaySpeedData;
+ SearchDelaySpeeds? changedValue = selected?.LocalizationKey != PluginViewModel.DefaultLocalizationKey ? selected.Value : null;
+ _pluginViewModel.PluginSearchDelay = changedValue;
+
+ // Update search delay speed text and close window
+ _pluginViewModel.OnSearchDelaySpeedChanged();
+ Close();
+ }
+}
diff --git a/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs b/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs
index 15a81443645..c8c119e94bf 100644
--- a/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -9,7 +8,7 @@ public class DropdownDataGeneric : BaseModel where TValue : Enum
{
public string Display { get; set; }
public TValue Value { get; private init; }
- private string LocalizationKey { get; init; }
+ public string LocalizationKey { get; set; }
public static List GetValues (string keyPrefix) where TR : DropdownDataGeneric, new()
{
@@ -19,7 +18,7 @@ public class DropdownDataGeneric : BaseModel where TValue : Enum
foreach (var value in enumValues)
{
var key = keyPrefix + value;
- var display = InternationalizationManager.Instance.GetTranslation(key);
+ var display = App.API.GetTranslation(key);
data.Add(new TR { Display = display, Value = value, LocalizationKey = key });
}
@@ -30,7 +29,7 @@ public static void UpdateLabels(List options) where TR : DropdownDataGen
{
foreach (var item in options)
{
- item.Display = InternationalizationManager.Instance.GetTranslation(item.LocalizationKey);
+ item.Display = App.API.GetTranslation(item.LocalizationKey);
}
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 4a729b578ca..90901157926 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -150,7 +150,7 @@ public bool PortableMode
public SearchDelaySpeedData SearchDelaySpeed
{
get => SearchDelaySpeeds.FirstOrDefault(x => x.Value == Settings.SearchDelaySpeed) ??
- SearchDelaySpeeds.FirstOrDefault(x => x.Value == Flow.Launcher.Plugin.SearchDelaySpeeds.Medium) ??
+ SearchDelaySpeeds.FirstOrDefault(x => x.Value == Plugin.SearchDelaySpeeds.Medium) ??
SearchDelaySpeeds.FirstOrDefault();
set
{
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index e633362351a..7ca77651227 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -13,6 +13,8 @@ namespace Flow.Launcher.ViewModel
{
public partial class PluginViewModel : BaseModel
{
+ public const string DefaultLocalizationKey = "default";
+
private readonly PluginPair _pluginPair;
public PluginPair PluginPair
{
@@ -127,7 +129,7 @@ public Control SettingControl
PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
public int Priority => PluginPair.Metadata.Priority;
- public string SearchDelaySpeedText => PluginPair.Metadata.SearchDelaySpeed == null ? App.API.GetTranslation("default") : App.API.GetTranslation($"SearchDelaySpeed{PluginPair.Metadata.SearchDelaySpeed}");
+ public string SearchDelaySpeedText => PluginPair.Metadata.SearchDelaySpeed == null ? App.API.GetTranslation(DefaultLocalizationKey) : App.API.GetTranslation($"SearchDelaySpeed{PluginPair.Metadata.SearchDelaySpeed}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public void OnActionKeywordsChanged()
@@ -135,6 +137,11 @@ public void OnActionKeywordsChanged()
OnPropertyChanged(nameof(ActionKeywordsText));
}
+ public void OnSearchDelaySpeedChanged()
+ {
+ OnPropertyChanged(nameof(SearchDelaySpeedText));
+ }
+
public void ChangePriority(int newPriority)
{
PluginPair.Metadata.Priority = newPriority;
@@ -180,8 +187,8 @@ private void SetActionKeywords()
[RelayCommand]
private void SetSearchDelaySpeed()
{
- /*var searchDelaySpeedWindow = new SearchDelaySpeedWindow(this);
- searchDelaySpeedWindow.ShowDialog();*/
+ var searchDelaySpeedWindow = new SearchDelaySpeedWindow(this);
+ searchDelaySpeedWindow.ShowDialog();
}
}
}
From e9c1cffd3304867f24d2cd2f2c609998c75755d3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 12:58:27 +0800
Subject: [PATCH 0767/1335] Code quality
---
.../UserSettings/Settings.cs | 24 +++----------------
1 file changed, 3 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index ab0a364d29c..fed4b667bc6 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -320,28 +320,10 @@ public bool HideNotifyIcon
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
- bool _searchQueryResultsWithDelay { get; set; }
- public bool SearchQueryResultsWithDelay
- {
- get => _searchQueryResultsWithDelay;
- set
- {
- _searchQueryResultsWithDelay = value;
- OnPropertyChanged();
- }
- }
-
- SearchDelaySpeeds searchDelaySpeed { get; set; } = SearchDelaySpeeds.Medium;
+ public bool SearchQueryResultsWithDelay { get; set; }
+
[JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelaySpeeds SearchDelaySpeed
- {
- get => searchDelaySpeed;
- set
- {
- searchDelaySpeed = value;
- OnPropertyChanged();
- }
- }
+ public SearchDelaySpeeds SearchDelaySpeed { get; set; } = SearchDelaySpeeds.Medium;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
From dec1e77b0ce7dd31aab99661b7505d3cf8bf2a7c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:04:41 +0800
Subject: [PATCH 0768/1335] Improve code comments
---
Flow.Launcher/SearchDelaySpeedWindow.xaml.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs b/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
index 5889a1280df..cfbde8be220 100644
--- a/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
@@ -28,7 +28,7 @@ private void SearchDelaySpeed_OnLoaded(object sender, RoutedEventArgs e)
selected = searchDelaySpeeds.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelay);
}
// Add default value to the beginning of the list
- // This value should be null
+ // When _pluginViewModel.PluginSearchDelay equals null, we will select this
searchDelaySpeeds.Insert(0, new SearchDelaySpeedData { Display = App.API.GetTranslation(PluginViewModel.DefaultLocalizationKey), LocalizationKey = PluginViewModel.DefaultLocalizationKey });
selected ??= searchDelaySpeeds.FirstOrDefault();
tbDelay.ItemsSource = searchDelaySpeeds;
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 309cd67bbb0..f4393119298 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -298,7 +298,7 @@ public void ReQuery()
{
if (QueryResultsSelected())
{
- // When we are requiring, we should not delay the query
+ // When we are re-querying, we should not delay the query
_ = QueryResultsAsync(false, isReQuery: true);
}
}
@@ -306,7 +306,7 @@ public void ReQuery()
public void ReQuery(bool reselect)
{
BackToQueryResults();
- // When we are requiring, we should not delay the query
+ // When we are re-querying, we should not delay the query
_ = QueryResultsAsync(false, isReQuery: true, reSelect: reselect);
}
@@ -660,7 +660,7 @@ private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false
}
else if (isReQuery)
{
- // When we are requiring, we should not delay the query
+ // When we are re-querying, we should not delay the query
await QueryAsync(false, isReQuery: true);
}
From c4cd51c3126db130864d40ce05898962526a6d70 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:26:09 +0800
Subject: [PATCH 0769/1335] Change to search delay time
---
.../UserSettings/PluginSettings.cs | 12 +++----
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Plugin/PluginMetadata.cs | 4 +--
Flow.Launcher.Plugin/SearchDelaySpeeds.cs | 32 -----------------
Flow.Launcher.Plugin/SearchDelayTime.cs | 32 +++++++++++++++++
Flow.Launcher/Languages/en.xaml | 26 +++++++-------
.../Controls/InstalledPluginSearchDelay.xaml | 8 ++---
Flow.Launcher/SearchDelaySpeedWindow.xaml | 16 ++++-----
Flow.Launcher/SearchDelaySpeedWindow.xaml.cs | 36 +++++++++----------
.../SettingsPaneGeneralViewModel.cs | 20 +++++------
.../Views/SettingsPaneGeneral.xaml | 8 ++---
Flow.Launcher/ViewModel/MainViewModel.cs | 13 ++++---
Flow.Launcher/ViewModel/PluginViewModel.cs | 22 ++++++------
.../plugin.json | 2 +-
14 files changed, 115 insertions(+), 118 deletions(-)
delete mode 100644 Flow.Launcher.Plugin/SearchDelaySpeeds.cs
create mode 100644 Flow.Launcher.Plugin/SearchDelayTime.cs
diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
index d1c047495b4..da92a358351 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -51,7 +51,7 @@ public void UpdatePluginSettings(List metadatas)
settings.Version = metadata.Version;
}
settings.DefaultActionKeywords = metadata.ActionKeywords; // metadata provides default values
- settings.DefaultSearchDelaySpeed = metadata.SearchDelaySpeed; // metadata provides default values
+ settings.DefaultSearchDelayTime = metadata.SearchDelayTime; // metadata provides default values
// update metadata values with settings
if (settings.ActionKeywords?.Count > 0)
@@ -66,7 +66,7 @@ public void UpdatePluginSettings(List metadatas)
}
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
- metadata.SearchDelaySpeed = settings.SearchDelaySpeed;
+ metadata.SearchDelayTime = settings.SearchDelayTime;
}
else
{
@@ -80,8 +80,8 @@ public void UpdatePluginSettings(List metadatas)
ActionKeywords = metadata.ActionKeywords, // use default value
Disabled = metadata.Disabled,
Priority = metadata.Priority,
- DefaultSearchDelaySpeed = metadata.SearchDelaySpeed, // metadata provides default values
- SearchDelaySpeed = metadata.SearchDelaySpeed, // use default value
+ DefaultSearchDelayTime = metadata.SearchDelayTime, // metadata provides default values
+ SearchDelayTime = metadata.SearchDelayTime, // use default value
};
}
}
@@ -120,10 +120,10 @@ public class Plugin
public int Priority { get; set; }
[JsonIgnore]
- public SearchDelaySpeeds? DefaultSearchDelaySpeed { get; set; }
+ public SearchDelayTime? DefaultSearchDelayTime { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelaySpeeds? SearchDelaySpeed { get; set; }
+ public SearchDelayTime? SearchDelayTime { get; set; }
///
/// Used only to save the state of the plugin in settings
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index fed4b667bc6..fcfbe8ca0d1 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -323,7 +323,7 @@ public bool HideNotifyIcon
public bool SearchQueryResultsWithDelay { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelaySpeeds SearchDelaySpeed { get; set; } = SearchDelaySpeeds.Medium;
+ public SearchDelayTime SearchDelayTime { get; set; } = SearchDelayTime.Medium;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
diff --git a/Flow.Launcher.Plugin/PluginMetadata.cs b/Flow.Launcher.Plugin/PluginMetadata.cs
index 42b623717be..1496765cea4 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -99,10 +99,10 @@ internal set
public bool HideActionKeywordPanel { get; set; }
///
- /// Plugin search delay speed. Null means use default search delay.
+ /// Plugin search delay time. Null means use default search delay time.
///
[JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelaySpeeds? SearchDelaySpeed { get; set; } = null;
+ public SearchDelayTime? SearchDelayTime { get; set; } = null;
///
/// Plugin icon path.
diff --git a/Flow.Launcher.Plugin/SearchDelaySpeeds.cs b/Flow.Launcher.Plugin/SearchDelaySpeeds.cs
deleted file mode 100644
index 543f8b3f6fb..00000000000
--- a/Flow.Launcher.Plugin/SearchDelaySpeeds.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace Flow.Launcher.Plugin;
-
-///
-/// Enum for search delay speeds
-///
-public enum SearchDelaySpeeds
-{
- ///
- /// Slow search delay speed. 50ms.
- ///
- Slow,
-
- ///
- /// Moderately slow search delay speed. 100ms.
- ///
- ModeratelySlow,
-
- ///
- /// Medium search delay speed. 150ms. Default value.
- ///
- Medium,
-
- ///
- /// Moderately fast search delay speed. 200ms.
- ///
- ModeratelyFast,
-
- ///
- /// Fast search delay speed. 250ms.
- ///
- Fast
-}
diff --git a/Flow.Launcher.Plugin/SearchDelayTime.cs b/Flow.Launcher.Plugin/SearchDelayTime.cs
new file mode 100644
index 00000000000..8dae5997e33
--- /dev/null
+++ b/Flow.Launcher.Plugin/SearchDelayTime.cs
@@ -0,0 +1,32 @@
+namespace Flow.Launcher.Plugin;
+
+///
+/// Enum for search delay time
+///
+public enum SearchDelayTime
+{
+ ///
+ /// Long search delay time. 250ms.
+ ///
+ Long,
+
+ ///
+ /// Moderately long search delay time. 200ms.
+ ///
+ ModeratelyLong,
+
+ ///
+ /// Medium search delay time. 150ms. Default value.
+ ///
+ Medium,
+
+ ///
+ /// Moderately short search delay time. 100ms.
+ ///
+ ModeratelyShort,
+
+ ///
+ /// Short search delay time. 50ms.
+ ///
+ Short
+}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index ae930db7064..e6a764d4815 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -104,13 +104,13 @@
Shadow effect is not allowed while current theme has blur effect enabled
Search Delay
Delay for a while to search when typing. This reduces interface jumpiness and result load.
- Default Search Delay Speed
- Plugins default delay time after which search results appear when typing is stopped. Default is medium.
- Slow
- Moderately slow
- Medium
- Moderately fast
- Fast
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped. Default is "Medium".
+ Long
+ Moderately long
+ Medium
+ Moderately short
+ Short
Search Plugin
@@ -127,8 +127,8 @@
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay speed
- Change Plugin Seach Delay Speed
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Current Priority
New Priority
Priority
@@ -366,10 +366,10 @@
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
- Search Delay Speed Setting
- Select the search delay speed you like to use for the plugin. Select Default if you don't want to specify any, and the plugin will use default search delay speed.
- Current search delay speed
- New search delay speed
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Custom Query Hotkey
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
index bd2f9a7c9b2..0fd98bfac42 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
@@ -32,18 +32,18 @@
VerticalAlignment="Center"
DockPanel.Dock="Left"
Style="{DynamicResource SettingTitleLabel}"
- Text="{DynamicResource pluginSearchDelaySpeed}" />
+ Text="{DynamicResource pluginSearchDelayTime}" />
+ ToolTip="{DynamicResource pluginSearchDelayTimeTooltip}" />
diff --git a/Flow.Launcher/SearchDelaySpeedWindow.xaml b/Flow.Launcher/SearchDelaySpeedWindow.xaml
index 1813ff6abdf..21ecd39c0ea 100644
--- a/Flow.Launcher/SearchDelaySpeedWindow.xaml
+++ b/Flow.Launcher/SearchDelaySpeedWindow.xaml
@@ -1,13 +1,13 @@
@@ -60,13 +60,13 @@
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
- Text="{DynamicResource searchDelaySpeedTitle}"
+ Text="{DynamicResource searchDelayTimeTitle}"
TextAlignment="Left" />
@@ -78,9 +78,9 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
- Text="{DynamicResource currentSearchDelaySpeed}" />
+ Text="{DynamicResource currentSearchDelayTime}" />
+ Text="{DynamicResource newSearchDelayTime}" />
.GetValues("SearchDelaySpeed");
- SearchDelaySpeedData selected = null;
- // Because default value is SearchDelaySpeeds.Slow, we need to get selected value before adding default value
- if (_pluginViewModel.PluginSearchDelay != null)
+ tbOldSearchDelayTime.Text = _pluginViewModel.SearchDelayTimeText;
+ var searchDelayTimes = DropdownDataGeneric.GetValues("SearchDelayTime");
+ SearchDelayTimeData selected = null;
+ // Because default value is SearchDelayTime.Slow, we need to get selected value before adding default value
+ if (_pluginViewModel.PluginSearchDelayTime != null)
{
- selected = searchDelaySpeeds.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelay);
+ selected = searchDelayTimes.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelayTime);
}
// Add default value to the beginning of the list
// When _pluginViewModel.PluginSearchDelay equals null, we will select this
- searchDelaySpeeds.Insert(0, new SearchDelaySpeedData { Display = App.API.GetTranslation(PluginViewModel.DefaultLocalizationKey), LocalizationKey = PluginViewModel.DefaultLocalizationKey });
- selected ??= searchDelaySpeeds.FirstOrDefault();
- tbDelay.ItemsSource = searchDelaySpeeds;
+ searchDelayTimes.Insert(0, new SearchDelayTimeData { Display = App.API.GetTranslation("default"), LocalizationKey = "default" });
+ selected ??= searchDelayTimes.FirstOrDefault();
+ tbDelay.ItemsSource = searchDelayTimes;
tbDelay.SelectedItem = selected;
tbDelay.Focus();
}
@@ -43,13 +43,13 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
- // Update search delay speed
- var selected = tbDelay.SelectedItem as SearchDelaySpeedData;
- SearchDelaySpeeds? changedValue = selected?.LocalizationKey != PluginViewModel.DefaultLocalizationKey ? selected.Value : null;
- _pluginViewModel.PluginSearchDelay = changedValue;
+ // Update search delay time
+ var selected = tbDelay.SelectedItem as SearchDelayTimeData;
+ SearchDelayTime? changedValue = selected?.LocalizationKey != "default" ? selected.Value : null;
+ _pluginViewModel.PluginSearchDelayTime = changedValue;
- // Update search delay speed text and close window
- _pluginViewModel.OnSearchDelaySpeedChanged();
+ // Update search delay time text and close window
+ _pluginViewModel.OnSearchDelayTimeChanged();
Close();
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 90901157926..3262ad2084c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -31,7 +31,7 @@ public class SearchWindowScreenData : DropdownDataGeneric {
public class SearchWindowAlignData : DropdownDataGeneric { }
public class SearchPrecisionData : DropdownDataGeneric { }
public class LastQueryModeData : DropdownDataGeneric { }
- public class SearchDelaySpeedData : DropdownDataGeneric { }
+ public class SearchDelayTimeData : DropdownDataGeneric { }
public bool StartFlowLauncherOnSystemStartup
{
@@ -144,22 +144,22 @@ public bool PortableMode
public List LastQueryModes { get; } =
DropdownDataGeneric.GetValues("LastQuery");
- public List SearchDelaySpeeds { get; } =
- DropdownDataGeneric.GetValues("SearchDelaySpeed");
+ public List SearchDelayTimes { get; } =
+ DropdownDataGeneric.GetValues("SearchDelayTime");
- public SearchDelaySpeedData SearchDelaySpeed
+ public SearchDelayTimeData SearchDelayTime
{
- get => SearchDelaySpeeds.FirstOrDefault(x => x.Value == Settings.SearchDelaySpeed) ??
- SearchDelaySpeeds.FirstOrDefault(x => x.Value == Plugin.SearchDelaySpeeds.Medium) ??
- SearchDelaySpeeds.FirstOrDefault();
+ get => SearchDelayTimes.FirstOrDefault(x => x.Value == Settings.SearchDelayTime) ??
+ SearchDelayTimes.FirstOrDefault(x => x.Value == Plugin.SearchDelayTime.Medium) ??
+ SearchDelayTimes.FirstOrDefault();
set
{
if (value == null)
return;
- if (Settings.SearchDelaySpeed != value.Value)
+ if (Settings.SearchDelayTime != value.Value)
{
- Settings.SearchDelaySpeed = value.Value;
+ Settings.SearchDelayTime = value.Value;
}
}
}
@@ -170,7 +170,7 @@ private void UpdateEnumDropdownLocalizations()
DropdownDataGeneric.UpdateLabels(SearchWindowAligns);
DropdownDataGeneric.UpdateLabels(SearchPrecisionScores);
DropdownDataGeneric.UpdateLabels(LastQueryModes);
- DropdownDataGeneric.UpdateLabels(SearchDelaySpeeds);
+ DropdownDataGeneric.UpdateLabels(SearchDelayTimes);
}
public string Language
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 372fdccd707..2b198474ba8 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -184,14 +184,14 @@
+ Sub="{DynamicResource searchDelayTimeToolTip}">
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f4393119298..283e26b9532 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1271,14 +1271,13 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
if (searchDelay)
{
- var searchDelaySpeed = plugin.Metadata.SearchDelaySpeed ?? Settings.SearchDelaySpeed;
- var searchDelayTime = searchDelaySpeed switch
+ var searchDelayTime = (plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime) switch
{
- SearchDelaySpeeds.Slow => 250,
- SearchDelaySpeeds.ModeratelySlow => 200,
- SearchDelaySpeeds.Medium => 150,
- SearchDelaySpeeds.ModeratelyFast => 100,
- SearchDelaySpeeds.Fast => 50,
+ SearchDelayTime.Long => 250,
+ SearchDelayTime.ModeratelyLong => 200,
+ SearchDelayTime.Medium => 150,
+ SearchDelayTime.ModeratelyShort => 100,
+ SearchDelayTime.Short => 50,
_ => 150
};
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 7ca77651227..76e212c1db1 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -13,8 +13,6 @@ namespace Flow.Launcher.ViewModel
{
public partial class PluginViewModel : BaseModel
{
- public const string DefaultLocalizationKey = "default";
-
private readonly PluginPair _pluginPair;
public PluginPair PluginPair
{
@@ -85,13 +83,13 @@ public bool IsExpanded
}
}
- public SearchDelaySpeeds? PluginSearchDelay
+ public SearchDelayTime? PluginSearchDelayTime
{
- get => PluginPair.Metadata.SearchDelaySpeed;
+ get => PluginPair.Metadata.SearchDelayTime;
set
{
- PluginPair.Metadata.SearchDelaySpeed = value;
- PluginSettingsObject.SearchDelaySpeed = value;
+ PluginPair.Metadata.SearchDelayTime = value;
+ PluginSettingsObject.SearchDelayTime = value;
}
}
@@ -129,7 +127,7 @@ public Control SettingControl
PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
public int Priority => PluginPair.Metadata.Priority;
- public string SearchDelaySpeedText => PluginPair.Metadata.SearchDelaySpeed == null ? App.API.GetTranslation(DefaultLocalizationKey) : App.API.GetTranslation($"SearchDelaySpeed{PluginPair.Metadata.SearchDelaySpeed}");
+ public string SearchDelayTimeText => PluginPair.Metadata.SearchDelayTime == null ? App.API.GetTranslation("default") : App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public void OnActionKeywordsChanged()
@@ -137,9 +135,9 @@ public void OnActionKeywordsChanged()
OnPropertyChanged(nameof(ActionKeywordsText));
}
- public void OnSearchDelaySpeedChanged()
+ public void OnSearchDelayTimeChanged()
{
- OnPropertyChanged(nameof(SearchDelaySpeedText));
+ OnPropertyChanged(nameof(SearchDelayTimeText));
}
public void ChangePriority(int newPriority)
@@ -185,10 +183,10 @@ private void SetActionKeywords()
}
[RelayCommand]
- private void SetSearchDelaySpeed()
+ private void SetSearchDelayTime()
{
- var searchDelaySpeedWindow = new SearchDelaySpeedWindow(this);
- searchDelaySpeedWindow.ShowDialog();
+ var searchDelayTimeWindow = new SearchDelayTimeWindow(this);
+ searchDelayTimeWindow.ShowDialog();
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index f815900921e..e274261334a 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -32,5 +32,5 @@
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
"IcoPath": "Images\\web_search.png",
- "SearchDelaySpeed": "Slow"
+ "SearchDelayTime": "Long"
}
From 72a59ba6c50ab740866204cd780e88a676f37b0f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:27:21 +0800
Subject: [PATCH 0770/1335] Change file names
---
.../{SearchDelaySpeedWindow.xaml => SearchDelayTimeWindow.xaml} | 0
...archDelaySpeedWindow.xaml.cs => SearchDelayTimeWindow.xaml.cs} | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename Flow.Launcher/{SearchDelaySpeedWindow.xaml => SearchDelayTimeWindow.xaml} (100%)
rename Flow.Launcher/{SearchDelaySpeedWindow.xaml.cs => SearchDelayTimeWindow.xaml.cs} (100%)
diff --git a/Flow.Launcher/SearchDelaySpeedWindow.xaml b/Flow.Launcher/SearchDelayTimeWindow.xaml
similarity index 100%
rename from Flow.Launcher/SearchDelaySpeedWindow.xaml
rename to Flow.Launcher/SearchDelayTimeWindow.xaml
diff --git a/Flow.Launcher/SearchDelaySpeedWindow.xaml.cs b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
similarity index 100%
rename from Flow.Launcher/SearchDelaySpeedWindow.xaml.cs
rename to Flow.Launcher/SearchDelayTimeWindow.xaml.cs
From 5243d74eaf3152e4bb44938428ec22ea25a266d5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:31:16 +0800
Subject: [PATCH 0771/1335] Improve code comments
---
Flow.Launcher/SearchDelayTimeWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
index 8bde5eb33d8..1372e099380 100644
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
@@ -28,7 +28,7 @@ private void SearchDelayTimeWindow_OnLoaded(object sender, RoutedEventArgs e)
selected = searchDelayTimes.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelayTime);
}
// Add default value to the beginning of the list
- // When _pluginViewModel.PluginSearchDelay equals null, we will select this
+ // When _pluginViewModel.PluginSearchDelayTime equals null, we will select this
searchDelayTimes.Insert(0, new SearchDelayTimeData { Display = App.API.GetTranslation("default"), LocalizationKey = "default" });
selected ??= searchDelayTimes.FirstOrDefault();
tbDelay.ItemsSource = searchDelayTimes;
From b860bb2edddcf5aa5db585435a34da3dc8b5dbf8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:31:56 +0800
Subject: [PATCH 0772/1335] Code quality
---
Flow.Launcher/ViewModel/PluginViewModel.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 76e212c1db1..807fd6e8567 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -105,7 +105,8 @@ public SearchDelayTime? PluginSearchDelayTime
private Control _bottomPart3;
public Control BottomPart3 => IsExpanded ? _bottomPart3 ??= new InstalledPluginDisplayBottomData() : null;
- public bool HasSettingControl => PluginPair.Plugin is ISettingProvider && (PluginPair.Plugin is not JsonRPCPluginBase jsonRPCPluginBase || jsonRPCPluginBase.NeedCreateSettingPanel());
+ public bool HasSettingControl => PluginPair.Plugin is ISettingProvider &&
+ (PluginPair.Plugin is not JsonRPCPluginBase jsonRPCPluginBase || jsonRPCPluginBase.NeedCreateSettingPanel());
public Control SettingControl
=> IsExpanded
? _settingControl
@@ -127,7 +128,9 @@ public Control SettingControl
PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
public int Priority => PluginPair.Metadata.Priority;
- public string SearchDelayTimeText => PluginPair.Metadata.SearchDelayTime == null ? App.API.GetTranslation("default") : App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
+ public string SearchDelayTimeText => PluginPair.Metadata.SearchDelayTime == null ?
+ App.API.GetTranslation("default") :
+ App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public void OnActionKeywordsChanged()
From d42279bd8f754651c82bb80afe78725ed3bc2e26 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 13:41:14 +0800
Subject: [PATCH 0773/1335] Fix typo & Fix tip issue
---
Flow.Launcher/SearchDelayTimeWindow.xaml | 4 ++--
Flow.Launcher/SearchDelayTimeWindow.xaml.cs | 10 ++++++----
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/SearchDelayTimeWindow.xaml b/Flow.Launcher/SearchDelayTimeWindow.xaml
index 21ecd39c0ea..1c7ca58d0a0 100644
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml
+++ b/Flow.Launcher/SearchDelayTimeWindow.xaml
@@ -65,8 +65,8 @@
@@ -99,7 +99,7 @@
FontSize="14"
Text="{DynamicResource newSearchDelayTime}" />
.GetValues("SearchDelayTime");
SearchDelayTimeData selected = null;
@@ -31,9 +33,9 @@ private void SearchDelayTimeWindow_OnLoaded(object sender, RoutedEventArgs e)
// When _pluginViewModel.PluginSearchDelayTime equals null, we will select this
searchDelayTimes.Insert(0, new SearchDelayTimeData { Display = App.API.GetTranslation("default"), LocalizationKey = "default" });
selected ??= searchDelayTimes.FirstOrDefault();
- tbDelay.ItemsSource = searchDelayTimes;
- tbDelay.SelectedItem = selected;
- tbDelay.Focus();
+ cbDelay.ItemsSource = searchDelayTimes;
+ cbDelay.SelectedItem = selected;
+ cbDelay.Focus();
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
@@ -44,7 +46,7 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
// Update search delay time
- var selected = tbDelay.SelectedItem as SearchDelayTimeData;
+ var selected = cbDelay.SelectedItem as SearchDelayTimeData;
SearchDelayTime? changedValue = selected?.LocalizationKey != "default" ? selected.Value : null;
_pluginViewModel.PluginSearchDelayTime = changedValue;
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 807fd6e8567..e91badb3894 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -118,7 +118,7 @@ public Control SettingControl
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.HideActionKeywordPanel ?
Visibility.Collapsed : Visibility.Visible;
- public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
+ public string InitializeTime => PluginPair.Metadata.InitTime + "ms";
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
public string Version => App.API.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
public string InitAndQueryTime =>
From 6b6aaa14f4302567b1bf2a858e96aaef69df4588 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 31 Mar 2025 17:08:26 +0900
Subject: [PATCH 0774/1335] Add subtext indicating whether backdrop is not
available
---
Flow.Launcher/Languages/en.xaml | 1 +
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 1 +
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml | 4 ++--
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 7c96fe88dfb..44b82b3725c 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -196,6 +196,7 @@
Clock
Date
Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 53d70e8d5cd..6e2488fe1d1 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -21,6 +21,7 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneThemeViewModel : BaseModel
{
private const string DefaultFont = "Segoe UI";
+ public string BackdropSubText => !Win32Helper.IsBackdropSupported() ? App.API.GetTranslation("BackdropTypeDisabledToolTip") : "";
public Settings Settings { get; }
private readonly Theme _theme = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index e63567ce5b2..49306cd2df1 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -468,7 +468,8 @@
+ Icon=""
+ Sub="{Binding BackdropSubText}">
-
From 39f41e49cea401bab95527b2c4b6247187b2042e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 17:05:23 +0800
Subject: [PATCH 0775/1335] Improve string resources
---
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Plugin/SearchDelayTime.cs | 20 +++++++++----------
Flow.Launcher/Languages/en.xaml | 8 ++++----
Flow.Launcher/SearchDelayTimeWindow.xaml.cs | 2 +-
.../SettingsPaneGeneralViewModel.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 10 +++++-----
.../plugin.json | 2 +-
7 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index fcfbe8ca0d1..6cb20d12fdd 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -323,7 +323,7 @@ public bool HideNotifyIcon
public bool SearchQueryResultsWithDelay { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelayTime SearchDelayTime { get; set; } = SearchDelayTime.Medium;
+ public SearchDelayTime SearchDelayTime { get; set; } = SearchDelayTime.Normal;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
diff --git a/Flow.Launcher.Plugin/SearchDelayTime.cs b/Flow.Launcher.Plugin/SearchDelayTime.cs
index 8dae5997e33..ae1daabe08a 100644
--- a/Flow.Launcher.Plugin/SearchDelayTime.cs
+++ b/Flow.Launcher.Plugin/SearchDelayTime.cs
@@ -6,27 +6,27 @@
public enum SearchDelayTime
{
///
- /// Long search delay time. 250ms.
+ /// Very long search delay time. 250ms.
///
- Long,
+ VeryLong,
///
- /// Moderately long search delay time. 200ms.
+ /// Long search delay time. 200ms.
///
- ModeratelyLong,
+ Long,
///
- /// Medium search delay time. 150ms. Default value.
+ /// Normal search delay time. 150ms. Default value.
///
- Medium,
+ Normal,
///
- /// Moderately short search delay time. 100ms.
+ /// Short search delay time. 100ms.
///
- ModeratelyShort,
+ Short,
///
- /// Short search delay time. 50ms.
+ /// Very short search delay time. 50ms.
///
- Short
+ VeryShort
}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index e6a764d4815..364be40096b 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -105,12 +105,12 @@
Search Delay
Delay for a while to search when typing. This reduces interface jumpiness and result load.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped. Default is "Medium".
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
Long
- Moderately long
- Medium
- Moderately short
+ Normal
Short
+ Very short
Search Plugin
diff --git a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
index cfd8c5b7ee5..4a3c9f5a730 100644
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
+++ b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
@@ -24,7 +24,7 @@ private void SearchDelayTimeWindow_OnLoaded(object sender, RoutedEventArgs e)
tbOldSearchDelayTime.Text = _pluginViewModel.SearchDelayTimeText;
var searchDelayTimes = DropdownDataGeneric.GetValues("SearchDelayTime");
SearchDelayTimeData selected = null;
- // Because default value is SearchDelayTime.Slow, we need to get selected value before adding default value
+ // Because default value is SearchDelayTime.VeryShort, we need to get selected value before adding default value
if (_pluginViewModel.PluginSearchDelayTime != null)
{
selected = searchDelayTimes.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelayTime);
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3262ad2084c..cec8c318c59 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -150,7 +150,7 @@ public bool PortableMode
public SearchDelayTimeData SearchDelayTime
{
get => SearchDelayTimes.FirstOrDefault(x => x.Value == Settings.SearchDelayTime) ??
- SearchDelayTimes.FirstOrDefault(x => x.Value == Plugin.SearchDelayTime.Medium) ??
+ SearchDelayTimes.FirstOrDefault(x => x.Value == Plugin.SearchDelayTime.Normal) ??
SearchDelayTimes.FirstOrDefault();
set
{
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 283e26b9532..2fc4eaf7cf3 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1273,11 +1273,11 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
var searchDelayTime = (plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime) switch
{
- SearchDelayTime.Long => 250,
- SearchDelayTime.ModeratelyLong => 200,
- SearchDelayTime.Medium => 150,
- SearchDelayTime.ModeratelyShort => 100,
- SearchDelayTime.Short => 50,
+ SearchDelayTime.VeryLong => 250,
+ SearchDelayTime.Long => 200,
+ SearchDelayTime.Normal => 150,
+ SearchDelayTime.Short => 100,
+ SearchDelayTime.VeryShort => 50,
_ => 150
};
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index e274261334a..64681f803b8 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -32,5 +32,5 @@
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
"IcoPath": "Images\\web_search.png",
- "SearchDelayTime": "Long"
+ "SearchDelayTime": "VeryLong"
}
From 63b27ae84437f2d38938b74f69ea72b93e389ef6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 18:04:46 +0800
Subject: [PATCH 0776/1335] Remove debug codes
---
Flow.Launcher/ViewModel/MainViewModel.cs | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 24890a3636a..caedb44c02b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1150,9 +1150,6 @@ private void QueryHistory()
private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, bool reSelect = true)
{
- // TODO: Remove debug codes.
- System.Diagnostics.Debug.WriteLine("!!!QueryResults");
-
_updateSource?.Cancel();
var query = ConstructQuery(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
@@ -1233,8 +1230,6 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
true => Task.CompletedTask
}).ToArray();
- // TODO: Remove debug codes.
- System.Diagnostics.Debug.Write($"!!!Querying {query.RawQuery}: search delay {searchDelay}");
foreach (var plugin in plugins)
{
if (!plugin.Metadata.Disabled)
@@ -1281,14 +1276,8 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
_ => 150
};
- // TODO: Remove debug codes.
- System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waiting {searchDelayTime} ms");
-
await Task.Delay(searchDelayTime, token);
- // TODO: Remove debug codes.
- System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waited {searchDelayTime} ms");
-
if (token.IsCancellationRequested)
return;
}
@@ -1297,8 +1286,6 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
// Task.Yield will force it to run in ThreadPool
await Task.Yield();
- // TODO: Remove debug codes.
- System.Diagnostics.Debug.WriteLine($"!!!{query.RawQuery} Querying {plugin.Metadata.Name}");
IReadOnlyList results =
await PluginManager.QueryForPluginAsync(plugin, query, token);
From 0963a6c46783c5ba8152606986399afbc1a651b9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 18:07:02 +0800
Subject: [PATCH 0777/1335] Remove debug codes
---
Flow.Launcher/ViewModel/MainViewModel.cs | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index caedb44c02b..17e4b55b71e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1230,15 +1230,6 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
true => Task.CompletedTask
}).ToArray();
- foreach (var plugin in plugins)
- {
- if (!plugin.Metadata.Disabled)
- {
- System.Diagnostics.Debug.Write($"{plugin.Metadata.Name}, ");
- }
- }
- System.Diagnostics.Debug.Write("\n");
-
try
{
// Check the code, WhenAll will translate all type of IEnumerable or Collection to Array, so make an array at first
From ce93e24c7e490ab136abfa0797a0b85dabdb8fe7 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 31 Mar 2025 20:30:29 +0900
Subject: [PATCH 0778/1335] Ungroup Item in general page
---
.../Views/SettingsPaneGeneral.xaml | 57 ++++++-------------
1 file changed, 16 insertions(+), 41 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index edb2c144166..3f8272ddafe 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -28,16 +28,16 @@
Style="{StaticResource PageTitle}"
Text="{DynamicResource general}"
TextAlignment="left" />
-
-
-
-
+
+
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
Date: Mon, 31 Mar 2025 21:19:49 +0900
Subject: [PATCH 0779/1335] Add Control in PluginDisplay
---
.../Controls/InstalledPluginDisplay.xaml | 42 ++++++++++++++++---
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index b19c668e0bd..74edd2deac5 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -48,7 +48,7 @@
Grid.Column="2"
HorizontalAlignment="Right"
Orientation="Horizontal">
-
-
+ -->
+
+
-
-
+ -->
+
+
+
+
+
+
+
+
+
+ OnContent="{DynamicResource enable}"
+ Visibility="Collapsed" />
From eeb9ea78fdc39014f806263145ca5eb64b8d4651 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 21:27:59 +0800
Subject: [PATCH 0780/1335] Code quality
---
.../Environments/AbstractPluginEnvironment.cs | 50 +++++++++----------
1 file changed, 24 insertions(+), 26 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 7e9cc9a484a..f80e573f99f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -1,15 +1,14 @@
-using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin;
-using Flow.Launcher.Plugin.SharedCommands;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
-using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -43,8 +42,11 @@ internal AbstractPluginEnvironment(List pluginMetadataList, Plug
internal IEnumerable Setup()
{
+ // If no plugin is using the language, return empty list
if (!PluginMetadataList.Any(o => o.Language.Equals(Language, StringComparison.OrdinalIgnoreCase)))
+ {
return new List();
+ }
if (!string.IsNullOrEmpty(PluginsSettingsFilePath) && FilesFolders.FileExists(PluginsSettingsFilePath))
{
@@ -56,24 +58,21 @@ internal IEnumerable Setup()
}
var noRuntimeMessage = string.Format(
- InternationalizationManager.Instance.GetTranslation("runtimePluginInstalledChooseRuntimePrompt"),
+ API.GetTranslation("runtimePluginInstalledChooseRuntimePrompt"),
Language,
EnvName,
Environment.NewLine
);
if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
- var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
- string selectedFile;
+ var msg = string.Format(API.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
- selectedFile = GetFileFromDialog(msg, FileDialogFilter);
+ var selectedFile = GetFileFromDialog(msg, FileDialogFilter);
- if (!string.IsNullOrEmpty(selectedFile))
- PluginsSettingsFilePath = selectedFile;
+ if (!string.IsNullOrEmpty(selectedFile)) PluginsSettingsFilePath = selectedFile;
// Nothing selected because user pressed cancel from the file dialog window
- if (string.IsNullOrEmpty(selectedFile))
- InstallEnvironment();
+ if (string.IsNullOrEmpty(selectedFile)) InstallEnvironment();
}
else
{
@@ -86,7 +85,7 @@ internal IEnumerable Setup()
}
else
{
- API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
+ API.ShowMsgBox(string.Format(API.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
@@ -99,13 +98,11 @@ internal IEnumerable Setup()
private void EnsureLatestInstalled(string expectedPath, string currentPath, string installedDirPath)
{
- if (expectedPath == currentPath)
- return;
+ if (expectedPath == currentPath) return;
FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));
InstallEnvironment();
-
}
internal abstract PluginPair CreatePluginPair(string filePath, PluginMetadata metadata);
@@ -126,7 +123,7 @@ private IEnumerable SetPathForPluginPairs(string filePath, string la
return pluginPairs;
}
- private string GetFileFromDialog(string title, string filter = "")
+ private static string GetFileFromDialog(string title, string filter = "")
{
var dlg = new OpenFileDialog
{
@@ -140,7 +137,6 @@ private string GetFileFromDialog(string title, string filter = "")
var result = dlg.ShowDialog();
return result == DialogResult.OK ? dlg.FileName : string.Empty;
-
}
///
@@ -183,31 +179,33 @@ public static void PreStartPluginExecutablePathUpdate(Settings settings)
else
{
if (IsUsingPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName))
+ {
settings.PluginSettings.PythonExecutablePath
= GetUpdatedEnvironmentPath(settings.PluginSettings.PythonExecutablePath);
+ }
if (IsUsingPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName))
+ {
settings.PluginSettings.NodeExecutablePath
= GetUpdatedEnvironmentPath(settings.PluginSettings.NodeExecutablePath);
+ }
}
}
private static bool IsUsingPortablePath(string filePath, string pluginEnvironmentName)
{
- if (string.IsNullOrEmpty(filePath))
- return false;
+ if (string.IsNullOrEmpty(filePath)) return false;
// DataLocation.PortableDataPath returns the current portable path, this determines if an out
// of date path is also a portable path.
- var portableAppEnvLocation = $"UserData\\{DataLocation.PluginEnvironments}\\{pluginEnvironmentName}";
+ var portableAppEnvLocation = Path.Combine("UserData", DataLocation.PluginEnvironments, pluginEnvironmentName);
return filePath.Contains(portableAppEnvLocation);
}
private static bool IsUsingRoamingPath(string filePath)
{
- if (string.IsNullOrEmpty(filePath))
- return false;
+ if (string.IsNullOrEmpty(filePath)) return false;
return filePath.StartsWith(DataLocation.RoamingDataPath);
}
@@ -217,7 +215,7 @@ private static string GetUpdatedEnvironmentPath(string filePath)
var index = filePath.IndexOf(DataLocation.PluginEnvironments);
// get the substring after "Environments" because we can not determine it dynamically
- var ExecutablePathSubstring = filePath.Substring(index + DataLocation.PluginEnvironments.Count());
+ var ExecutablePathSubstring = filePath[(index + DataLocation.PluginEnvironments.Length)..];
return $"{DataLocation.PluginEnvironmentsPath}{ExecutablePathSubstring}";
}
}
From 5fa244c806c430d35325ae30aa1dc22c5c6c4d40 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 31 Mar 2025 22:44:34 +0900
Subject: [PATCH 0781/1335] Add setting filter
---
.../Converters/StringEqualityToVisibilityConverter.cs | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
diff --git a/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs b/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
new file mode 100644
index 00000000000..4757681bc73
--- /dev/null
+++ b/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
@@ -0,0 +1,6 @@
+namespace Flow.Launcher.Converters;
+
+public class StringEqualityToVisibilityConverter
+{
+
+}
From 0136c570faf3d8cdf4e7094054a1ed0cd62103c5 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 31 Mar 2025 22:44:46 +0900
Subject: [PATCH 0782/1335] Add Setting Filter
---
.../StringEqualityToVisibilityConverter.cs | 23 ++++-
.../Controls/InstalledPluginDisplay.xaml | 34 +++++--
.../SettingsPanePluginsViewModel.cs | 69 +++++++++++++++
.../Views/SettingsPanePlugins.xaml | 88 ++++++++++---------
Flow.Launcher/ViewModel/PluginViewModel.cs | 14 ++-
5 files changed, 172 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs b/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
index 4757681bc73..4e44536361e 100644
--- a/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
+++ b/Flow.Launcher/Converters/StringEqualityToVisibilityConverter.cs
@@ -1,6 +1,23 @@
-namespace Flow.Launcher.Converters;
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
-public class StringEqualityToVisibilityConverter
+namespace Flow.Launcher.Converters
{
-
+ public class StringEqualityToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value == null || parameter == null)
+ return Visibility.Collapsed;
+
+ return value.ToString() == parameter.ToString() ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
}
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 74edd2deac5..ca9f673d893 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -7,10 +7,14 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:viewModel="clr-namespace:Flow.Launcher.ViewModel"
+ xmlns:converters="clr-namespace:Flow.Launcher.Converters"
d:DataContext="{d:DesignInstance viewModel:PluginViewModel}"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
+
+
+
+ Visibility="{Binding DataContext.CurrentDisplayMode,
+ RelativeSource={RelativeSource AncestorType=ListBox},
+ Converter={StaticResource StringEqualityToVisibilityConverter},
+ ConverterParameter=Priority}">
+ Margin="0 0 8 0"
+ VerticalAlignment="Center"
+ FontSize="13"
+ Foreground="{DynamicResource Color08B}"
+ Text="{DynamicResource priority}" />
+
+ Visibility="{Binding DataContext.CurrentDisplayMode,
+ RelativeSource={RelativeSource AncestorType=ListBox},
+ Converter={StaticResource StringEqualityToVisibilityConverter},
+ ConverterParameter=SearchDelay}">
+
-
+ Visibility="{Binding DataContext.CurrentDisplayMode,
+ RelativeSource={RelativeSource AncestorType=ListBox},
+ Converter={StaticResource StringEqualityToVisibilityConverter},
+ ConverterParameter=OnOff}" />
+
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 3c1aba400a0..5cd14ba7edb 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -14,6 +14,75 @@ public class SettingsPanePluginsViewModel : BaseModel
{
private readonly Settings _settings;
+ private bool _isOnOffSelected = true;
+ public bool IsOnOffSelected
+ {
+ get => _isOnOffSelected;
+ set
+ {
+ if (_isOnOffSelected != value)
+ {
+ _isOnOffSelected = value;
+ OnPropertyChanged(nameof(IsOnOffSelected));
+ UpdateDisplayMode();
+ }
+ }
+ }
+
+ private bool _isPrioritySelected;
+ public bool IsPrioritySelected
+ {
+ get => _isPrioritySelected;
+ set
+ {
+ if (_isPrioritySelected != value)
+ {
+ _isPrioritySelected = value;
+ OnPropertyChanged(nameof(IsPrioritySelected));
+ UpdateDisplayMode();
+ }
+ }
+ }
+
+ private bool _isSearchDelaySelected;
+ public bool IsSearchDelaySelected
+ {
+ get => _isSearchDelaySelected;
+ set
+ {
+ if (_isSearchDelaySelected != value)
+ {
+ _isSearchDelaySelected = value;
+ OnPropertyChanged(nameof(IsSearchDelaySelected));
+ UpdateDisplayMode();
+ }
+ }
+ }
+
+ private string _currentDisplayMode = "OnOff";
+ public string CurrentDisplayMode
+ {
+ get => _currentDisplayMode;
+ set
+ {
+ if (_currentDisplayMode != value)
+ {
+ _currentDisplayMode = value;
+ OnPropertyChanged(nameof(CurrentDisplayMode));
+ }
+ }
+ }
+
+ private void UpdateDisplayMode()
+ {
+ if (IsOnOffSelected)
+ CurrentDisplayMode = "OnOff";
+ else if (IsPrioritySelected)
+ CurrentDisplayMode = "Priority";
+ else if (IsSearchDelaySelected)
+ CurrentDisplayMode = "SearchDelay";
+ }
+
public SettingsPanePluginsViewModel(Settings settings)
{
_settings = settings;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index 37079a46fef..7580a559189 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -6,6 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019"
+ xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:viewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
Title="Plugins"
@@ -17,6 +18,7 @@
mc:Ignorable="d">
+
@@ -31,51 +33,51 @@
Style="{StaticResource PageTitle}"
Text="{DynamicResource plugins}"
TextAlignment="Left" />
-
-
-
-
-
+ Orientation="Horizontal"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center">
+
+
+
+
+
+
+
string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
- public int Priority => PluginPair.Metadata.Priority;
+ //public int Priority => PluginPair.Metadata.Priority;
+ private int _priority;
+ public int Priority
+ {
+ get => PluginPair.Metadata.Priority;
+ set
+ {
+ if (PluginPair.Metadata.Priority != value)
+ {
+ ChangePriority(value);
+ }
+ }
+ }
public string SearchDelayTimeText => PluginPair.Metadata.SearchDelayTime == null ?
App.API.GetTranslation("default") :
App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
From cc1e6dd7eeb40218e1c89b6399530d6db9c5a8e7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 31 Mar 2025 21:53:33 +0800
Subject: [PATCH 0783/1335] Fix theme select initialization issue
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 4467b94fbdb..31faeba5231 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -9,9 +9,13 @@ public class ThemeSelector
{
public const string Keyword = "fltheme";
- private readonly Theme _theme;
private readonly PluginInitContext _context;
+ // Do not initialize it in the constructor, because it will cause null reference in
+ // var dicts = Application.Current.Resources.MergedDictionaries; line of Theme
+ private Theme theme = null;
+ private Theme Theme => theme ??= Ioc.Default.GetRequiredService();
+
#region Theme Selection
// Theme select codes simplified from SettingsPaneThemeViewModel.cs
@@ -19,24 +23,23 @@ public class ThemeSelector
private Theme.ThemeData _selectedTheme;
public Theme.ThemeData SelectedTheme
{
- get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == _theme.GetCurrentTheme());
+ get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == Theme.GetCurrentTheme());
set
{
_selectedTheme = value;
- _theme.ChangeTheme(value.FileNameWithoutExtension);
+ Theme.ChangeTheme(value.FileNameWithoutExtension);
- _ = _theme.RefreshFrameAsync();
+ _ = Theme.RefreshFrameAsync();
}
}
- private List Themes => _theme.LoadAvailableThemes();
+ private List Themes => Theme.LoadAvailableThemes();
#endregion
public ThemeSelector(PluginInitContext context)
{
_context = context;
- _theme = Ioc.Default.GetRequiredService();
}
public List Query(Query query)
From fb50e6d08f6a31e4e43983867bfff3384acad300 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 1 Apr 2025 05:03:49 +0900
Subject: [PATCH 0784/1335] Add search delay control
---
Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index ca9f673d893..009644fd606 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -120,9 +120,7 @@
RelativeSource={RelativeSource AncestorType=ListBox},
Converter={StaticResource StringEqualityToVisibilityConverter},
ConverterParameter=SearchDelay}">
-
From d77400d39bbe1dbc7ae476326dfce66e3748f93f Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 1 Apr 2025 05:36:24 +0900
Subject: [PATCH 0785/1335] Add customcontrol for searchdelay
---
.../Controls/InstalledPluginDisplay.xaml | 5 +-
.../InstalledPluginSearchDelayCombobox.xaml | 39 +++++++++
...InstalledPluginSearchDelayCombobox.xaml.cs | 84 +++++++++++++++++++
3 files changed, 126 insertions(+), 2 deletions(-)
create mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
create mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 009644fd606..cb1d8dbc45f 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -92,7 +92,7 @@
-
-
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
new file mode 100644
index 00000000000..b379b875f53
--- /dev/null
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
new file mode 100644
index 00000000000..649913872bb
--- /dev/null
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
@@ -0,0 +1,84 @@
+using System.Collections.Generic;
+using System.Windows.Controls;
+using Flow.Launcher.Plugin;
+
+namespace Flow.Launcher.Resources.Controls
+{
+ public partial class InstalledPluginSearchDelayCombobox
+ {
+ public InstalledPluginSearchDelayCombobox()
+ {
+ InitializeComponent();
+ LoadDelayOptions();
+ Loaded += InstalledPluginSearchDelayCombobox_Loaded;
+ }
+
+ private void InstalledPluginSearchDelayCombobox_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ if (DataContext is ViewModel.PluginViewModel viewModel)
+ {
+ // 초기 값 설정
+ int currentDelayMs = GetCurrentDelayMs(viewModel);
+ foreach (DelayOption option in cbDelay.Items)
+ {
+ if (option.Value == currentDelayMs)
+ {
+ cbDelay.SelectedItem = option;
+ break;
+ }
+ }
+ }
+ }
+
+ private int GetCurrentDelayMs(ViewModel.PluginViewModel viewModel)
+ {
+ // SearchDelayTime enum 값을 int로 변환
+ SearchDelayTime? delayTime = viewModel.PluginPair.Metadata.SearchDelayTime;
+ if (delayTime.HasValue)
+ {
+ return (int)delayTime.Value;
+ }
+ return 0; // 기본값
+ }
+
+ private void LoadDelayOptions()
+ {
+ // 검색 지연 시간 옵션들 (SearchDelayTime enum 값에 맞춰야 함)
+ var delayOptions = new List
+ {
+ new DelayOption { Display = "0 ms", Value = 0 },
+ new DelayOption { Display = "50 ms", Value = 50 },
+ new DelayOption { Display = "100 ms", Value = 100 },
+ new DelayOption { Display = "150 ms", Value = 150 },
+ new DelayOption { Display = "200 ms", Value = 200 },
+ new DelayOption { Display = "250 ms", Value = 250 },
+ new DelayOption { Display = "300 ms", Value = 300 },
+ new DelayOption { Display = "350 ms", Value = 350 },
+ new DelayOption { Display = "400 ms", Value = 400 },
+ new DelayOption { Display = "450 ms", Value = 450 },
+ new DelayOption { Display = "500 ms", Value = 500 },
+ };
+
+ cbDelay.ItemsSource = delayOptions;
+ }
+
+ private void CbDelay_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (DataContext is ViewModel.PluginViewModel viewModel && cbDelay.SelectedItem is DelayOption selectedOption)
+ {
+ // int 값을 SearchDelayTime enum으로 변환
+ int delayValue = selectedOption.Value;
+ viewModel.PluginPair.Metadata.SearchDelayTime = (SearchDelayTime)delayValue;
+
+ // 설정 저장
+ //How to save?
+ }
+ }
+ }
+
+ public class DelayOption
+ {
+ public string Display { get; set; }
+ public int Value { get; set; }
+ }
+}
From bf259dcb13eb0258417f79e1858303717c32a1e9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 08:47:57 +0800
Subject: [PATCH 0786/1335] Fix application dispose issue
---
Flow.Launcher/App.xaml.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 7b1d113fbdc..9aee56bff81 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -138,6 +138,11 @@ private async void OnStartup(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
+ // Because new message box api uses MessageBoxEx window,
+ // if it is created and closed before main window is created, it will cause the application to exit.
+ // So set to OnExplicitShutdown to prevent the application from shutting down before main window is created
+ Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
+
Log.SetLogLevel(_settings.LogLevel);
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
From 6a2b3495a009927c8593de42a3c21020f01c12d7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 09:26:39 +0800
Subject: [PATCH 0787/1335] Ask reselect environment path until it is valid
---
.../Environments/AbstractPluginEnvironment.cs | 40 +++++++++++++++++--
Flow.Launcher/Languages/en.xaml | 5 +++
2 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index f80e573f99f..0bd00d982ae 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -69,10 +69,44 @@ internal IEnumerable Setup()
var selectedFile = GetFileFromDialog(msg, FileDialogFilter);
- if (!string.IsNullOrEmpty(selectedFile)) PluginsSettingsFilePath = selectedFile;
-
+ if (!string.IsNullOrEmpty(selectedFile))
+ {
+ PluginsSettingsFilePath = selectedFile;
+ }
// Nothing selected because user pressed cancel from the file dialog window
- if (string.IsNullOrEmpty(selectedFile)) InstallEnvironment();
+ else
+ {
+ var forceDownloadMessage = string.Format(
+ API.GetTranslation("runtimeExecutableInvalidChooseDownload"),
+ Language,
+ EnvName,
+ Environment.NewLine
+ );
+
+ // Let users select valid path or choose to download
+ while (string.IsNullOrEmpty(selectedFile))
+ {
+ if (API.ShowMsgBox(forceDownloadMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ // Continue select file
+ selectedFile = GetFileFromDialog(msg, FileDialogFilter);
+ }
+ else
+ {
+ // User selected no, break the loop
+ break;
+ }
+ }
+
+ if (!string.IsNullOrEmpty(selectedFile))
+ {
+ PluginsSettingsFilePath = selectedFile;
+ }
+ else
+ {
+ InstallEnvironment();
+ }
+ }
}
else
{
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 3c0e5b1532d..2df430c3b67 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -9,6 +9,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
From a9dfd1b377d2129cf74a51171386db84bc486a78 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 09:57:04 +0800
Subject: [PATCH 0788/1335] Code quality
---
.../Environments/AbstractPluginEnvironment.cs | 4 ++--
.../Environments/PythonEnvironment.cs | 12 ++++++++----
.../Environments/TypeScriptEnvironment.cs | 12 ++++++++----
.../Environments/TypeScriptV2Environment.cs | 12 ++++++++----
4 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index 0bd00d982ae..bbb6cf63870 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -249,8 +249,8 @@ private static string GetUpdatedEnvironmentPath(string filePath)
var index = filePath.IndexOf(DataLocation.PluginEnvironments);
// get the substring after "Environments" because we can not determine it dynamically
- var ExecutablePathSubstring = filePath[(index + DataLocation.PluginEnvironments.Length)..];
- return $"{DataLocation.PluginEnvironmentsPath}{ExecutablePathSubstring}";
+ var executablePathSubstring = filePath[(index + DataLocation.PluginEnvironments.Length)..];
+ return $"{DataLocation.PluginEnvironmentsPath}{executablePathSubstring}";
}
}
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index 607c1906215..fab5738de3b 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -1,10 +1,10 @@
-using Droplex;
+using System.Collections.Generic;
+using System.IO;
+using Droplex;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
-using System.Collections.Generic;
-using System.IO;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -22,7 +22,11 @@ internal class PythonEnvironment : AbstractPluginEnvironment
internal override string FileDialogFilter => "Python|pythonw.exe";
- internal override string PluginsSettingsFilePath { get => PluginSettings.PythonExecutablePath; set => PluginSettings.PythonExecutablePath = value; }
+ internal override string PluginsSettingsFilePath
+ {
+ get => PluginSettings.PythonExecutablePath;
+ set => PluginSettings.PythonExecutablePath = value;
+ }
internal PythonEnvironment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 399f7cc03fd..8a4f527ba83 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -1,10 +1,10 @@
using System.Collections.Generic;
+using System.IO;
using Droplex;
+using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin;
-using System.IO;
-using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -19,7 +19,11 @@ internal class TypeScriptEnvironment : AbstractPluginEnvironment
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
- internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
+ internal override string PluginsSettingsFilePath
+ {
+ get => PluginSettings.NodeExecutablePath;
+ set => PluginSettings.NodeExecutablePath = value;
+ }
internal TypeScriptEnvironment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index e8cb72e11d6..61fd2837677 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -1,10 +1,10 @@
using System.Collections.Generic;
+using System.IO;
using Droplex;
+using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin;
-using System.IO;
-using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -19,7 +19,11 @@ internal class TypeScriptV2Environment : AbstractPluginEnvironment
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
- internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
+ internal override string PluginsSettingsFilePath
+ {
+ get => PluginSettings.NodeExecutablePath;
+ set => PluginSettings.NodeExecutablePath = value;
+ }
internal TypeScriptV2Environment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
From f9c1b6aa3e4dd7052f484e8518e92fffbe234861 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 09:57:55 +0800
Subject: [PATCH 0789/1335] Adjust usings
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 4f869901ca8..17517832bd8 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -1,20 +1,19 @@
-using Flow.Launcher.Core.ExternalPlugins;
-using System;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using ISavable = Flow.Launcher.Plugin.ISavable;
using Flow.Launcher.Plugin.SharedCommands;
-using System.Text.Json;
-using Flow.Launcher.Core.Resource;
-using CommunityToolkit.Mvvm.DependencyInjection;
+using ISavable = Flow.Launcher.Plugin.ISavable;
namespace Flow.Launcher.Core.Plugin
{
From 6f0126d3ba3f4ab8c6928141287391602d77cf1f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 11:47:18 +0800
Subject: [PATCH 0790/1335] Add log error api function for csharp and jsonrpc
---
.../Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs | 8 ++++++--
Flow.Launcher.Infrastructure/Logger/Log.cs | 11 ++---------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 5 +++++
Flow.Launcher/PublicAPIInstance.cs | 3 +++
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index 8df2ce9ed9e..102d0089f9a 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -12,7 +12,7 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models
{
public class JsonRPCPublicAPI
{
- private IPublicAPI _api;
+ private readonly IPublicAPI _api;
public JsonRPCPublicAPI(IPublicAPI api)
{
@@ -104,7 +104,6 @@ public List GetAllPlugins()
return _api.GetAllPlugins();
}
-
public MatchResult FuzzySearch(string query, string stringToCompare)
{
return _api.FuzzySearch(query, stringToCompare);
@@ -156,6 +155,11 @@ public void LogWarn(string className, string message, [CallerMemberName] string
_api.LogWarn(className, message, methodName);
}
+ public void LogError(string className, string message, [CallerMemberName] string methodName = "")
+ {
+ _api.LogError(className, message, methodName);
+ }
+
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
_api.OpenDirectory(DirectoryPath, FileNameOrFilePath);
diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs
index 9f5d6725e2b..9e1173f34de 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -1,12 +1,12 @@
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Runtime.ExceptionServices;
+using Flow.Launcher.Infrastructure.UserSettings;
using NLog;
using NLog.Config;
using NLog.Targets;
-using Flow.Launcher.Infrastructure.UserSettings;
using NLog.Targets.Wrappers;
-using System.Runtime.ExceptionServices;
namespace Flow.Launcher.Infrastructure.Logger
{
@@ -135,13 +135,6 @@ private static string CheckClassAndMessageAndReturnFullClassWithMethod(string cl
return className;
}
- private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
- {
- var logger = LogManager.GetLogger(classAndMethod);
-
- logger.Error(e, message);
- }
-
private static void LogInternal(string message, LogLevel level)
{
if (FormatValid(message))
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index f178ebb90d4..9258e514703 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -227,6 +227,11 @@ public interface IPublicAPI
///
void LogWarn(string className, string message, [CallerMemberName] string methodName = "");
+ ///
+ /// Log error message
+ ///
+ void LogError(string className, string message, [CallerMemberName] string methodName = "");
+
///
/// Log an Exception. Will throw if in debug mode so developer will be aware,
/// otherwise logs the eror message. This is the primary logging method used for Flow
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e19ad2fdcd4..31307b6688b 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -187,6 +187,9 @@ public void LogInfo(string className, string message, [CallerMemberName] string
public void LogWarn(string className, string message, [CallerMemberName] string methodName = "") =>
Log.Warn(className, message, methodName);
+ public void LogError(string className, string message, [CallerMemberName] string methodName = "") =>
+ Log.Error(className, message, methodName);
+
public void LogException(string className, string message, Exception e,
[CallerMemberName] string methodName = "") => Log.Exception(className, message, e, methodName);
From 1381248e9e71444b56704548167830010f97ac68 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 11:54:18 +0800
Subject: [PATCH 0791/1335] Adjust code formats
---
Flow.Launcher/PublicAPIInstance.cs | 35 ++++++++++++++++++++----------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 31307b6688b..2d2713e7908 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -11,9 +11,9 @@
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Squirrel;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -27,7 +27,7 @@
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
-using Flow.Launcher.Core.Resource;
+using Squirrel;
namespace Flow.Launcher
{
@@ -78,7 +78,11 @@ public void RestartApp()
public bool IsMainWindowVisible() => _mainVM.MainWindowVisibilityStatus;
- public event VisibilityChangedEventHandler VisibilityChanged { add => _mainVM.VisibilityChanged += value; remove => _mainVM.VisibilityChanged -= value; }
+ public event VisibilityChangedEventHandler VisibilityChanged
+ {
+ add => _mainVM.VisibilityChanged += value;
+ remove => _mainVM.VisibilityChanged -= value;
+ }
// Must use Ioc.Default.GetRequiredService() to avoid circular dependency
public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
@@ -162,13 +166,14 @@ public void CopyToClipboard(string stringToCopy, bool directCopy = false, bool s
public MatchResult FuzzySearch(string query, string stringToCompare) =>
StringMatcher.FuzzySearch(query, stringToCompare);
- public Task HttpGetStringAsync(string url, CancellationToken token = default) => Http.GetAsync(url, token);
+ public Task HttpGetStringAsync(string url, CancellationToken token = default) =>
+ Http.GetAsync(url, token);
public Task HttpGetStreamAsync(string url, CancellationToken token = default) =>
Http.GetStreamAsync(url, token);
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null,
- CancellationToken token = default) => Http.DownloadAsync(url, filePath, reportProgress, token);
+ CancellationToken token = default) =>Http.DownloadAsync(url, filePath, reportProgress, token);
public void AddActionKeyword(string pluginId, string newActionKeyword) =>
PluginManager.AddActionKeyword(pluginId, newActionKeyword);
@@ -190,8 +195,8 @@ public void LogWarn(string className, string message, [CallerMemberName] string
public void LogError(string className, string message, [CallerMemberName] string methodName = "") =>
Log.Error(className, message, methodName);
- public void LogException(string className, string message, Exception e,
- [CallerMemberName] string methodName = "") => Log.Exception(className, message, e, methodName);
+ public void LogException(string className, string message, Exception e, [CallerMemberName] string methodName = "") =>
+ Log.Exception(className, message, e, methodName);
private readonly ConcurrentDictionary _pluginJsonStorages = new();
@@ -204,7 +209,7 @@ public void RemovePluginSettings(string assemblyName)
var name = value.GetType().GetField("AssemblyName")?.GetValue(value)?.ToString();
if (name == assemblyName)
{
- _pluginJsonStorages.Remove(key, out var pluginJsonStorage);
+ _pluginJsonStorages.Remove(key, out var _);
}
}
}
@@ -333,17 +338,23 @@ public bool IsGameModeOn()
private readonly List> _globalKeyboardHandlers = new();
- public void RegisterGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Add(callback);
- public void RemoveGlobalKeyboardCallback(Func callback) => _globalKeyboardHandlers.Remove(callback);
+ public void RegisterGlobalKeyboardCallback(Func callback) =>
+ _globalKeyboardHandlers.Add(callback);
+
+ public void RemoveGlobalKeyboardCallback(Func callback) =>
+ _globalKeyboardHandlers.Remove(callback);
public void ReQuery(bool reselect = true) => _mainVM.ReQuery(reselect);
public void BackToQueryResults() => _mainVM.BackToQueryResults();
- public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
+ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "",
+ MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None,
+ MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync,
+ Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
#endregion
From 835e4096c8ec781e6bd319946853060f9de2b493 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 11:56:51 +0800
Subject: [PATCH 0792/1335] Fix build issue
---
Flow.Launcher.Infrastructure/Logger/Log.cs | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs
index 9e1173f34de..84331ef702e 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -135,6 +135,15 @@ private static string CheckClassAndMessageAndReturnFullClassWithMethod(string cl
return className;
}
+#if !DEBUG
+ private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
+ {
+ var logger = LogManager.GetLogger(classAndMethod);
+
+ logger.Error(e, message);
+ }
+#endif
+
private static void LogInternal(string message, LogLevel level)
{
if (FormatValid(message))
From 24327533c6e165f0cfa02e9a822fcf973c1880df Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 14:16:32 +0800
Subject: [PATCH 0793/1335] Add plugin json storage
---
.../Image/ImageLoader.cs | 1 +
.../Storage/BinaryStorage.cs | 60 +++++++++++++++----
.../Storage/PluginBinaryStorage.cs | 15 +++++
.../Storage/PluginJsonStorage.cs | 6 --
4 files changed, 64 insertions(+), 18 deletions(-)
create mode 100644 Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 6f7b1cd908d..cca4bd2a4f1 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -37,6 +37,7 @@ public static async Task InitializeAsync()
_hashGenerator = new ImageHashGenerator();
var usage = await LoadStorageToConcurrentDictionaryAsync();
+ _storage.ClearData();
ImageCache.Initialize(usage);
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 5b73faae6a6..69ac6000b76 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -4,6 +4,8 @@
using Flow.Launcher.Infrastructure.UserSettings;
using MemoryPack;
+#nullable enable
+
namespace Flow.Launcher.Infrastructure.Storage
{
///
@@ -15,40 +17,53 @@ namespace Flow.Launcher.Infrastructure.Storage
///
public class BinaryStorage
{
+ protected T? Data;
+
public const string FileSuffix = ".cache";
+ protected string FilePath { get; init; } = null!;
+
+ protected string DirectoryPath { get; init; } = null!;
+
// Let the derived class to set the file path
- public BinaryStorage(string filename, string directoryPath = null)
+ protected BinaryStorage()
{
- directoryPath ??= DataLocation.CacheDirectory;
- Helper.ValidateDirectory(directoryPath);
-
- FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
}
- public string FilePath { get; }
+ public BinaryStorage(string filename)
+ {
+ DirectoryPath = DataLocation.CacheDirectory;
+ Helper.ValidateDirectory(DirectoryPath);
+
+ FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}");
+ }
public async ValueTask TryLoadAsync(T defaultData)
{
+ if (Data != null)
+ return Data;
+
if (File.Exists(FilePath))
{
if (new FileInfo(FilePath).Length == 0)
{
Log.Error($"|BinaryStorage.TryLoad|Zero length cache file <{FilePath}>");
- await SaveAsync(defaultData);
- return defaultData;
+ Data = defaultData;
+ await SaveAsync();
}
await using var stream = new FileStream(FilePath, FileMode.Open);
var d = await DeserializeAsync(stream, defaultData);
- return d;
+ Data = d;
}
else
{
Log.Info("|BinaryStorage.TryLoad|Cache file not exist, load default data");
- await SaveAsync(defaultData);
- return defaultData;
+ Data = defaultData;
+ await SaveAsync();
}
+
+ return Data;
}
private static async ValueTask DeserializeAsync(Stream stream, T defaultData)
@@ -56,7 +71,7 @@ private static async ValueTask DeserializeAsync(Stream stream, T defaultData)
try
{
var t = await MemoryPackSerializer.DeserializeAsync(stream);
- return t;
+ return t ?? defaultData;
}
catch (System.Exception)
{
@@ -65,6 +80,27 @@ private static async ValueTask DeserializeAsync(Stream stream, T defaultData)
}
}
+ public async ValueTask SaveAsync()
+ {
+ await using var stream = new FileStream(FilePath, FileMode.Create);
+ await MemoryPackSerializer.SerializeAsync(stream, Data);
+ }
+
+ // For SavePluginSettings function
+ public void Save()
+ {
+ var serialized = MemoryPackSerializer.Serialize(Data);
+
+ File.WriteAllBytes(FilePath, serialized);
+ }
+
+ // ImageCache need to be converted into concurrent dictionary, so it does not need to cache loading results into Data
+ public void ClearData()
+ {
+ Data = default;
+ }
+
+ // ImageCache storages data in its class, so it needs to pass it to SaveAsync
public async ValueTask SaveAsync(T data)
{
await using var stream = new FileStream(FilePath, FileMode.Create);
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
new file mode 100644
index 00000000000..87f51d5d773
--- /dev/null
+++ b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
@@ -0,0 +1,15 @@
+using System.IO;
+
+namespace Flow.Launcher.Infrastructure.Storage
+{
+ public class PluginBinaryStorage : BinaryStorage where T : new()
+ {
+ public PluginBinaryStorage(string cacheName, string cacheDirectory)
+ {
+ DirectoryPath = cacheDirectory;
+ Helper.ValidateDirectory(DirectoryPath);
+
+ FilePath = Path.Combine(DirectoryPath, $"{cacheName}{FileSuffix}");
+ }
+ }
+}
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index b377c81aa14..9c6547c6684 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -10,7 +10,6 @@ namespace Flow.Launcher.Infrastructure.Storage
public PluginJsonStorage()
{
- // C# related, add python related below
var dataType = typeof(T);
AssemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, AssemblyName);
@@ -18,10 +17,5 @@ public PluginJsonStorage()
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
}
-
- public PluginJsonStorage(T data) : this()
- {
- Data = data;
- }
}
}
From ca221d710026b3e402873a174696a48e28e5d958 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 14:19:59 +0800
Subject: [PATCH 0794/1335] Add binary storage api functions
---
.../JsonRPCV2Models/JsonRPCPublicAPI.cs | 5 ++
Flow.Launcher.Core/Plugin/PluginManager.cs | 5 +-
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 33 ++++++++++++
Flow.Launcher.Plugin/Interfaces/ISavable.cs | 7 +--
Flow.Launcher/PublicAPIInstance.cs | 53 ++++++++++++++++---
5 files changed, 91 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
index 8df2ce9ed9e..cf1c57f3ece 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs
@@ -185,5 +185,10 @@ public void StopLoadingBar()
{
_api.StopLoadingBar();
}
+
+ public void SavePluginCaches()
+ {
+ _api.SavePluginCaches();
+ }
}
}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 4f869901ca8..fa4e43e0713 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -66,6 +66,7 @@ public static void Save()
}
API.SavePluginSettings();
+ API.SavePluginCaches();
}
public static async ValueTask DisposePluginsAsync()
@@ -587,11 +588,13 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo
if (removePluginSettings)
{
- // For dotnet plugins, we need to remove their PluginJsonStorage instance
+ // For dotnet plugins, we need to remove their PluginJsonStorage and PluginBinaryStorage instances
if (AllowedLanguage.IsDotNet(plugin.Language))
{
var method = API.GetType().GetMethod("RemovePluginSettings");
method?.Invoke(API, new object[] { plugin.AssemblyName });
+ var method1 = API.GetType().GetMethod("RemovePluginCache");
+ method1?.Invoke(API, new object[] { plugin.PluginCacheDirectoryPath });
}
try
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index f178ebb90d4..be776b06868 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,38 @@ public interface IPublicAPI
/// Stop the loading bar in main window
///
public void StopLoadingBar();
+
+ ///
+ /// Save all Flow's plugins caches
+ ///
+ void SavePluginCaches();
+
+ ///
+ /// Load BinaryStorage for current plugin's cache. This is the method used to load cache from binary in Flow.
+ /// When the file is not exist, it will create a new instance for the specific type.
+ ///
+ /// Type for deserialization
+ /// Cache file name
+ /// Cache directory from plugin metadata
+ /// Default data to return
+ ///
+ ///
+ /// BinaryStorage utilize MemoryPack, which means the object must be MemoryPackSerializable
+ ///
+ Task LoadCacheBinaryStorageAsync(string cacheName, string cacheDirectory, T defaultData) where T : new();
+
+ ///
+ /// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.Launcher
+ /// This method will save the original instance loaded with LoadCacheBinaryStorageAsync.
+ /// This API call is for manually Save. Flow will automatically save all cache type that has called LoadCacheBinaryStorageAsync or SaveCacheBinaryStorageAsync previously.
+ ///
+ /// Type for Serialization
+ /// Cache file name
+ /// Cache directory from plugin metadata
+ ///
+ ///
+ /// BinaryStorage utilize MemoryPack, which means the object must be MemoryPackSerializable
+ ///
+ Task SaveCacheBinaryStorageAsync(string cacheName, string cacheDirectory) where T : new();
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/ISavable.cs b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
index 77bd304e4ea..cabd269624e 100644
--- a/Flow.Launcher.Plugin/Interfaces/ISavable.cs
+++ b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
@@ -1,11 +1,12 @@
-namespace Flow.Launcher.Plugin
+namespace Flow.Launcher.Plugin
{
///
/// Inherit this interface if additional data e.g. cache needs to be saved.
///
///
/// For storing plugin settings, prefer
- /// or .
+ /// or .
+ /// or .
/// Once called, your settings will be automatically saved by Flow.
///
public interface ISavable : IFeatures
@@ -15,4 +16,4 @@ public interface ISavable : IFeatures
///
void Save();
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e19ad2fdcd4..17d7e103e9a 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -236,14 +236,6 @@ public void SavePluginSettings()
((PluginJsonStorage)_pluginJsonStorages[type]).Save();
}
- public void SaveJsonStorage(T settings) where T : new()
- {
- var type = typeof(T);
- _pluginJsonStorages[type] = new PluginJsonStorage(settings);
-
- ((PluginJsonStorage)_pluginJsonStorages[type]).Save();
- }
-
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
using var explorer = new Process();
@@ -342,6 +334,51 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
+ private readonly ConcurrentDictionary<(string, string, Type), object> _pluginBinaryStorages = new();
+
+ public void RemovePluginCache(string cacheDirectory)
+ {
+ foreach (var keyValuePair in _pluginBinaryStorages)
+ {
+ var key = keyValuePair.Key;
+ var currentCacheDirectory = key.Item2;
+ if (cacheDirectory == currentCacheDirectory)
+ {
+ _pluginBinaryStorages.Remove(key, out var _);
+ }
+ }
+ }
+
+ ///
+ /// Save plugin caches.
+ ///
+ public void SavePluginCaches()
+ {
+ foreach (var value in _pluginBinaryStorages.Values)
+ {
+ var method = value.GetType().GetMethod("Save");
+ method?.Invoke(value, null);
+ }
+ }
+
+ public async Task LoadCacheBinaryStorageAsync(string cacheName, string cacheDirectory, T defaultData) where T : new()
+ {
+ var type = typeof(T);
+ if (!_pluginBinaryStorages.ContainsKey((cacheName, cacheDirectory, type)))
+ _pluginBinaryStorages[(cacheName, cacheDirectory, type)] = new PluginBinaryStorage(cacheName, cacheDirectory);
+
+ return await ((PluginBinaryStorage)_pluginBinaryStorages[(cacheName, cacheDirectory, type)]).TryLoadAsync(defaultData);
+ }
+
+ public async Task SaveCacheBinaryStorageAsync(string cacheName, string cacheDirectory) where T : new()
+ {
+ var type = typeof(T);
+ if (!_pluginBinaryStorages.ContainsKey((cacheName, cacheDirectory, type)))
+ _pluginBinaryStorages[(cacheName, cacheDirectory, type)] = new PluginBinaryStorage(cacheName, cacheDirectory);
+
+ await ((PluginBinaryStorage)_pluginBinaryStorages[(cacheName, cacheDirectory, type)]).SaveAsync();
+ }
+
#endregion
#region Private Methods
From 0496d6c04ac2bed323060f41519c41fe1358dc73 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 14:21:29 +0800
Subject: [PATCH 0795/1335] Use api functions for Program plugin
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 82 +++++++++----------
.../Programs/UWPPackage.cs | 2 +-
.../Programs/Win32.cs | 2 +-
.../Views/ProgramSetting.xaml.cs | 6 +-
4 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 3be23214c86..5bc518105cf 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -8,7 +8,6 @@
using System.Windows.Controls;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
@@ -19,19 +18,17 @@
namespace Flow.Launcher.Plugin.Program
{
- public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable,
- IDisposable
+ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, IAsyncReloadable, IDisposable
{
- internal static Win32[] _win32s { get; set; }
- internal static UWPApp[] _uwps { get; set; }
- internal static Settings _settings { get; set; }
+ private const string Win32CacheName = "Win32";
+ private const string UwpCacheName = "UWP";
+ internal static List _win32s { get; private set; }
+ internal static List _uwps { get; private set; }
+ internal static Settings _settings { get; private set; }
internal static PluginInitContext Context { get; private set; }
- private static BinaryStorage _win32Storage;
- private static BinaryStorage _uwpStorage;
-
private static readonly List emptyResults = new();
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
@@ -81,12 +78,6 @@ static Main()
{
}
- public void Save()
- {
- _win32Storage.SaveAsync(_win32s);
- _uwpStorage.SaveAsync(_uwps);
- }
-
public async Task> QueryAsync(Query query, CancellationToken token)
{
var result = await cache.GetOrCreateAsync(query.Search, async entry =>
@@ -191,7 +182,9 @@ public async Task InitAsync(PluginInitContext context)
await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
{
- Helper.ValidateDirectory(Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
+ var pluginCachePath = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
+
+ Helper.ValidateDirectory(pluginCachePath);
static void MoveFile(string sourcePath, string destinationPath)
{
@@ -236,20 +229,18 @@ static void MoveFile(string sourcePath, string destinationPath)
}
// Move old cache files to the new cache directory
- var oldWin32CacheFile = Path.Combine(DataLocation.CacheDirectory, $"Win32.cache");
- var newWin32CacheFile = Path.Combine(Context.CurrentPluginMetadata.PluginCacheDirectoryPath, $"Win32.cache");
+ var oldWin32CacheFile = Path.Combine(DataLocation.CacheDirectory, $"{Win32CacheName}.cache");
+ var newWin32CacheFile = Path.Combine(pluginCachePath, $"{Win32CacheName}.cache");
MoveFile(oldWin32CacheFile, newWin32CacheFile);
- var oldUWPCacheFile = Path.Combine(DataLocation.CacheDirectory, $"UWP.cache");
- var newUWPCacheFile = Path.Combine(Context.CurrentPluginMetadata.PluginCacheDirectoryPath, $"UWP.cache");
+ var oldUWPCacheFile = Path.Combine(DataLocation.CacheDirectory, $"{UwpCacheName}.cache");
+ var newUWPCacheFile = Path.Combine(pluginCachePath, $"{UwpCacheName}.cache");
MoveFile(oldUWPCacheFile, newUWPCacheFile);
- _win32Storage = new BinaryStorage("Win32", Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
- _win32s = await _win32Storage.TryLoadAsync(Array.Empty());
- _uwpStorage = new BinaryStorage("UWP", Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
- _uwps = await _uwpStorage.TryLoadAsync(Array.Empty());
+ _win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCachePath, new List());
+ _uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCachePath, new List());
});
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Length}>");
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwps.Length}>");
+ Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Count}>");
+ Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwps.Count}>");
bool cacheEmpty = !_win32s.Any() || !_uwps.Any();
@@ -273,36 +264,45 @@ static void WatchProgramUpdate()
}
}
- public static void IndexWin32Programs()
+ public static async Task IndexWin32ProgramsAsync()
{
var win32S = Win32.All(_settings);
- _win32s = win32S;
+ _win32s.Clear();
+ foreach (var win32 in win32S)
+ {
+ _win32s.Add(win32);
+ }
ResetCache();
- _win32Storage.SaveAsync(_win32s);
+ await Context.API.SaveCacheBinaryStorageAsync>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
}
- public static void IndexUwpPrograms()
+ public static async Task IndexUwpProgramsAsync()
{
- var applications = UWPPackage.All(_settings);
- _uwps = applications;
+ var uwps = UWPPackage.All(_settings);
+ _uwps.Clear();
+ foreach (var uwp in uwps)
+ {
+ _uwps.Add(uwp);
+ }
ResetCache();
- _uwpStorage.SaveAsync(_uwps);
+ await Context.API.SaveCacheBinaryStorageAsync>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
}
public static async Task IndexProgramsAsync()
{
- var a = Task.Run(() =>
+ var win32Task = Task.Run(async () =>
{
- Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs);
+ await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32ProgramsAsync);
});
- var b = Task.Run(() =>
+ var uwpTask = Task.Run(async () =>
{
- Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|UWPProgram index cost", IndexUwpPrograms);
+ await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|UWPProgram index cost", IndexUwpProgramsAsync);
});
- await Task.WhenAll(a, b).ConfigureAwait(false);
+
+ await Task.WhenAll(win32Task, uwpTask).ConfigureAwait(false);
}
internal static void ResetCache()
@@ -314,7 +314,7 @@ internal static void ResetCache()
public Control CreateSettingPanel()
{
- return new ProgramSetting(Context, _settings, _win32s, _uwps);
+ return new ProgramSetting(Context, _settings);
}
public string GetTranslatedPluginTitle()
@@ -370,7 +370,7 @@ private static void DisableProgram(IProgram programToDelete)
_settings.DisabledProgramSources.Add(new ProgramSource(program));
_ = Task.Run(() =>
{
- IndexUwpPrograms();
+ _ = IndexUwpProgramsAsync();
});
}
else if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
@@ -380,7 +380,7 @@ private static void DisableProgram(IProgram programToDelete)
_settings.DisabledProgramSources.Add(new ProgramSource(program));
_ = Task.Run(() =>
{
- IndexWin32Programs();
+ _ = IndexWin32ProgramsAsync();
});
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
index 654897cc57f..bf100ed7ee3 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
@@ -317,7 +317,7 @@ public static async Task WatchPackageChange()
{
await Task.Delay(3000).ConfigureAwait(false);
PackageChangeChannel.Reader.TryRead(out _);
- await Task.Run(Main.IndexUwpPrograms);
+ await Task.Run(Main.IndexUwpProgramsAsync);
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
index a64a708efd3..06be2a628cf 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
@@ -797,7 +797,7 @@ public static async Task MonitorDirectoryChangeAsync()
{
}
- await Task.Run(Main.IndexWin32Programs);
+ await Task.Run(Main.IndexWin32ProgramsAsync);
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 91864cb680c..5ad7fcea369 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -18,8 +18,8 @@ namespace Flow.Launcher.Plugin.Program.Views
///
public partial class ProgramSetting : UserControl
{
- private PluginInitContext context;
- private Settings _settings;
+ private readonly PluginInitContext context;
+ private readonly Settings _settings;
private GridViewColumnHeader _lastHeaderClicked;
private ListSortDirection _lastDirection;
@@ -109,7 +109,7 @@ public bool EnableUWP
public bool ShowUWPCheckbox => UWPPackage.SupportUWP();
- public ProgramSetting(PluginInitContext context, Settings settings, Win32[] win32s, UWPApp[] uwps)
+ public ProgramSetting(PluginInitContext context, Settings settings)
{
this.context = context;
_settings = settings;
From 68e1fc28efcc31362193aab4e73aa7459bf1b1af Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 14:35:43 +0800
Subject: [PATCH 0796/1335] Use try remove for safety
---
Flow.Launcher/PublicAPIInstance.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 17d7e103e9a..77019555082 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -201,7 +201,7 @@ public void RemovePluginSettings(string assemblyName)
var name = value.GetType().GetField("AssemblyName")?.GetValue(value)?.ToString();
if (name == assemblyName)
{
- _pluginJsonStorages.Remove(key, out var pluginJsonStorage);
+ _pluginJsonStorages.TryRemove(key, out var pluginJsonStorage);
}
}
}
@@ -344,7 +344,7 @@ public void RemovePluginCache(string cacheDirectory)
var currentCacheDirectory = key.Item2;
if (cacheDirectory == currentCacheDirectory)
{
- _pluginBinaryStorages.Remove(key, out var _);
+ _pluginBinaryStorages.TryRemove(key, out var _);
}
}
}
From 8e8b5dbbba6d45c9304b556c022fe2ebf277ed5d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 19:18:32 +0800
Subject: [PATCH 0797/1335] Code quality
---
.../ViewModels/SettingsPaneAboutViewModel.cs | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 20f905411d2..07e9fba1edd 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -6,7 +6,6 @@
using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -24,7 +23,7 @@ public string LogFolderSize
get
{
var size = GetLogFiles().Sum(file => file.Length);
- return $"{InternationalizationManager.Instance.GetTranslation("clearlogfolder")} ({BytesToReadableString(size)})";
+ return $"{App.API.GetTranslation("clearlogfolder")} ({BytesToReadableString(size)})";
}
}
@@ -42,7 +41,7 @@ public string LogFolderSize
};
public string ActivatedTimes => string.Format(
- InternationalizationManager.Instance.GetTranslation("about_activate_times"),
+ App.API.GetTranslation("about_activate_times"),
_settings.ActivateTimes
);
@@ -88,8 +87,8 @@ private void OpenWelcomeWindow()
private void AskClearLogFolderConfirmation()
{
var confirmResult = App.API.ShowMsgBox(
- InternationalizationManager.Instance.GetTranslation("clearlogfolderMessage"),
- InternationalizationManager.Instance.GetTranslation("clearlogfolder"),
+ App.API.GetTranslation("clearlogfolderMessage"),
+ App.API.GetTranslation("clearlogfolder"),
MessageBoxButton.YesNo
);
@@ -121,7 +120,7 @@ private void OpenLogsFolder()
}
[RelayCommand]
- private Task UpdateApp() => _updater.UpdateAppAsync(false);
+ private Task UpdateAppAsync() => _updater.UpdateAppAsync(false);
private void ClearLogFolder()
{
From 482fdc939f9fd01dfdd4b75f485e30768c43e63d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 1 Apr 2025 20:12:27 +0800
Subject: [PATCH 0798/1335] Add clean cache option
---
Flow.Launcher/Languages/en.xaml | 2 +
.../ViewModels/SettingsPaneAboutViewModel.cs | 49 ++++++++++++++++++-
.../SettingPages/Views/SettingsPaneAbout.xaml | 4 ++
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 2df430c3b67..6963d81c955 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -325,6 +325,8 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Clear Caches
+ Are you sure you want to delete all caches?
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 07e9fba1edd..47cb1b6c388 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -27,6 +27,15 @@ public string LogFolderSize
}
}
+ public string CacheFolderSize
+ {
+ get
+ {
+ var size = GetCacheFiles().Sum(file => file.Length);
+ return $"{App.API.GetTranslation("clearcachefolder")} ({BytesToReadableString(size)})";
+ }
+ }
+
public string Website => Constant.Website;
public string SponsorPage => Constant.SponsorPage;
public string ReleaseNotes => _updater.GitHubRepository + "/releases/latest";
@@ -98,6 +107,21 @@ private void AskClearLogFolderConfirmation()
}
}
+ [RelayCommand]
+ private void AskClearCacheFolderConfirmation()
+ {
+ var confirmResult = App.API.ShowMsgBox(
+ App.API.GetTranslation("clearcachefolderMessage"),
+ App.API.GetTranslation("clearcachefolder"),
+ MessageBoxButton.YesNo
+ );
+
+ if (confirmResult == MessageBoxResult.Yes)
+ {
+ ClearCacheFolder();
+ }
+ }
+
[RelayCommand]
private void OpenSettingsFolder()
{
@@ -112,7 +136,6 @@ private void OpenParentOfSettingsFolder(object parameter)
App.API.OpenDirectory(parentFolderPath);
}
-
[RelayCommand]
private void OpenLogsFolder()
{
@@ -147,6 +170,30 @@ private static List GetLogFiles(string version = "")
return GetLogDir(version).EnumerateFiles("*", SearchOption.AllDirectories).ToList();
}
+ private void ClearCacheFolder()
+ {
+ var cacheDirectory = GetCacheDir();
+ var cacheFiles = GetCacheFiles();
+
+ cacheFiles.ForEach(f => f.Delete());
+
+ cacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
+ .ToList()
+ .ForEach(dir => dir.Delete(true));
+
+ OnPropertyChanged(nameof(CacheFolderSize));
+ }
+
+ private static DirectoryInfo GetCacheDir()
+ {
+ return new DirectoryInfo(DataLocation.CacheDirectory);
+ }
+
+ private static List GetCacheFiles()
+ {
+ return GetCacheDir().EnumerateFiles("*", SearchOption.AllDirectories).ToList();
+ }
+
private static string BytesToReadableString(long bytes)
{
const int scale = 1024;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index 75c51341133..f7deee7cfdc 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -90,6 +90,10 @@
Margin="0 12 0 0"
Icon="">
+
Date: Tue, 1 Apr 2025 20:54:36 +0800
Subject: [PATCH 0799/1335] Add exception handler
---
Flow.Launcher/Languages/en.xaml | 1 +
.../ViewModels/SettingsPaneAboutViewModel.cs | 23 +++++++++++++++----
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 6963d81c955..f96509bde2a 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -327,6 +327,7 @@
Are you sure you want to delete all logs?
Clear Caches
Are you sure you want to delete all caches?
+ Failed to clear folders and files
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 47cb1b6c388..1cd90e613c9 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -103,7 +103,15 @@ private void AskClearLogFolderConfirmation()
if (confirmResult == MessageBoxResult.Yes)
{
- ClearLogFolder();
+ try
+ {
+ ClearLogFolder();
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(nameof(SettingsPaneAboutViewModel), "Failed to clear log folder", e);
+ App.API.ShowMsgBox(App.API.GetTranslation("clearfolderfailMessage"));
+ }
}
}
@@ -118,7 +126,15 @@ private void AskClearCacheFolderConfirmation()
if (confirmResult == MessageBoxResult.Yes)
{
- ClearCacheFolder();
+ try
+ {
+ ClearCacheFolder();
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(nameof(SettingsPaneAboutViewModel), "Failed to clear cache folder", e);
+ App.API.ShowMsgBox(App.API.GetTranslation("clearfolderfailMessage"));
+ }
}
}
@@ -202,8 +218,7 @@ private static string BytesToReadableString(long bytes)
foreach (string order in orders)
{
- if (bytes > max)
- return $"{decimal.Divide(bytes, max):##.##} {order}";
+ if (bytes > max) return $"{decimal.Divide(bytes, max):##.##} {order}";
max /= scale;
}
From 84510854aeb7b2d365780a31dfc3ab83047e8b20 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 10:11:16 +0800
Subject: [PATCH 0800/1335] Improve exception handler
---
Flow.Launcher/Languages/en.xaml | 2 +-
.../ViewModels/SettingsPaneAboutViewModel.cs | 79 ++++++++++++++-----
2 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f96509bde2a..24ab3cf9477 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -327,7 +327,7 @@
Are you sure you want to delete all logs?
Clear Caches
Are you sure you want to delete all caches?
- Failed to clear folders and files
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 1cd90e613c9..e0530bb8384 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -15,6 +15,8 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneAboutViewModel : BaseModel
{
+ private static readonly string ClassName = nameof(SettingsPaneAboutViewModel);
+
private readonly Settings _settings;
private readonly Updater _updater;
@@ -103,13 +105,8 @@ private void AskClearLogFolderConfirmation()
if (confirmResult == MessageBoxResult.Yes)
{
- try
+ if (!ClearLogFolder())
{
- ClearLogFolder();
- }
- catch (Exception e)
- {
- App.API.LogException(nameof(SettingsPaneAboutViewModel), "Failed to clear log folder", e);
App.API.ShowMsgBox(App.API.GetTranslation("clearfolderfailMessage"));
}
}
@@ -126,13 +123,8 @@ private void AskClearCacheFolderConfirmation()
if (confirmResult == MessageBoxResult.Yes)
{
- try
- {
- ClearCacheFolder();
- }
- catch (Exception e)
+ if (!ClearCacheFolder())
{
- App.API.LogException(nameof(SettingsPaneAboutViewModel), "Failed to clear cache folder", e);
App.API.ShowMsgBox(App.API.GetTranslation("clearfolderfailMessage"));
}
}
@@ -161,19 +153,45 @@ private void OpenLogsFolder()
[RelayCommand]
private Task UpdateAppAsync() => _updater.UpdateAppAsync(false);
- private void ClearLogFolder()
+ private bool ClearLogFolder()
{
+ var success = true;
var logDirectory = GetLogDir();
var logFiles = GetLogFiles();
- logFiles.ForEach(f => f.Delete());
+ logFiles.ForEach(f =>
+ {
+ try
+ {
+ f.Delete();
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete log file: {f.Name}", e);
+ success = false;
+ }
+ });
logDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
+ // Do not clean log files of current version
.Where(dir => !Constant.Version.Equals(dir.Name))
.ToList()
- .ForEach(dir => dir.Delete());
+ .ForEach(dir =>
+ {
+ try
+ {
+ dir.Delete();
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete log directory: {dir.Name}", e);
+ success = false;
+ }
+ });
OnPropertyChanged(nameof(LogFolderSize));
+
+ return success;
}
private static DirectoryInfo GetLogDir(string version = "")
@@ -186,18 +204,43 @@ private static List GetLogFiles(string version = "")
return GetLogDir(version).EnumerateFiles("*", SearchOption.AllDirectories).ToList();
}
- private void ClearCacheFolder()
+ private bool ClearCacheFolder()
{
+ var success = true;
var cacheDirectory = GetCacheDir();
var cacheFiles = GetCacheFiles();
- cacheFiles.ForEach(f => f.Delete());
+ cacheFiles.ForEach(f =>
+ {
+ try
+ {
+ f.Delete();
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete cache file: {f.Name}", e);
+ success = false;
+ }
+ });
cacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
.ToList()
- .ForEach(dir => dir.Delete(true));
+ .ForEach(dir =>
+ {
+ try
+ {
+ dir.Delete(true);
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
+ success = false;
+ }
+ });
OnPropertyChanged(nameof(CacheFolderSize));
+
+ return success;
}
private static DirectoryInfo GetCacheDir()
From 7fc453330f08f33c8a87bbdc5cc5d1f7c38b2484 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 10:12:59 +0800
Subject: [PATCH 0801/1335] Recrusive delete log folders
---
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index e0530bb8384..6cfb9830656 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -180,7 +180,7 @@ private bool ClearLogFolder()
{
try
{
- dir.Delete();
+ dir.Delete(true);
}
catch (Exception e)
{
From 53c12327c0bcce76b770273c6a95f2c15ed0d27b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 11:51:34 +0800
Subject: [PATCH 0802/1335] Revert changes
---
Flow.Launcher.Infrastructure/Logger/Log.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs
index 84331ef702e..807d631c704 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -135,14 +135,12 @@ private static string CheckClassAndMessageAndReturnFullClassWithMethod(string cl
return className;
}
-#if !DEBUG
private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
{
var logger = LogManager.GetLogger(classAndMethod);
logger.Error(e, message);
}
-#endif
private static void LogInternal(string message, LogLevel level)
{
From 5165ce8f2a5d11f3b81f3feb37887e03f4c6677f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:22:36 +0800
Subject: [PATCH 0803/1335] Add LoadImageAsync api function
---
.../Image/ImageLoader.cs | 14 ++++++++------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 16 ++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 4 ++++
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 6f7b1cd908d..4bd4c29c81e 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -277,7 +277,7 @@ public static bool TryGetValue(string path, bool loadFullImage, out ImageSource
return ImageCache.TryGetValue(path, loadFullImage, out image);
}
- public static async ValueTask LoadAsync(string path, bool loadFullImage = false)
+ public static async ValueTask LoadAsync(string path, bool loadFullImage = false, bool cacheImage = true)
{
var imageResult = await LoadInternalAsync(path, loadFullImage);
@@ -293,16 +293,18 @@ public static async ValueTask LoadAsync(string path, bool loadFullI
// image already exists
img = ImageCache[key, loadFullImage] ?? img;
}
- else
+ else if (cacheImage)
{
- // new guid
-
+ // save guid key
GuidToKey[hash] = path;
}
}
- // update cache
- ImageCache[path, loadFullImage] = img;
+ if (cacheImage)
+ {
+ // update cache
+ ImageCache[path, loadFullImage] = img;
+ }
}
return img;
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index f178ebb90d4..fb80ede837d 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Media;
namespace Flow.Launcher.Plugin
{
@@ -344,5 +345,20 @@ public interface IPublicAPI
/// Stop the loading bar in main window
///
public void StopLoadingBar();
+
+ ///
+ /// Load image from path. Support local, remote and data:image url.
+ /// If image path is missing, it will retun a missing icon.
+ ///
+ /// The path of the image.
+ ///
+ /// Load full image or not.
+ ///
+ ///
+ /// Cache the image or not. Cached image will be stored in FL cache.
+ /// If the image is just used one time, it's better to set this to false.
+ ///
+ ///
+ ValueTask LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e19ad2fdcd4..d12c6ac3edf 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -10,6 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Squirrel;
using Flow.Launcher.Core;
@@ -342,6 +343,9 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
+ public ValueTask LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true) =>
+ ImageLoader.LoadAsync(path, loadFullImage, cacheImage);
+
#endregion
#region Private Methods
From f76110856fdc1c104d3dc1c5a888073b1ac3f413 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:25:06 +0800
Subject: [PATCH 0804/1335] Use api function in main project
---
Flow.Launcher/MessageBoxEx.xaml.cs | 2 +-
Flow.Launcher/Msg.xaml.cs | 6 +++---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
Flow.Launcher/ViewModel/ResultViewModel.cs | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/MessageBoxEx.xaml.cs b/Flow.Launcher/MessageBoxEx.xaml.cs
index e9b434fd97b..3d94769d002 100644
--- a/Flow.Launcher/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher/MessageBoxEx.xaml.cs
@@ -156,7 +156,7 @@ private static async Task SetImageOfMessageBoxAsync(MessageBoxImage icon)
private async Task SetImageAsync(string imageName)
{
var imagePath = Path.Combine(Constant.ProgramDirectory, "Images", imageName);
- var imageSource = await ImageLoader.LoadAsync(imagePath);
+ var imageSource = await App.API.LoadImageAsync(imagePath);
Img.Source = imageSource;
}
diff --git a/Flow.Launcher/Msg.xaml.cs b/Flow.Launcher/Msg.xaml.cs
index 94184ff6377..ff9accd62f2 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -43,7 +43,7 @@ public Msg()
private async System.Threading.Tasks.Task LoadImageAsync()
{
- imgClose.Source = await ImageLoader.LoadAsync(Path.Combine(Infrastructure.Constant.ProgramDirectory, "Images\\close.png"));
+ imgClose.Source = await App.API.LoadImageAsync(Path.Combine(Constant.ProgramDirectory, "Images\\close.png"));
}
void imgClose_MouseUp(object sender, MouseButtonEventArgs e)
@@ -71,11 +71,11 @@ public async void Show(string title, string subTitle, string iconPath)
if (!File.Exists(iconPath))
{
- imgIco.Source = await ImageLoader.LoadAsync(Path.Combine(Constant.ProgramDirectory, "Images\\app.png"));
+ imgIco.Source = await App.API.LoadImageAsync(Path.Combine(Constant.ProgramDirectory, "Images\\app.png"));
}
else
{
- imgIco.Source = await ImageLoader.LoadAsync(iconPath);
+ imgIco.Source = await App.API.LoadImageAsync(iconPath);
}
Show();
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 17e4b55b71e..bfa5bd5042a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1168,7 +1168,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
else if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
- PluginIconSource = await ImageLoader.LoadAsync(PluginIconPath);
+ PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
SearchIconVisibility = Visibility.Hidden;
}
else
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index e91badb3894..93a595de41e 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -45,7 +45,7 @@ private static string PluginManagerActionKeyword
private async Task LoadIconAsync()
{
- Image = await ImageLoader.LoadAsync(PluginPair.Metadata.IcoPath);
+ Image = await App.API.LoadImageAsync(PluginPair.Metadata.IcoPath);
OnPropertyChanged(nameof(Image));
}
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index db124e0788a..9aab71a328e 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -199,7 +199,7 @@ private async Task LoadImageInternalAsync(string imagePath, Result.
}
}
- return await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false);
+ return await App.API.LoadImageAsync(imagePath, loadFullImage).ConfigureAwait(false);
}
private async Task LoadImageAsync()
From 4572068e768921e0834c53f6f4192c71ae762c04 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:25:28 +0800
Subject: [PATCH 0805/1335] Use api functions in plugin projects
---
.../Views/PreviewPanel.xaml.cs | 3 +--
.../SearchSourceViewModel.cs | 9 ++++-----
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 878832e4fb8..aaf1efdc1fd 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -7,7 +7,6 @@
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
-using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Plugin.Explorer.Search;
namespace Flow.Launcher.Plugin.Explorer.Views;
@@ -89,7 +88,7 @@ public PreviewPanel(Settings settings, string filePath)
private async Task LoadImageAsync()
{
- PreviewImage = await ImageLoader.LoadAsync(FilePath, true).ConfigureAwait(false);
+ PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
public event PropertyChangedEventHandler? PropertyChanged;
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
index 9c5e81cb537..6554edd837b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceViewModel.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Infrastructure.Image;
-using System;
+using System;
using System.IO;
using System.Threading.Tasks;
#pragma warning disable IDE0005
@@ -41,8 +40,8 @@ public void CopyNewImageToUserDataDirectoryIfRequired(
#if DEBUG
throw;
#else
- Main._context.API.ShowMsgBox(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
- UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
+ Main._context.API.ShowMsgBox(string.Format("Copying the selected image file to {0} has failed, changes will now be reverted", destinationFileNameFullPath));
+ UpdateIconAttributes(selectedSearchSource, fullPathToOriginalImage);
#endif
}
}
@@ -61,7 +60,7 @@ internal bool ShouldProvideHint(string fullPathToSelectedImage)
internal async ValueTask LoadPreviewIconAsync(string pathToPreviewIconImage)
{
- return await ImageLoader.LoadAsync(pathToPreviewIconImage);
+ return await Main._context.API.LoadImageAsync(pathToPreviewIconImage);
}
}
}
From 3de8005297fcba6e517ea674e3b2dc1129aea8e8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:26:22 +0800
Subject: [PATCH 0806/1335] Improve WebSearch project code quality
---
.../SuggestionSources/Baidu.cs | 8 +++-----
.../SuggestionSources/Bing.cs | 16 +++++-----------
.../SuggestionSources/DuckDuckGo.cs | 8 +++-----
.../SuggestionSources/Google.cs | 8 +++-----
4 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
index 51f81b718f5..590666af711 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
@@ -4,8 +4,6 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
@@ -22,11 +20,11 @@ public override async Task> SuggestionsAsync(string query, Cancella
try
{
const string api = "http://suggestion.baidu.com/su?json=1&wd=";
- result = await Http.GetAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
+ result = await Main._context.API.HttpGetStringAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Baidu), "Can't get suggestion from baidu", e);
return null;
}
@@ -41,7 +39,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (JsonException e)
{
- Log.Exception("|Baidu.Suggestions|can't parse suggestions", e);
+ Main._context.API.LogException(nameof(Baidu), "Can't parse suggestions", e);
return new List();
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
index 640674243e2..938f7d387c9 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
@@ -1,6 +1,4 @@
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
-using System;
+using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
@@ -10,16 +8,15 @@
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
- class Bing : SuggestionSource
+ public class Bing : SuggestionSource
{
public override async Task> SuggestionsAsync(string query, CancellationToken token)
{
-
try
{
const string api = "https://api.bing.com/qsonhs.aspx?q=";
- await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
+ await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token).ConfigureAwait(false);
using var json = (await JsonDocument.ParseAsync(resultStream, cancellationToken: token));
var root = json.RootElement.GetProperty("AS");
@@ -33,18 +30,15 @@ public override async Task> SuggestionsAsync(string query, Cancella
.EnumerateArray()
.Select(s => s.GetProperty("Txt").GetString()))
.ToList();
-
-
-
}
catch (Exception e) when (e is HttpRequestException or { InnerException: TimeoutException })
{
- Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Bing), "Can't get suggestion from baidu", e);
return null;
}
catch (JsonException e)
{
- Log.Exception("|Bing.Suggestions|can't parse suggestions", e);
+ Main._context.API.LogException(nameof(Bing), "Can't parse suggestions", e);
return new List();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
index 8fafb44cce1..1d248caf37a 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
using System.Text.Json;
@@ -25,7 +23,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
{
const string api = "https://duckduckgo.com/ac/?type=list&q=";
- await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
+ await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);
@@ -36,12 +34,12 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Log.Exception("|DuckDuckGo.Suggestions|Can't get suggestion from DuckDuckGo", e);
+ Main._context.API.LogException(nameof(DuckDuckGo), "Can't get suggestion from DuckDuckGo", e);
return null;
}
catch (JsonException e)
{
- Log.Exception("|DuckDuckGo.Suggestions|can't parse suggestions", e);
+ Main._context.API.LogException(nameof(DuckDuckGo), "Can't parse suggestions", e);
return new List();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
index 265de4a982c..5f2504009b0 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
using System.Text.Json;
@@ -18,7 +16,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
{
const string api = "https://www.google.com/complete/search?output=chrome&q=";
- await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
+ await using var resultStream = await Main._context.API.HttpGetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);
using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);
@@ -29,12 +27,12 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Google), "Can't get suggestion from baidu", e);
return null;
}
catch (JsonException e)
{
- Log.Exception("|Google.Suggestions|can't parse suggestions", e);
+ Main._context.API.LogException(nameof(Google), "Can't parse suggestions", e);
return new List();
}
}
From f9a01e10025563e069c3caafce85b80e89d60d2f Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:34:04 +0800
Subject: [PATCH 0807/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index fb80ede837d..0ee576b2e35 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -348,7 +348,7 @@ public interface IPublicAPI
///
/// Load image from path. Support local, remote and data:image url.
- /// If image path is missing, it will retun a missing icon.
+ /// If image path is missing, it will return a missing icon.
///
/// The path of the image.
///
From 15a7e3a5afd8af4a9139935fd376d963963fb66b Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:35:03 +0800
Subject: [PATCH 0808/1335] Fix log typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
index 938f7d387c9..9efc36263c2 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
@@ -33,7 +33,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or { InnerException: TimeoutException })
{
- Main._context.API.LogException(nameof(Bing), "Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Bing), "Can't get suggestion from Bing", e);
return null;
}
catch (JsonException e)
From a33ecdbb971869605c4e8c03b5a0a00465040bd4 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:35:27 +0800
Subject: [PATCH 0809/1335] Fix log typos
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
.../Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
index 5f2504009b0..ad8fb508f09 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
@@ -27,7 +27,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Main._context.API.LogException(nameof(Google), "Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Google), "Can't get suggestion from Google", e);
return null;
}
catch (JsonException e)
From e6a8fe3523b7c810faebf2b2235e1322884c0696 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 18:36:25 +0800
Subject: [PATCH 0810/1335] Use caption letter
---
.../Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
index 590666af711..65be06b53ee 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
@@ -24,7 +24,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Main._context.API.LogException(nameof(Baidu), "Can't get suggestion from baidu", e);
+ Main._context.API.LogException(nameof(Baidu), "Can't get suggestion from Baidu", e);
return null;
}
From b62c19e28b0fd8063dc3004dc21a7c840162d3b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 19:30:15 +0800
Subject: [PATCH 0811/1335] Move format function position
---
Flow.Launcher.Core/Updater.cs | 13 ++++++++++++-
Flow.Launcher.Infrastructure/Helper.cs | 22 ----------------------
2 files changed, 12 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 9a77ece3253..96efcacf600 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -17,6 +17,7 @@
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
+using System.Text.Json;
namespace Flow.Launcher.Core
{
@@ -51,7 +52,7 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString());
var currentVersion = Version.Parse(Constant.Version);
- Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.FutureReleaseEntry.Formatted()}>");
+ Log.Info($"|Updater.UpdateApp|Future Release <{Formatted(newUpdateInfo.FutureReleaseEntry)}>");
if (newReleaseVersion <= currentVersion)
{
@@ -151,5 +152,15 @@ public string NewVersionTips(string version)
return tips;
}
+
+ private static string Formatted(T t)
+ {
+ var formatted = JsonSerializer.Serialize(t, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
+
+ return formatted;
+ }
}
}
diff --git a/Flow.Launcher.Infrastructure/Helper.cs b/Flow.Launcher.Infrastructure/Helper.cs
index 864d796c7bb..c393c401684 100644
--- a/Flow.Launcher.Infrastructure/Helper.cs
+++ b/Flow.Launcher.Infrastructure/Helper.cs
@@ -2,18 +2,11 @@
using System;
using System.IO;
-using System.Text.Json;
-using System.Text.Json.Serialization;
namespace Flow.Launcher.Infrastructure
{
public static class Helper
{
- static Helper()
- {
- jsonFormattedSerializerOptions.Converters.Add(new JsonStringEnumConverter());
- }
-
///
/// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
///
@@ -71,20 +64,5 @@ public static void ValidateDirectory(string path)
Directory.CreateDirectory(path);
}
}
-
- private static readonly JsonSerializerOptions jsonFormattedSerializerOptions = new JsonSerializerOptions
- {
- WriteIndented = true
- };
-
- public static string Formatted(this T t)
- {
- var formatted = JsonSerializer.Serialize(t, new JsonSerializerOptions
- {
- WriteIndented = true
- });
-
- return formatted;
- }
}
}
From 44ba60cdfcd58785456c8fcb61a203197005daa5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 20:17:32 +0800
Subject: [PATCH 0812/1335] Move ValidateDirectory functions to FileFolders for
plugin usage
---
Flow.Launcher.Infrastructure/Helper.cs | 36 ---------------
.../Storage/BinaryStorage.cs | 3 +-
.../Storage/FlowLauncherJsonStorage.cs | 5 +-
.../Storage/JsonStorage.cs | 3 +-
.../Storage/PluginJsonStorage.cs | 3 +-
.../SharedCommands/FilesFolders.cs | 46 +++++++++++++++++++
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 4 +-
.../Flow.Launcher.Plugin.WebSearch/Main.cs | 3 +-
8 files changed, 58 insertions(+), 45 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Helper.cs b/Flow.Launcher.Infrastructure/Helper.cs
index c393c401684..b02d84ca7fc 100644
--- a/Flow.Launcher.Infrastructure/Helper.cs
+++ b/Flow.Launcher.Infrastructure/Helper.cs
@@ -1,7 +1,6 @@
#nullable enable
using System;
-using System.IO;
namespace Flow.Launcher.Infrastructure
{
@@ -29,40 +28,5 @@ public static void RequireNonNull(this T obj)
throw new NullReferenceException();
}
}
-
- public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
- {
- if (!Directory.Exists(dataDirectory))
- {
- Directory.CreateDirectory(dataDirectory);
- }
-
- foreach (var bundledDataPath in Directory.GetFiles(bundledDataDirectory))
- {
- var data = Path.GetFileName(bundledDataPath);
- var dataPath = Path.Combine(dataDirectory, data.NonNull());
- if (!File.Exists(dataPath))
- {
- File.Copy(bundledDataPath, dataPath);
- }
- else
- {
- var time1 = new FileInfo(bundledDataPath).LastWriteTimeUtc;
- var time2 = new FileInfo(dataPath).LastWriteTimeUtc;
- if (time1 != time2)
- {
- File.Copy(bundledDataPath, dataPath, true);
- }
- }
- }
- }
-
- public static void ValidateDirectory(string path)
- {
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
- }
}
}
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 5b73faae6a6..a8d5f5d6218 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin.SharedCommands;
using MemoryPack;
namespace Flow.Launcher.Infrastructure.Storage
@@ -21,7 +22,7 @@ public class BinaryStorage
public BinaryStorage(string filename, string directoryPath = null)
{
directoryPath ??= DataLocation.CacheDirectory;
- Helper.ValidateDirectory(directoryPath);
+ FilesFolders.ValidateDirectory(directoryPath);
FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
}
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index 865041fb397..3669bb405ea 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -1,5 +1,6 @@
using System.IO;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
@@ -8,10 +9,10 @@ namespace Flow.Launcher.Infrastructure.Storage
public FlowLauncherJsonStorage()
{
var directoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName);
- Helper.ValidateDirectory(directoryPath);
+ FilesFolders.ValidateDirectory(directoryPath);
var filename = typeof(T).Name;
FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 40106acd829..a3488124b92 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -5,6 +5,7 @@
using System.Text.Json;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
@@ -37,7 +38,7 @@ public JsonStorage(string filePath)
FilePath = filePath;
DirectoryPath = Path.GetDirectoryName(filePath) ?? throw new ArgumentException("Invalid file path");
- Helper.ValidateDirectory(DirectoryPath);
+ FilesFolders.ValidateDirectory(DirectoryPath);
}
public async Task LoadAsync()
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index b377c81aa14..cc78bb8f6dc 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -1,5 +1,6 @@
using System.IO;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
@@ -14,7 +15,7 @@ public PluginJsonStorage()
var dataType = typeof(T);
AssemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, AssemblyName);
- Helper.ValidateDirectory(DirectoryPath);
+ FilesFolders.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
}
diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
index 5f003e351dc..1de5841a530 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -318,5 +318,51 @@ public static string EnsureTrailingSlash(this string path)
{
return path.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
}
+
+ ///
+ /// Validates a directory, creating it if it doesn't exist
+ ///
+ ///
+ public static void ValidateDirectory(string path)
+ {
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+ }
+
+ ///
+ /// Validates a data directory, synchronizing it by ensuring all files from a bundled source directory exist in it.
+ /// If files are missing or outdated, they are copied from the bundled directory to the data directory.
+ ///
+ ///
+ ///
+ public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
+ {
+ if (!Directory.Exists(dataDirectory))
+ {
+ Directory.CreateDirectory(dataDirectory);
+ }
+
+ foreach (var bundledDataPath in Directory.GetFiles(bundledDataDirectory))
+ {
+ var data = Path.GetFileName(bundledDataPath);
+ if (data == null) continue;
+ var dataPath = Path.Combine(dataDirectory, data);
+ if (!File.Exists(dataPath))
+ {
+ File.Copy(bundledDataPath, dataPath);
+ }
+ else
+ {
+ var time1 = new FileInfo(bundledDataPath).LastWriteTimeUtc;
+ var time2 = new FileInfo(dataPath).LastWriteTimeUtc;
+ if (time1 != time2)
+ {
+ File.Copy(bundledDataPath, dataPath, true);
+ }
+ }
+ }
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 3be23214c86..73b4ae9e65c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,13 +6,13 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
using Flow.Launcher.Plugin.Program.Views.Models;
+using Flow.Launcher.Plugin.SharedCommands;
using Microsoft.Extensions.Caching.Memory;
using Path = System.IO.Path;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
@@ -191,7 +191,7 @@ public async Task InitAsync(PluginInitContext context)
await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
{
- Helper.ValidateDirectory(Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
+ FilesFolders.ValidateDirectory(Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
static void MoveFile(string sourcePath, string destinationPath)
{
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
index 7ad9715bbd8..76aeb3250b1 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs
@@ -5,7 +5,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.WebSearch
@@ -180,7 +179,7 @@ void Init()
// Default images directory is in the WebSearch's application folder
DefaultImagesDirectory = Path.Combine(pluginDirectory, Images);
- Helper.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
+ FilesFolders.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
// Custom images directory is in the WebSearch's data location folder
CustomImagesDirectory = Path.Combine(_context.CurrentPluginMetadata.PluginSettingsDirectoryPath, "CustomIcons");
From 0430eea2fd14f208be42d560716319bde2a0362f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 22:25:55 +0800
Subject: [PATCH 0813/1335] Use api functions instead of project reference for
code quality
---
.../Commands/BookmarkLoader.cs | 5 ++--
.../FirefoxBookmarkLoader.cs | 23 ++++++++++---------
...low.Launcher.Plugin.BrowserBookmark.csproj | 1 -
.../Main.cs | 15 ++----------
4 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
index 3468015ebaf..758ce68ae78 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.SharedModels;
@@ -10,11 +9,11 @@ internal static class BookmarkLoader
{
internal static MatchResult MatchProgram(Bookmark bookmark, string queryString)
{
- var match = StringMatcher.FuzzySearch(queryString, bookmark.Name);
+ var match = Main._context.API.FuzzySearch(queryString, bookmark.Name);
if (match.IsSearchPrecisionScoreMet())
return match;
- return StringMatcher.FuzzySearch(queryString, bookmark.Url);
+ return Main._context.API.FuzzySearch(queryString, bookmark.Url);
}
internal static List LoadAllBookmarks(Settings setting)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 3b37bbaed5d..0e02b2c9e7a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -1,15 +1,16 @@
-using Flow.Launcher.Plugin.BrowserBookmark.Models;
-using Microsoft.Data.Sqlite;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin.BrowserBookmark.Models;
+using Microsoft.Data.Sqlite;
namespace Flow.Launcher.Plugin.BrowserBookmark;
public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{
+ private static readonly string ClassName = nameof(FirefoxBookmarkLoaderBase);
+
private readonly string _faviconCacheDir;
protected FirefoxBookmarkLoaderBase()
@@ -52,7 +53,7 @@ protected List GetBookmarksFromPath(string placesPath)
}
catch (Exception ex)
{
- Log.Exception($"Failed to register Firefox bookmark file monitoring: {placesPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to register Firefox bookmark file monitoring: {placesPath}", ex);
}
// Use a copy to avoid lock issues with the original file
@@ -93,12 +94,12 @@ protected List GetBookmarksFromPath(string placesPath)
}
catch (Exception ex)
{
- Log.Exception($"Failed to delete temporary favicon DB: {tempDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
}
}
catch (Exception ex)
{
- Log.Exception($"Failed to load Firefox bookmarks: {placesPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to load Firefox bookmarks: {placesPath}", ex);
}
return bookmarks;
@@ -177,7 +178,7 @@ ORDER BY i.width DESC -- Select largest icon available
}
catch (Exception ex)
{
- Log.Exception($"Failed to extract Firefox favicon: {bookmark.Url}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to extract Firefox favicon: {bookmark.Url}", ex);
}
}
@@ -192,12 +193,12 @@ ORDER BY i.width DESC -- Select largest icon available
}
catch (Exception ex)
{
- Log.Exception($"Failed to delete temporary favicon DB: {tempDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
}
}
catch (Exception ex)
{
- Log.Exception($"Failed to load Firefox favicon DB: {faviconDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {faviconDbPath}", ex);
}
}
@@ -218,7 +219,7 @@ private static void SaveBitmapData(byte[] imageData, string outputPath)
}
catch (Exception ex)
{
- Log.Exception($"Failed to save image: {outputPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to save image: {outputPath}", ex);
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index b4e42fbcdc3..d09b9e750c3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -81,7 +81,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index ce7f56c3455..5ab868ab9c1 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.BrowserBookmark.Commands;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.BrowserBookmark.Views;
@@ -15,7 +14,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark;
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable
{
- private static PluginInitContext _context;
+ internal static PluginInitContext _context;
private static List _cachedBookmarks = new();
@@ -23,16 +22,6 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
private static bool _initialized = false;
- public static PluginInitContext GetContext()
- {
- return _context;
- }
-
- public static string GetPluginDirectory()
- {
- return _context?.CurrentPluginMetadata?.PluginDirectory;
- }
-
public void Init(PluginInitContext context)
{
_context = context;
@@ -223,7 +212,7 @@ public List LoadContextMenus(Result selectedResult)
catch (Exception e)
{
var message = "Failed to set url in clipboard";
- Log.Exception("Main", message, e, "LoadContextMenus");
+ _context.API.LogException(nameof(Main), message, e);
_context.API.ShowMsg(message);
From 168f898baf15950ed79fe2e2a26c96a4bd4e89aa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 22:27:45 +0800
Subject: [PATCH 0814/1335] Cleanup namespaces
---
.../Views/SettingsControl.xaml.cs | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
index 8584a3eb01c..3182adfed65 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
@@ -3,13 +3,6 @@
using System.Windows.Input;
using System.ComponentModel;
using System.Threading.Tasks;
-using System;
-using System.IO;
-using System.Windows;
-using System.Windows.Input;
-using System.ComponentModel;
-using System.Threading.Tasks;
-using Flow.Launcher.Plugin.BrowserBookmark.Models;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views;
@@ -23,6 +16,7 @@ public SettingsControl(Settings settings)
Settings = settings;
InitializeComponent();
}
+
public bool LoadChromeBookmark
{
get => Settings.LoadChromeBookmark;
@@ -62,6 +56,7 @@ public bool OpenInNewBrowserWindow
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenInNewBrowserWindow)));
}
}
+
public event PropertyChangedEventHandler PropertyChanged;
private void NewCustomBrowser(object sender, RoutedEventArgs e)
From b564a39aae1990610a09ccd54531cae9c82e07e4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 22:31:31 +0800
Subject: [PATCH 0815/1335] Use api functions instead of project reference for
code quality
---
.../ChromiumBookmarkLoader.cs | 22 ++++++++++---------
...low.Launcher.Plugin.BrowserBookmark.csproj | 3 ++-
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index d9c4e91d020..39bbb73ff4c 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -1,15 +1,17 @@
-using Flow.Launcher.Plugin.BrowserBookmark.Models;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
using System.Text.Json;
-using Flow.Launcher.Infrastructure.Logger;
using System;
+using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
namespace Flow.Launcher.Plugin.BrowserBookmark;
public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
+ private readonly static string ClassName = nameof(ChromiumBookmarkLoader);
+
private readonly string _faviconCacheDir;
protected ChromiumBookmarkLoader()
@@ -44,7 +46,7 @@ protected List LoadBookmarks(string browserDataPath, string name)
}
catch (Exception ex)
{
- Log.Exception($"Failed to register bookmark file monitoring: {bookmarkPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to register bookmark file monitoring: {bookmarkPath}", ex);
}
var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})");
@@ -136,7 +138,7 @@ private void LoadFaviconsFromDb(string dbPath, List bookmarks)
}
catch (Exception ex)
{
- Log.Exception($"Failed to copy favicon DB: {dbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
return;
}
@@ -189,7 +191,7 @@ ORDER BY b.width DESC
}
catch (Exception ex)
{
- Log.Exception($"Failed to extract bookmark favicon: {bookmark.Url}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to extract bookmark favicon: {bookmark.Url}", ex);
}
}
@@ -199,7 +201,7 @@ ORDER BY b.width DESC
}
catch (Exception ex)
{
- Log.Exception($"Failed to connect to SQLite: {tempDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to connect to SQLite: {tempDbPath}", ex);
}
// Delete temporary file
@@ -209,12 +211,12 @@ ORDER BY b.width DESC
}
catch (Exception ex)
{
- Log.Exception($"Failed to delete temporary favicon DB: {tempDbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
}
}
catch (Exception ex)
{
- Log.Exception($"Failed to load favicon DB: {dbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to load favicon DB: {dbPath}", ex);
}
}
@@ -226,7 +228,7 @@ private static void SaveBitmapData(byte[] imageData, string outputPath)
}
catch (Exception ex)
{
- Log.Exception($"Failed to save image: {outputPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to save image: {outputPath}", ex);
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
index d09b9e750c3..49ae2656495 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj
@@ -1,4 +1,4 @@
-
+
Library
@@ -81,6 +81,7 @@
+
From a845e68c98f4ed3c350bd291dc0a5847bc4f4a8c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 2 Apr 2025 22:39:30 +0800
Subject: [PATCH 0816/1335] Use plugin cache directory
---
.../ChromiumBookmarkLoader.cs | 7 ++-----
.../FirefoxBookmarkLoader.cs | 5 +----
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 9 +++++++++
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 39bbb73ff4c..28287647259 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -10,16 +10,13 @@ namespace Flow.Launcher.Plugin.BrowserBookmark;
public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
- private readonly static string ClassName = nameof(ChromiumBookmarkLoader);
+ private static readonly string ClassName = nameof(ChromiumBookmarkLoader);
private readonly string _faviconCacheDir;
protected ChromiumBookmarkLoader()
{
- _faviconCacheDir = Path.Combine(
- Path.GetDirectoryName(typeof(ChromiumBookmarkLoader).Assembly.Location),
- "FaviconCache");
- Directory.CreateDirectory(_faviconCacheDir);
+ _faviconCacheDir = Main._faviconCacheDir;
}
public abstract List GetBookmarks();
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 0e02b2c9e7a..d2f9733293f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -15,10 +15,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
protected FirefoxBookmarkLoaderBase()
{
- _faviconCacheDir = Path.Combine(
- Path.GetDirectoryName(typeof(FirefoxBookmarkLoaderBase).Assembly.Location),
- "FaviconCache");
- Directory.CreateDirectory(_faviconCacheDir);
+ _faviconCacheDir = Main._faviconCacheDir;
}
public abstract List GetBookmarks();
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 5ab868ab9c1..5dec8b953e3 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
+using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.BrowserBookmark.Commands;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.BrowserBookmark.Views;
@@ -14,6 +15,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark;
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable
{
+ internal static string _faviconCacheDir;
+
internal static PluginInitContext _context;
private static List _cachedBookmarks = new();
@@ -28,6 +31,12 @@ public void Init(PluginInitContext context)
_settings = context.API.LoadSettingJsonStorage();
+ _faviconCacheDir = Path.Combine(
+ _context.CurrentPluginMetadata.PluginCacheDirectoryPath,
+ "FaviconCache");
+
+ Helper.ValidateDirectory(_faviconCacheDir);
+
LoadBookmarksIfEnabled();
}
From 5d16216a5519a42c6f201219ddca60ef24289308 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 21:53:09 +0800
Subject: [PATCH 0817/1335] Fix environment exit
---
Flow.Launcher.Core/Configuration/Portable.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 069154364ab..4f8287c16a4 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -169,7 +169,7 @@ public void PreStartCleanUpAfterPortabilityUpdate()
{
FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));
- Environment.Exit(0);
+ Application.Current.Shutdown();
}
}
// Otherwise, if the portable data folder is marked for deletion,
From 96f10d27997f13e24866a415c346ba947e515f98 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 22:13:12 +0800
Subject: [PATCH 0818/1335] Code quality
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 11 +++++++++++
Flow.Launcher/Notification.cs | 5 ++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 7a3a0c36e26..42461dc180a 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -488,5 +488,16 @@ or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
}
#endregion
+
+ #region Noticification
+
+ public static bool IsNotificationSupport()
+ {
+ // Noticification only supported Windows 10 19041+
+ return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+ Environment.OSVersion.Version.Build >= 19041;
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher/Notification.cs b/Flow.Launcher/Notification.cs
index cb1cbb729ec..23125de151e 100644
--- a/Flow.Launcher/Notification.cs
+++ b/Flow.Launcher/Notification.cs
@@ -9,8 +9,8 @@ namespace Flow.Launcher
{
internal static class Notification
{
- internal static bool legacy = Environment.OSVersion.Version.Build < 19041;
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "")]
+ internal static bool legacy = !Win32Helper.IsNotificationSupport();
+
internal static void Uninstall()
{
if (!legacy)
@@ -25,7 +25,6 @@ public static void Show(string title, string subTitle, string iconPath = null)
});
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "")]
private static void ShowInternal(string title, string subTitle, string iconPath = null)
{
// Handle notification for win7/8/early win10
From b1721f15077c264a79df2642e12a5fd1c1b369fe Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 22:25:04 +0800
Subject: [PATCH 0819/1335] Code quality
---
Flow.Launcher.Core/Updater.cs | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 9a77ece3253..5b2144efe9f 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -4,10 +4,11 @@
using System.Net.Http;
using System.Net.Sockets;
using System.Linq;
+using System.Text.Json.Serialization;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using JetBrains.Annotations;
-using Squirrel;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure;
@@ -15,8 +16,8 @@
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using System.Text.Json.Serialization;
-using System.Threading;
+using JetBrains.Annotations;
+using Squirrel;
namespace Flow.Launcher.Core
{
@@ -70,7 +71,7 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
if (DataLocation.PortableDataLocationInUse())
{
- var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
+ var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => _api.ShowMsgBox(s));
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => _api.ShowMsgBox(s)))
_api.ShowMsgBox(string.Format(_api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
@@ -122,7 +123,7 @@ private class GithubRelease
}
// https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/UpdateManager.Factory.cs
- private async Task GitHubUpdateManagerAsync(string repository)
+ private static async Task GitHubUpdateManagerAsync(string repository)
{
var uri = new Uri(repository);
var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases";
@@ -144,9 +145,9 @@ private async Task GitHubUpdateManagerAsync(string repository)
return manager;
}
- public string NewVersionTips(string version)
+ private static string NewVersionTips(string version)
{
- var translator = InternationalizationManager.Instance;
+ var translator = Ioc.Default.GetRequiredService();
var tips = string.Format(translator.GetTranslation("newVersionTips"), version);
return tips;
From 0def881b9d74497974124c35327cfa10b6bc35fa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 22:27:02 +0800
Subject: [PATCH 0820/1335] Code quality
---
Flow.Launcher.Core/Configuration/Portable.cs | 40 ++++++++------------
1 file changed, 15 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 4f8287c16a4..8abdae8d856 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -22,7 +22,7 @@ public class Portable : IPortable
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
///
///
- private UpdateManager NewUpdateManager()
+ private static UpdateManager NewUpdateManager()
{
var applicationFolderName = Constant.ApplicationDirectory
.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
@@ -81,20 +81,16 @@ public void EnablePortableMode()
public void RemoveShortcuts()
{
- using (var portabilityUpdater = NewUpdateManager())
- {
- portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu);
- portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop);
- portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup);
- }
+ using var portabilityUpdater = NewUpdateManager();
+ portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu);
+ portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop);
+ portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup);
}
public void RemoveUninstallerEntry()
{
- using (var portabilityUpdater = NewUpdateManager())
- {
- portabilityUpdater.RemoveUninstallerRegistryEntry();
- }
+ using var portabilityUpdater = NewUpdateManager();
+ portabilityUpdater.RemoveUninstallerRegistryEntry();
}
public void MoveUserDataFolder(string fromLocation, string toLocation)
@@ -110,12 +106,10 @@ public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
public void CreateShortcuts()
{
- using (var portabilityUpdater = NewUpdateManager())
- {
- portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu, false);
- portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop, false);
- portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup, false);
- }
+ using var portabilityUpdater = NewUpdateManager();
+ portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu, false);
+ portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop, false);
+ portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup, false);
}
public void CreateUninstallerEntry()
@@ -129,18 +123,14 @@ public void CreateUninstallerEntry()
subKey2.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String);
}
- using (var portabilityUpdater = NewUpdateManager())
- {
- _ = portabilityUpdater.CreateUninstallerRegistryEntry();
- }
+ using var portabilityUpdater = NewUpdateManager();
+ _ = portabilityUpdater.CreateUninstallerRegistryEntry();
}
- internal void IndicateDeletion(string filePathTodelete)
+ private static void IndicateDeletion(string filePathTodelete)
{
var deleteFilePath = Path.Combine(filePathTodelete, DataLocation.DeletionIndicatorFile);
- using (var _ = File.CreateText(deleteFilePath))
- {
- }
+ using var _ = File.CreateText(deleteFilePath);
}
///
From 2f53a79a26fc84cb012d580a37c9c2bab7eb7965 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 22:56:31 +0800
Subject: [PATCH 0821/1335] Revert "Fix environment exit"
This reverts commit 5d16216a5519a42c6f201219ddca60ef24289308.
---
Flow.Launcher.Core/Configuration/Portable.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 8abdae8d856..2b570d2c088 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -159,7 +159,7 @@ public void PreStartCleanUpAfterPortabilityUpdate()
{
FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));
- Application.Current.Shutdown();
+ Environment.Exit(0);
}
}
// Otherwise, if the portable data folder is marked for deletion,
From b725975b9898e249a7382171cf2edb07437871d0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 23:01:16 +0800
Subject: [PATCH 0822/1335] Fix environment exit stuck issue
---
Flow.Launcher/App.xaml.cs | 8 ++++++++
Flow.Launcher/MainWindow.xaml.cs | 13 +++++++++----
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 9aee56bff81..f484d4dbadc 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -304,6 +304,14 @@ protected virtual void Dispose(bool disposing)
return;
}
+ // If we call Environment.Exit(0), the application dispose will be called before _mainWindow.Close()
+ // Accessing _mainWindow?.Dispatcher will cause the application stuck
+ // So here we need to check it and just return so that we will not acees _mainWindow?.Dispatcher
+ if (!_mainWindow.CanClose)
+ {
+ return;
+ }
+
_disposed = true;
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 011d46d6b21..c62606743a6 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -32,6 +32,13 @@ namespace Flow.Launcher
{
public partial class MainWindow : IDisposable
{
+ #region Public Property
+
+ // Window Event: Close Event
+ public bool CanClose { get; set; } = false;
+
+ #endregion
+
#region Private Fields
// Dependency Injection
@@ -45,8 +52,6 @@ public partial class MainWindow : IDisposable
private readonly ContextMenu _contextMenu = new();
private readonly MainViewModel _viewModel;
- // Window Event: Close Event
- private bool _canClose = false;
// Window Event: Key Event
private bool _isArrowKeyPressed = false;
@@ -279,7 +284,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
private async void OnClosing(object sender, CancelEventArgs e)
{
- if (!_canClose)
+ if (!CanClose)
{
_notifyIcon.Visible = false;
App.API.SaveAppAllSettings();
@@ -287,7 +292,7 @@ private async void OnClosing(object sender, CancelEventArgs e)
await PluginManager.DisposePluginsAsync();
Notification.Uninstall();
// After plugins are all disposed, we can close the main window
- _canClose = true;
+ CanClose = true;
// Use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event
Application.Current.Shutdown();
}
From 95b38d21af7b8790659d9eb49e2edbbba9a037b1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 09:57:03 +0800
Subject: [PATCH 0823/1335] Wait image cache saved before restarting
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 8 +++++++-
Flow.Launcher/PublicAPIInstance.cs | 7 +++++--
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 6f7b1cd908d..0ba059b7bd5 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -61,7 +61,7 @@ await Stopwatch.NormalAsync("|ImageLoader.Initialize|Preload images cost", async
});
}
- public static async Task Save()
+ public static async Task SaveAsync()
{
await storageLock.WaitAsync();
@@ -77,6 +77,12 @@ await _storage.SaveAsync(ImageCache.EnumerateEntries()
}
}
+ public static async Task WaitSaveAsync()
+ {
+ await storageLock.WaitAsync();
+ storageLock.Release();
+ }
+
private static async Task> LoadStorageToConcurrentDictionaryAsync()
{
await storageLock.WaitAsync();
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index e19ad2fdcd4..b86e731b3b8 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -57,7 +57,7 @@ public void ChangeQuery(string query, bool requery = false)
_mainVM.ChangeQueryText(query, requery);
}
- public void RestartApp()
+ public async void RestartApp()
{
_mainVM.Hide();
@@ -66,6 +66,9 @@ public void RestartApp()
// which will cause ungraceful exit
SaveAppAllSettings();
+ // wait for all image caches to be saved
+ await ImageLoader.WaitSaveAsync();
+
// Restart requires Squirrel's Update.exe to be present in the parent folder,
// it is only published from the project's release pipeline. When debugging without it,
// the project may not restart or just terminates. This is expected.
@@ -88,7 +91,7 @@ public void SaveAppAllSettings()
PluginManager.Save();
_mainVM.Save();
_settings.Save();
- _ = ImageLoader.Save();
+ _ = ImageLoader.SaveAsync();
}
public Task ReloadAllPluginData() => PluginManager.ReloadDataAsync();
From e4577eb23edbe6ce4e13154d2588d9e42e494764 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 10:02:47 +0800
Subject: [PATCH 0824/1335] Improve code comment
---
Flow.Launcher/PublicAPIInstance.cs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b86e731b3b8..a9862c74c8c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -57,16 +57,18 @@ public void ChangeQuery(string query, bool requery = false)
_mainVM.ChangeQueryText(query, requery);
}
+#pragma warning disable VSTHRD100 // Avoid async void methods
+
public async void RestartApp()
{
_mainVM.Hide();
- // we must manually save
+ // We must manually save
// UpdateManager.RestartApp() will call Environment.Exit(0)
// which will cause ungraceful exit
SaveAppAllSettings();
- // wait for all image caches to be saved
+ // Wait for all image caches to be saved before restarting
await ImageLoader.WaitSaveAsync();
// Restart requires Squirrel's Update.exe to be present in the parent folder,
@@ -75,6 +77,8 @@ public async void RestartApp()
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
+#pragma warning restore VSTHRD100 // Avoid async void methods
+
public void ShowMainWindow() => _mainVM.Show();
public void HideMainWindow() => _mainVM.Hide();
From 043fe76a613a5768bcd0e983acb555c58a8d681f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 10:03:19 +0800
Subject: [PATCH 0825/1335] Add settings save lock
---
Flow.Launcher/PublicAPIInstance.cs | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index a9862c74c8c..d88eeb7c9e3 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -37,6 +37,8 @@ public class PublicAPIInstance : IPublicAPI
private readonly Internationalization _translater;
private readonly MainViewModel _mainVM;
+ private readonly object _saveSettingsLock = new();
+
#region Constructor
public PublicAPIInstance(Settings settings, Internationalization translater, MainViewModel mainVM)
@@ -92,9 +94,12 @@ public async void RestartApp()
public void SaveAppAllSettings()
{
- PluginManager.Save();
- _mainVM.Save();
- _settings.Save();
+ lock (_saveSettingsLock)
+ {
+ _settings.Save();
+ PluginManager.Save();
+ _mainVM.Save();
+ }
_ = ImageLoader.SaveAsync();
}
From 95a3fd36dea778911d0f4f8b9a434e4813096b6a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 10:34:59 +0800
Subject: [PATCH 0826/1335] Do not crash when caught exception on saving
settings
---
.../Plugin/JsonRPCPluginSettings.cs | 20 +++++++++--
.../Storage/FlowLauncherJsonStorage.cs | 35 ++++++++++++++++++-
.../Storage/PluginJsonStorage.cs | 33 +++++++++++++++++
3 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 944b2fd100d..e0a21725135 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -23,6 +23,8 @@ public class JsonRPCPluginSettings
protected ConcurrentDictionary Settings { get; set; } = null!;
public required IPublicAPI API { get; init; }
+ private static readonly string ClassName = nameof(JsonRPCPluginSettings);
+
private JsonStorage> _storage = null!;
private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
@@ -122,12 +124,26 @@ public void UpdateSettings(IReadOnlyDictionary settings)
public async Task SaveAsync()
{
- await _storage.SaveAsync();
+ try
+ {
+ await _storage.SaveAsync();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin settings to path: {SettingPath}", e);
+ }
}
public void Save()
{
- _storage.Save();
+ try
+ {
+ _storage.Save();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin settings to path: {SettingPath}", e);
+ }
}
public bool NeedCreateSettingPanel()
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index 865041fb397..a3634a0e2e8 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -1,10 +1,19 @@
using System.IO;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Infrastructure.Storage
{
public class FlowLauncherJsonStorage : JsonStorage where T : new()
{
+ private static readonly string ClassName = "FlowLauncherJsonStorage";
+
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
public FlowLauncherJsonStorage()
{
var directoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName);
@@ -13,5 +22,29 @@ public FlowLauncherJsonStorage()
var filename = typeof(T).Name;
FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
}
+
+ public new void Save()
+ {
+ try
+ {
+ base.Save();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
+ }
+ }
+
+ public new async Task SaveAsync()
+ {
+ try
+ {
+ await base.SaveAsync();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index b377c81aa14..e02d51bdbcf 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -1,5 +1,8 @@
using System.IO;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Infrastructure.Storage
{
@@ -8,6 +11,12 @@ namespace Flow.Launcher.Infrastructure.Storage
// Use assembly name to check which plugin is using this storage
public readonly string AssemblyName;
+ private static readonly string ClassName = "PluginJsonStorage";
+
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
public PluginJsonStorage()
{
// C# related, add python related below
@@ -23,5 +32,29 @@ public PluginJsonStorage(T data) : this()
{
Data = data;
}
+
+ public new void Save()
+ {
+ try
+ {
+ base.Save();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
+ }
+ }
+
+ public new async Task SaveAsync()
+ {
+ try
+ {
+ await base.SaveAsync();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
+ }
+ }
}
}
From f6e3608f72ab28c48bf8563ea3bb58af7b9950bb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 10:42:48 +0800
Subject: [PATCH 0827/1335] Do not crash when saving cache
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 0ba059b7bd5..1ee033821f0 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -71,6 +71,10 @@ await _storage.SaveAsync(ImageCache.EnumerateEntries()
.Select(x => x.Key)
.ToList());
}
+ catch (System.Exception e)
+ {
+ Log.Exception($"|ImageLoader.SaveAsync|Failed to save image cache to file", e);
+ }
finally
{
storageLock.Release();
From 2d6667bb53549c5580004fe194b56b90d20cdcd7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 10:42:55 +0800
Subject: [PATCH 0828/1335] Test save error
---
Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 40106acd829..52bcdcfab8b 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -180,20 +180,24 @@ private void BackupOriginFile()
public void Save()
{
- string serialized = JsonSerializer.Serialize(Data,
+ throw new NotImplementedException("Save error");
+
+ /*string serialized = JsonSerializer.Serialize(Data,
new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(TempFilePath, serialized);
- AtomicWriteSetting();
+ AtomicWriteSetting();*/
}
public async Task SaveAsync()
{
- await using var tempOutput = File.OpenWrite(TempFilePath);
+ throw new NotImplementedException("SaveAsync error");
+
+ /*await using var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
new JsonSerializerOptions { WriteIndented = true });
- AtomicWriteSetting();
+ AtomicWriteSetting();*/
}
private void AtomicWriteSetting()
From c2f8480c049a4a818831c05558080907f2bac8d0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:15:13 +0800
Subject: [PATCH 0829/1335] Revert "Test save error"
This reverts commit 2d6667bb53549c5580004fe194b56b90d20cdcd7.
---
Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 52bcdcfab8b..40106acd829 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -180,24 +180,20 @@ private void BackupOriginFile()
public void Save()
{
- throw new NotImplementedException("Save error");
-
- /*string serialized = JsonSerializer.Serialize(Data,
+ string serialized = JsonSerializer.Serialize(Data,
new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(TempFilePath, serialized);
- AtomicWriteSetting();*/
+ AtomicWriteSetting();
}
public async Task SaveAsync()
{
- throw new NotImplementedException("SaveAsync error");
-
- /*await using var tempOutput = File.OpenWrite(TempFilePath);
+ await using var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
new JsonSerializerOptions { WriteIndented = true });
- AtomicWriteSetting();*/
+ AtomicWriteSetting();
}
private void AtomicWriteSetting()
From 2a2ef234d952be3bc44507f95248b1622b92256d Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:17:30 +0800
Subject: [PATCH 0830/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 42461dc180a..f2b99588d66 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -489,8 +489,7 @@ or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
#endregion
- #region Noticification
-
+ #region Notification
public static bool IsNotificationSupport()
{
// Noticification only supported Windows 10 19041+
From 834780d6e7d57577a59f35c0ad5715f99e7b61cf Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:17:37 +0800
Subject: [PATCH 0831/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index f2b99588d66..5bec3e5e79f 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -492,7 +492,7 @@ or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
#region Notification
public static bool IsNotificationSupport()
{
- // Noticification only supported Windows 10 19041+
+ // Notification only supported Windows 10 19041+
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.Build >= 19041;
}
From 8df1e6a0ce9977346327c9e9249ef2359c3a9ad1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:18:57 +0800
Subject: [PATCH 0832/1335] Add blank line
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 5bec3e5e79f..d3023a3f05a 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -490,6 +490,7 @@ or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
#endregion
#region Notification
+
public static bool IsNotificationSupport()
{
// Notification only supported Windows 10 19041+
From 3283adce59384003887d5d91dfa767ca6822c92e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:27:10 +0800
Subject: [PATCH 0833/1335] Fix typos
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index d3023a3f05a..c21849403ca 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -491,9 +491,9 @@ or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
#region Notification
- public static bool IsNotificationSupport()
+ public static bool IsNotificationSupported()
{
- // Notification only supported Windows 10 19041+
+ // Notifications only supported on Windows 10 19041+
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.Build >= 19041;
}
From ec7a4e8aaa1463524ae0cacebceb5ec7f89e94b8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:27:50 +0800
Subject: [PATCH 0834/1335] Fix build issue
---
Flow.Launcher/Notification.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Notification.cs b/Flow.Launcher/Notification.cs
index 23125de151e..30b3a067334 100644
--- a/Flow.Launcher/Notification.cs
+++ b/Flow.Launcher/Notification.cs
@@ -9,7 +9,7 @@ namespace Flow.Launcher
{
internal static class Notification
{
- internal static bool legacy = !Win32Helper.IsNotificationSupport();
+ internal static bool legacy = !Win32Helper.IsNotificationSupported();
internal static void Uninstall()
{
From 28ab71f11a60304db888c465e871c24be5b18ab5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 11:46:07 +0800
Subject: [PATCH 0835/1335] Fix build issue
---
Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs | 1 +
Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs | 1 +
2 files changed, 2 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index 0fbeed9f55f..8b4062b6b24 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index 910672119c7..e8cbd70fb98 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
From df84e02f55d87404d1f9fe07299d20747072900c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 15:37:03 +0800
Subject: [PATCH 0836/1335] Improve code quality
---
...Flow.Launcher.Plugin.PluginsManager.csproj | 3 +-
.../Main.cs | 13 ++++-----
.../PluginsManager.cs | 29 +++++++++----------
3 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
index c33c428890b..5a2259ff18b 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
@@ -18,8 +18,7 @@
-
-
+
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
index 156135f813d..b333aba4211 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -1,18 +1,17 @@
-using Flow.Launcher.Core.ExternalPlugins;
-using Flow.Launcher.Plugin.PluginsManager.ViewModels;
-using Flow.Launcher.Plugin.PluginsManager.Views;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure;
using System.Threading.Tasks;
using System.Threading;
+using Flow.Launcher.Core.ExternalPlugins;
+using Flow.Launcher.Plugin.PluginsManager.ViewModels;
+using Flow.Launcher.Plugin.PluginsManager.Views;
namespace Flow.Launcher.Plugin.PluginsManager
{
public class Main : ISettingProvider, IAsyncPlugin, IContextMenu, IPluginI18n
{
- internal PluginInitContext Context { get; set; }
+ internal static PluginInitContext Context { get; set; }
internal Settings Settings;
@@ -56,7 +55,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
Settings.UpdateCommand => await pluginManager.RequestUpdateAsync(query.SecondToEndSearch, token, query.IsReQuery),
_ => pluginManager.GetDefaultHotKeys().Where(hotkey =>
{
- hotkey.Score = StringMatcher.FuzzySearch(query.Search, hotkey.Title).Score;
+ hotkey.Score = Context.API.FuzzySearch(query.Search, hotkey.Title).Score;
return hotkey.Score > 0;
}).ToList()
};
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 79d6aedd5a9..9cee8bc8f53 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,8 +1,5 @@
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
@@ -17,7 +14,9 @@ namespace Flow.Launcher.Plugin.PluginsManager
{
internal class PluginsManager
{
- private const string zip = "zip";
+ private const string ZipSuffix = "zip";
+
+ private static readonly string ClassName = nameof(PluginsManager);
private PluginInitContext Context { get; set; }
@@ -169,7 +168,7 @@ await DownloadFileAsync(
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
- Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ Context.API.LogException(ClassName, "An error occurred while downloading plugin", e);
return;
}
@@ -179,7 +178,7 @@ await DownloadFileAsync(
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
plugin.Name));
- Log.Exception("PluginsManager", "An error occurred while downloading plugin", e);
+ Context.API.LogException(ClassName, "An error occurred while downloading plugin", e);
return;
}
@@ -366,7 +365,7 @@ await PluginManager.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserP
}
}).ContinueWith(t =>
{
- Log.Exception("PluginsManager", $"Update failed for {x.Name}",
+ Context.API.LogException(ClassName, $"Update failed for {x.Name}",
t.Exception.InnerException);
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
@@ -438,7 +437,7 @@ await PluginManager.UpdatePluginAsync(plugin.PluginExistingMetadata, plugin.Plug
}
catch (Exception ex)
{
- Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", ex.InnerException);
+ Context.API.LogException(ClassName, $"Update failed for {plugin.Name}", ex.InnerException);
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(
@@ -486,7 +485,7 @@ internal List Search(IEnumerable results, string searchName)
return results
.Where(x =>
{
- var matchResult = StringMatcher.FuzzySearch(searchName, x.Title);
+ var matchResult = Context.API.FuzzySearch(searchName, x.Title);
if (matchResult.IsSearchPrecisionScoreMet())
x.Score = matchResult.Score;
@@ -498,7 +497,7 @@ internal List Search(IEnumerable results, string searchName)
internal List InstallFromWeb(string url)
{
var filename = url.Split("/").Last();
- var name = filename.Split(string.Format(".{0}", zip)).First();
+ var name = filename.Split(string.Format(".{0}", ZipSuffix)).First();
var plugin = new UserPlugin
{
@@ -605,7 +604,7 @@ internal async ValueTask> RequestInstallOrUpdateAsync(string search
await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
if (Uri.IsWellFormedUriString(search, UriKind.Absolute)
- && search.Split('.').Last() == zip)
+ && search.Split('.').Last() == ZipSuffix)
return InstallFromWeb(search);
if (FilesFolders.IsZipFilePath(search, checkFileExists: true))
@@ -656,21 +655,21 @@ private void Install(UserPlugin plugin, string downloadedFilePath)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile"));
- Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
+ Context.API.LogException(ClassName, e.Message, e);
}
catch (InvalidOperationException e)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"),
plugin.Name));
- Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
+ Context.API.LogException(ClassName, e.Message, e);
}
catch (ArgumentException e)
{
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"),
plugin.Name));
- Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
+ Context.API.LogException(ClassName, e.Message, e);
}
}
@@ -744,7 +743,7 @@ private async Task UninstallAsync(PluginMetadata plugin)
}
catch (ArgumentException e)
{
- Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e);
+ Context.API.LogException(ClassName, e.Message, e);
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_error_title"),
Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"));
}
From e2d9148702aa47a64d02c915fda77f80b165bc54 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 15:52:57 +0800
Subject: [PATCH 0837/1335] Move user plugin to plugin project
---
.../ExternalPlugins/CommunityPluginSource.cs | 1 +
.../ExternalPlugins/CommunityPluginStore.cs | 1 +
.../ExternalPlugins/PluginsManifest.cs | 1 +
.../ExternalPlugins/UserPlugin.cs | 23 ------
Flow.Launcher.Plugin/UserPlugin.cs | 80 +++++++++++++++++++
.../ViewModel/PluginStoreItemViewModel.cs | 2 -
.../ContextMenu.cs | 3 +-
.../Utilities.cs | 3 +-
8 files changed, 85 insertions(+), 29 deletions(-)
delete mode 100644 Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
create mode 100644 Flow.Launcher.Plugin/UserPlugin.cs
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
index 68be746f28e..e9713564ec7 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -1,5 +1,6 @@
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin;
using System;
using System.Collections.Generic;
using System.Net;
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
index affd7c31207..1f23c2f6619 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.ExternalPlugins
{
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index ac8abcdcce8..4f5c4ae40c4 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -1,4 +1,5 @@
using Flow.Launcher.Infrastructure.Logger;
+using Flow.Launcher.Plugin;
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs b/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
deleted file mode 100644
index 79d6d7605e3..00000000000
--- a/Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-
-namespace Flow.Launcher.Core.ExternalPlugins
-{
- public record UserPlugin
- {
- public string ID { get; set; }
- public string Name { get; set; }
- public string Description { get; set; }
- public string Author { get; set; }
- public string Version { get; set; }
- public string Language { get; set; }
- public string Website { get; set; }
- public string UrlDownload { get; set; }
- public string UrlSourceCode { get; set; }
- public string LocalInstallPath { get; set; }
- public string IcoPath { get; set; }
- public DateTime? LatestReleaseDate { get; set; }
- public DateTime? DateAdded { get; set; }
-
- public bool IsFromLocalInstallPath => !string.IsNullOrEmpty(LocalInstallPath);
- }
-}
diff --git a/Flow.Launcher.Plugin/UserPlugin.cs b/Flow.Launcher.Plugin/UserPlugin.cs
new file mode 100644
index 00000000000..5c9189ae153
--- /dev/null
+++ b/Flow.Launcher.Plugin/UserPlugin.cs
@@ -0,0 +1,80 @@
+using System;
+
+namespace Flow.Launcher.Plugin
+{
+ ///
+ /// User Plugin Model for Flow Launcher
+ ///
+ public record UserPlugin
+ {
+ ///
+ /// Unique identifier of the plugin
+ ///
+ public string ID { get; set; }
+
+ ///
+ /// Name of the plugin
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Description of the plugin
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Author of the plugin
+ ///
+ public string Author { get; set; }
+
+ ///
+ /// Version of the plugin
+ ///
+ public string Version { get; set; }
+
+ ///
+ /// Allow language of the plugin
+ ///
+ public string Language { get; set; }
+
+ ///
+ /// Website of the plugin
+ ///
+ public string Website { get; set; }
+
+ ///
+ /// URL to download the plugin
+ ///
+ public string UrlDownload { get; set; }
+
+ ///
+ /// URL to the source code of the plugin
+ ///
+ public string UrlSourceCode { get; set; }
+
+ ///
+ /// URL to the issue tracker of the plugin
+ ///
+ public string LocalInstallPath { get; set; }
+
+ ///
+ /// Icon path of the plugin
+ ///
+ public string IcoPath { get; set; }
+
+ ///
+ /// The date when the plugin was last updated
+ ///
+ public DateTime? LatestReleaseDate { get; set; }
+
+ ///
+ /// The date when the plugin was added to the local system
+ ///
+ public DateTime? DateAdded { get; set; }
+
+ ///
+ /// The date when the plugin was last updated on the local system
+ ///
+ public bool IsFromLocalInstallPath => !string.IsNullOrEmpty(LocalInstallPath);
+ }
+}
diff --git a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
index 38b5bec6561..d1cf7450121 100644
--- a/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs
@@ -1,10 +1,8 @@
using System;
using System.Linq;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin;
-using SemanticVersioning;
using Version = SemanticVersioning.Version;
namespace Flow.Launcher.ViewModel
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
index 482e821dc4c..265657ef45d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ContextMenu.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core.ExternalPlugins;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Flow.Launcher.Plugin.PluginsManager
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
index 743f5b25bff..4bb78f6ff8d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core.ExternalPlugins;
-using ICSharpCode.SharpZipLib.Zip;
+using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using System.IO.Compression;
using System.Linq;
From b9c0eb7b7859d5288f1cb53bb60be110ed669210 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 15:56:18 +0800
Subject: [PATCH 0838/1335] Code quality
---
.../ExternalPlugins/PluginsManifest.cs | 12 ++++++------
.../PluginsManager.cs | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index 4f5c4ae40c4..44d3ef0ff7b 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -1,9 +1,9 @@
-using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin;
-using System;
+using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.ExternalPlugins
{
@@ -18,11 +18,11 @@ public static class PluginsManifest
private static readonly SemaphoreSlim manifestUpdateLock = new(1);
private static DateTime lastFetchedAt = DateTime.MinValue;
- private static TimeSpan fetchTimeout = TimeSpan.FromMinutes(2);
+ private static readonly TimeSpan fetchTimeout = TimeSpan.FromMinutes(2);
public static List UserPlugins { get; private set; }
- public static async Task UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false)
+ public static async Task UpdateManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default)
{
try
{
@@ -44,7 +44,7 @@ public static async Task UpdateManifestAsync(CancellationToken token = def
}
catch (Exception e)
{
- Log.Exception($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http request failed", e);
+ Ioc.Default.GetRequiredService().LogException(nameof(PluginsManifest), "Http request failed", e);
}
finally
{
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 9cee8bc8f53..9d2a8fe739e 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -236,7 +236,7 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
- await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
+ await PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
var pluginFromLocalPath = null as UserPlugin;
var updateFromLocalPath = false;
@@ -601,7 +601,7 @@ private bool InstallSourceKnown(string url)
internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
- await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly);
+ await PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
if (Uri.IsWellFormedUriString(search, UriKind.Absolute)
&& search.Split('.').Last() == ZipSuffix)
From 55d1754ed6941835745baf7a64efac7be05a5cb1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 16:05:33 +0800
Subject: [PATCH 0839/1335] Move PluginManifest public function to api
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 18 ++++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 6 ++++++
.../SettingsPanePluginStoreViewModel.cs | 5 ++---
.../Main.cs | 3 +--
.../PluginsManager.cs | 12 +++++-------
5 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index f178ebb90d4..513c2da8431 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,23 @@ public interface IPublicAPI
/// Stop the loading bar in main window
///
public void StopLoadingBar();
+
+ ///
+ /// Update the plugin manifest
+ ///
+ ///
+ /// FL has multiple urls to download the plugin manifest. Set this to true to only use the primary url.
+ ///
+ ///
+ ///
+ /// True if the manifest is updated successfully, false otherwise.
+ ///
+ public Task UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default);
+
+ ///
+ /// Get the plugin manifest
+ ///
+ ///
+ public IReadOnlyList GetUserPlugins();
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index d88eeb7c9e3..a8ec46982c8 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -28,6 +28,7 @@
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Core.ExternalPlugins;
namespace Flow.Launcher
{
@@ -354,6 +355,11 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
+ public Task UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default) =>
+ PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
+
+ public IReadOnlyList GetUserPlugins() => PluginsManifest.UserPlugins;
+
#endregion
#region Private Methods
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 15579a61da0..23a316304d3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -2,7 +2,6 @@
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -14,7 +13,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
public string FilterText { get; set; } = string.Empty;
public IList ExternalPlugins =>
- PluginsManifest.UserPlugins?.Select(p => new PluginStoreItemViewModel(p))
+ App.API.GetUserPlugins()?.Select(p => new PluginStoreItemViewModel(p))
.OrderByDescending(p => p.Category == PluginStoreItemViewModel.NewRelease)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.RecentlyUpdated)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.None)
@@ -24,7 +23,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
[RelayCommand]
private async Task RefreshExternalPluginsAsync()
{
- if (await PluginsManifest.UpdateManifestAsync())
+ if (await App.API.UpdatePluginManifestAsync())
{
OnPropertyChanged(nameof(ExternalPlugins));
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
index b333aba4211..742d85fc1d4 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -3,7 +3,6 @@
using System.Windows.Controls;
using System.Threading.Tasks;
using System.Threading;
-using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Plugin.PluginsManager.ViewModels;
using Flow.Launcher.Plugin.PluginsManager.Views;
@@ -34,7 +33,7 @@ public async Task InitAsync(PluginInitContext context)
contextMenu = new ContextMenu(Context);
pluginManager = new PluginsManager(Context, Settings);
- await PluginsManifest.UpdateManifestAsync();
+ await Context.API.UpdatePluginManifestAsync();
}
public List LoadContextMenus(Result selectedResult)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 9d2a8fe739e..c742e457c68 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core.ExternalPlugins;
-using Flow.Launcher.Core.Plugin;
+using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using System;
using System.Collections.Generic;
@@ -236,7 +235,7 @@ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
- await PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
+ await Context.API.UpdatePluginManifestAsync(usePrimaryUrlOnly, token);
var pluginFromLocalPath = null as UserPlugin;
var updateFromLocalPath = false;
@@ -249,7 +248,7 @@ internal async ValueTask> RequestUpdateAsync(string search, Cancell
}
var updateSource = !updateFromLocalPath
- ? PluginsManifest.UserPlugins
+ ? Context.API.GetUserPlugins()
: new List { pluginFromLocalPath };
var resultsForUpdate = (
@@ -601,7 +600,7 @@ private bool InstallSourceKnown(string url)
internal async ValueTask> RequestInstallOrUpdateAsync(string search, CancellationToken token,
bool usePrimaryUrlOnly = false)
{
- await PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
+ await Context.API.UpdatePluginManifestAsync(usePrimaryUrlOnly, token);
if (Uri.IsWellFormedUriString(search, UriKind.Absolute)
&& search.Split('.').Last() == ZipSuffix)
@@ -611,8 +610,7 @@ internal async ValueTask> RequestInstallOrUpdateAsync(string search
return InstallFromLocalPath(search);
var results =
- PluginsManifest
- .UserPlugins
+ Context.API.GetUserPlugins()
.Where(x => !PluginExists(x.ID) && !PluginManager.PluginModified(x.ID))
.Select(x =>
new Result
From 4744ff780e91ef36c7f835a7cb7a9b3c02a52af5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 16:33:03 +0800
Subject: [PATCH 0840/1335] Move PluginManager public function to api
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 43 +++++++----------
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 47 +++++++++++++++++--
Flow.Launcher/PublicAPIInstance.cs | 13 ++++-
.../SettingsPanePluginStoreViewModel.cs | 2 +-
.../PluginsManager.cs | 31 ++++++------
5 files changed, 87 insertions(+), 49 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 17517832bd8..aa6c54a9434 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -454,16 +454,11 @@ private static bool SameOrLesserPluginVersionExists(string metadataPath)
#region Public functions
- public static bool PluginModified(string uuid)
+ public static bool PluginModified(string id)
{
- return _modifiedPlugins.Contains(uuid);
+ return _modifiedPlugins.Contains(id);
}
-
- ///
- /// Update a plugin to new version, from a zip file. By default will remove the zip file if update is via url,
- /// unless it's a local path installation
- ///
public static async Task UpdatePluginAsync(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
@@ -471,17 +466,11 @@ public static async Task UpdatePluginAsync(PluginMetadata existingVersion, UserP
_modifiedPlugins.Add(existingVersion.ID);
}
- ///
- /// Install a plugin. By default will remove the zip file if installation is from url, unless it's a local path installation
- ///
public static void InstallPlugin(UserPlugin plugin, string zipFilePath)
{
InstallPlugin(plugin, zipFilePath, checkModified: true);
}
- ///
- /// Uninstall a plugin.
- ///
public static async Task UninstallPluginAsync(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false)
{
await UninstallPluginAsync(plugin, removePluginFromSettings, removePluginSettings, true);
@@ -525,20 +514,20 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
var folderName = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}" : $"{plugin.Name}-{plugin.Version}";
var defaultPluginIDs = new List
- {
- "0ECADE17459B49F587BF81DC3A125110", // BrowserBookmark
- "CEA0FDFC6D3B4085823D60DC76F28855", // Calculator
- "572be03c74c642baae319fc283e561a8", // Explorer
- "6A122269676E40EB86EB543B945932B9", // PluginIndicator
- "9f8f9b14-2518-4907-b211-35ab6290dee7", // PluginsManager
- "b64d0a79-329a-48b0-b53f-d658318a1bf6", // ProcessKiller
- "791FC278BA414111B8D1886DFE447410", // Program
- "D409510CD0D2481F853690A07E6DC426", // Shell
- "CEA08895D2544B019B2E9C5009600DF4", // Sys
- "0308FD86DE0A4DEE8D62B9B535370992", // URL
- "565B73353DBF4806919830B9202EE3BF", // WebSearch
- "5043CETYU6A748679OPA02D27D99677A" // WindowsSettings
- };
+ {
+ "0ECADE17459B49F587BF81DC3A125110", // BrowserBookmark
+ "CEA0FDFC6D3B4085823D60DC76F28855", // Calculator
+ "572be03c74c642baae319fc283e561a8", // Explorer
+ "6A122269676E40EB86EB543B945932B9", // PluginIndicator
+ "9f8f9b14-2518-4907-b211-35ab6290dee7", // PluginsManager
+ "b64d0a79-329a-48b0-b53f-d658318a1bf6", // ProcessKiller
+ "791FC278BA414111B8D1886DFE447410", // Program
+ "D409510CD0D2481F853690A07E6DC426", // Shell
+ "CEA08895D2544B019B2E9C5009600DF4", // Sys
+ "0308FD86DE0A4DEE8D62B9B535370992", // URL
+ "565B73353DBF4806919830B9202EE3BF", // WebSearch
+ "5043CETYU6A748679OPA02D27D99677A" // WindowsSettings
+ };
// Treat default plugin differently, it needs to be removable along with each flow release
var installDirectory = !defaultPluginIDs.Any(x => x == plugin.ID)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 513c2da8431..eeb3f5de3ae 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -352,15 +352,54 @@ public interface IPublicAPI
/// FL has multiple urls to download the plugin manifest. Set this to true to only use the primary url.
///
///
- ///
- /// True if the manifest is updated successfully, false otherwise.
- ///
+ /// True if the manifest is updated successfully, false otherwise
public Task UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default);
///
/// Get the plugin manifest
///
///
- public IReadOnlyList GetUserPlugins();
+ public IReadOnlyList GetPluginManifest();
+
+ ///
+ /// Check if the plugin has been modified.
+ /// If this plugin is updated, installed or uninstalled and users do not restart the app,
+ /// it will be marked as modified
+ ///
+ /// Plugin id
+ ///
+ public bool PluginModified(string id);
+
+ ///
+ /// Update a plugin to new version, from a zip file. By default will remove the zip file if update is via url,
+ /// unless it's a local path installation
+ ///
+ /// The metadata of the old plugin to update
+ /// The new plugin to update
+ ///
+ /// Path to the zip file containing the plugin. It will be unzipped to the temporary directory, removed and installed.
+ ///
+ ///
+ public Task UpdatePluginAsync(PluginMetadata pluginMetadata, UserPlugin plugin, string zipFilePath);
+
+ ///
+ /// Install a plugin. By default will remove the zip file if installation is from url,
+ /// unless it's a local path installation
+ ///
+ /// The plugin to install
+ ///
+ /// Path to the zip file containing the plugin. It will be unzipped to the temporary directory, removed and installed.
+ ///
+ public void InstallPlugin(UserPlugin plugin, string zipFilePath);
+
+ ///
+ /// Uninstall a plugin
+ ///
+ /// The metadata of the plugin to uninstall
+ ///
+ /// Plugin has their own settings. If this is set to true, the plugin settings will be removed.
+ ///
+ ///
+ public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePluginSettings = false);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index a8ec46982c8..c40e40ebbae 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -358,7 +358,18 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M
public Task UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default) =>
PluginsManifest.UpdateManifestAsync(usePrimaryUrlOnly, token);
- public IReadOnlyList GetUserPlugins() => PluginsManifest.UserPlugins;
+ public IReadOnlyList GetPluginManifest() => PluginsManifest.UserPlugins;
+
+ public bool PluginModified(string id) => PluginManager.PluginModified(id);
+
+ public Task UpdatePluginAsync(PluginMetadata pluginMetadata, UserPlugin plugin, string zipFilePath) =>
+ PluginManager.UpdatePluginAsync(pluginMetadata, plugin, zipFilePath);
+
+ public void InstallPlugin(UserPlugin plugin, string zipFilePath) =>
+ PluginManager.InstallPlugin(plugin, zipFilePath);
+
+ public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePluginSettings = false) =>
+ PluginManager.UninstallPluginAsync(pluginMetadata, removePluginSettings);
#endregion
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 23a316304d3..84d8a2ff926 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -13,7 +13,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
public string FilterText { get; set; } = string.Empty;
public IList ExternalPlugins =>
- App.API.GetUserPlugins()?.Select(p => new PluginStoreItemViewModel(p))
+ App.API.GetPluginManifest()?.Select(p => new PluginStoreItemViewModel(p))
.OrderByDescending(p => p.Category == PluginStoreItemViewModel.NewRelease)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.RecentlyUpdated)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.None)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index c742e457c68..a16778ff461 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -1,6 +1,4 @@
-using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Plugin.SharedCommands;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -8,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.PluginsManager
{
@@ -49,7 +48,7 @@ internal List GetDefaultHotKeys()
{
return new List()
{
- new Result()
+ new()
{
Title = Settings.InstallCommand,
IcoPath = icoPath,
@@ -61,7 +60,7 @@ internal List GetDefaultHotKeys()
return false;
}
},
- new Result()
+ new()
{
Title = Settings.UninstallCommand,
IcoPath = icoPath,
@@ -73,7 +72,7 @@ internal List GetDefaultHotKeys()
return false;
}
},
- new Result()
+ new()
{
Title = Settings.UpdateCommand,
IcoPath = icoPath,
@@ -248,7 +247,7 @@ internal async ValueTask> RequestUpdateAsync(string search, Cancell
}
var updateSource = !updateFromLocalPath
- ? Context.API.GetUserPlugins()
+ ? Context.API.GetPluginManifest()
: new List { pluginFromLocalPath };
var resultsForUpdate = (
@@ -258,7 +257,7 @@ on existingPlugin.Metadata.ID equals pluginUpdateSource.ID
where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version,
StringComparison.InvariantCulture) <
0 // if current version precedes version of the plugin from update source (e.g. PluginsManifest)
- && !PluginManager.PluginModified(existingPlugin.Metadata.ID)
+ && !Context.API.PluginModified(existingPlugin.Metadata.ID)
select
new
{
@@ -274,7 +273,7 @@ where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version
if (!resultsForUpdate.Any())
return new List
{
- new Result
+ new()
{
Title = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_title"),
SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_subtitle"),
@@ -339,7 +338,7 @@ await DownloadFileAsync(
}
else
{
- await PluginManager.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
+ await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
@@ -431,7 +430,7 @@ await DownloadFileAsync(
if (cts.IsCancellationRequested)
return;
else
- await PluginManager.UpdatePluginAsync(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
+ await Context.API.UpdatePluginAsync(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin,
downloadToFilePath);
}
catch (Exception ex)
@@ -550,7 +549,7 @@ internal List InstallFromLocalPath(string localPath)
return new List
{
- new Result
+ new()
{
Title = $"{plugin.Name} by {plugin.Author}",
SubTitle = plugin.Description,
@@ -610,8 +609,8 @@ internal async ValueTask> RequestInstallOrUpdateAsync(string search
return InstallFromLocalPath(search);
var results =
- Context.API.GetUserPlugins()
- .Where(x => !PluginExists(x.ID) && !PluginManager.PluginModified(x.ID))
+ Context.API.GetPluginManifest()
+ .Where(x => !PluginExists(x.ID) && !Context.API.PluginModified(x.ID))
.Select(x =>
new Result
{
@@ -644,7 +643,7 @@ private void Install(UserPlugin plugin, string downloadedFilePath)
try
{
- PluginManager.InstallPlugin(plugin, downloadedFilePath);
+ Context.API.InstallPlugin(plugin, downloadedFilePath);
if (!plugin.IsFromLocalInstallPath)
File.Delete(downloadedFilePath);
@@ -737,7 +736,7 @@ private async Task UninstallAsync(PluginMetadata plugin)
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_subtitle"),
Context.API.GetTranslation("plugin_pluginsmanager_keep_plugin_settings_title"),
button: MessageBoxButton.YesNo) == MessageBoxResult.No;
- await PluginManager.UninstallPluginAsync(plugin, removePluginFromSettings: true, removePluginSettings: removePluginSettings);
+ await Context.API.UninstallPluginAsync(plugin, removePluginSettings);
}
catch (ArgumentException e)
{
From 473b139ea4a6b43346aa79c582ff66f0094477ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 16:35:28 +0800
Subject: [PATCH 0841/1335] Move FL project reference
---
.../Flow.Launcher.Plugin.PluginsManager.csproj | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
index 5a2259ff18b..8ff41a7add9 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj
@@ -18,7 +18,6 @@
-
@@ -36,4 +35,8 @@
PreserveNewest
+
+
+
+
From 56536d018891a7a28e1c5916a1426045b3682360 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 16:45:58 +0800
Subject: [PATCH 0842/1335] Add log for plugin binary storage
---
.../Storage/PluginBinaryStorage.cs | 36 ++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
index 87f51d5d773..d18060e3df0 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
@@ -1,15 +1,49 @@
using System.IO;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
{
public class PluginBinaryStorage : BinaryStorage where T : new()
{
+ private static readonly string ClassName = "PluginBinaryStorage";
+
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
public PluginBinaryStorage(string cacheName, string cacheDirectory)
{
DirectoryPath = cacheDirectory;
- Helper.ValidateDirectory(DirectoryPath);
+ FilesFolders.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{cacheName}{FileSuffix}");
}
+
+ public new void Save()
+ {
+ try
+ {
+ base.Save();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
+ }
+ }
+
+ public new async Task SaveAsync()
+ {
+ try
+ {
+ await base.SaveAsync();
+ }
+ catch (System.Exception e)
+ {
+ API.LogException(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
+ }
+ }
}
}
From cbd8d2272386ce4e28b688c9cd3b7bc8a16e832e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 17:24:21 +0800
Subject: [PATCH 0843/1335] Improve documents
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher.Plugin/UserPlugin.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/UserPlugin.cs b/Flow.Launcher.Plugin/UserPlugin.cs
index 5c9189ae153..3488b4b931f 100644
--- a/Flow.Launcher.Plugin/UserPlugin.cs
+++ b/Flow.Launcher.Plugin/UserPlugin.cs
@@ -73,7 +73,7 @@ public record UserPlugin
public DateTime? DateAdded { get; set; }
///
- /// The date when the plugin was last updated on the local system
+ /// Indicates whether the plugin is installed from a local path
///
public bool IsFromLocalInstallPath => !string.IsNullOrEmpty(LocalInstallPath);
}
From 171ebe955f23491ad6a70b3a6c197313f7aa47b0 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 17:24:36 +0800
Subject: [PATCH 0844/1335] Improve documents
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher.Plugin/UserPlugin.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/UserPlugin.cs b/Flow.Launcher.Plugin/UserPlugin.cs
index 3488b4b931f..74a16b83d80 100644
--- a/Flow.Launcher.Plugin/UserPlugin.cs
+++ b/Flow.Launcher.Plugin/UserPlugin.cs
@@ -53,7 +53,7 @@ public record UserPlugin
public string UrlSourceCode { get; set; }
///
- /// URL to the issue tracker of the plugin
+ /// Local path where the plugin is installed
///
public string LocalInstallPath { get; set; }
From 358b1fd7c875e4e4863227d53ee977872a9bd703 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:10:39 +0800
Subject: [PATCH 0845/1335] Move theme data and functions into api
---
Flow.Launcher.Core/Resource/Theme.cs | 31 ++++----
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 19 +++++
Flow.Launcher.Plugin/ThemeData.cs | 71 +++++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 13 ++++
4 files changed, 116 insertions(+), 18 deletions(-)
create mode 100644 Flow.Launcher.Plugin/ThemeData.cs
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index e5980b62fa3..4cf9ce7a714 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -81,11 +81,6 @@ public Theme(IPublicAPI publicAPI, Settings settings)
#region Theme Resources
- public string GetCurrentTheme()
- {
- return _settings.Theme;
- }
-
private void MakeSureThemeDirectoriesExist()
{
foreach (var dir in _themeDirectories.Where(dir => !Directory.Exists(dir)))
@@ -127,7 +122,7 @@ public void UpdateFonts()
try
{
// Load a ResourceDictionary for the specified theme.
- var themeName = GetCurrentTheme();
+ var themeName = _settings.Theme;
var dict = GetThemeResourceDictionary(themeName);
// Apply font settings to the theme resource.
@@ -330,7 +325,7 @@ private ResourceDictionary GetResourceDictionary(string theme)
private ResourceDictionary GetCurrentResourceDictionary()
{
- return GetResourceDictionary(GetCurrentTheme());
+ return GetResourceDictionary(_settings.Theme);
}
private ThemeData GetThemeDataFromPath(string path)
@@ -383,9 +378,15 @@ private string GetThemePath(string themeName)
#endregion
- #region Load & Change
+ #region Get & Change Theme
+
+ public ThemeData GetCurrentTheme()
+ {
+ var themes = GetAvailableThemes();
+ return themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme) ?? themes.FirstOrDefault();
+ }
- public List LoadAvailableThemes()
+ public List GetAvailableThemes()
{
List themes = new List();
foreach (var themeDirectory in _themeDirectories)
@@ -403,7 +404,7 @@ public List LoadAvailableThemes()
public bool ChangeTheme(string theme = null)
{
if (string.IsNullOrEmpty(theme))
- theme = GetCurrentTheme();
+ theme = _settings.Theme;
string path = GetThemePath(theme);
try
@@ -591,7 +592,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
{
AutoDropShadow(useDropShadowEffect);
}
- SetBlurForWindow(GetCurrentTheme(), backdropType);
+ SetBlurForWindow(_settings.Theme, backdropType);
if (!BlurEnabled)
{
@@ -610,7 +611,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
// Get the actual backdrop type and drop shadow effect settings
var (backdropType, _) = GetActualValue();
- SetBlurForWindow(GetCurrentTheme(), backdropType);
+ SetBlurForWindow(_settings.Theme, backdropType);
}, DispatcherPriority.Render);
}
@@ -898,11 +899,5 @@ private static bool IsBlurTheme()
}
#endregion
-
- #region Classes
-
- public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null);
-
- #endregion
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index f178ebb90d4..bfcc2f9e060 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -344,5 +344,24 @@ public interface IPublicAPI
/// Stop the loading bar in main window
///
public void StopLoadingBar();
+
+ ///
+ /// Get all available themes
+ ///
+ ///
+ public List GetAvailableThemes();
+
+ ///
+ /// Get the current theme
+ ///
+ ///
+ public ThemeData GetCurrentTheme();
+
+ ///
+ /// Set the current theme
+ ///
+ ///
+ ///
+ public void SetCurrentTheme(ThemeData theme);
}
}
diff --git a/Flow.Launcher.Plugin/ThemeData.cs b/Flow.Launcher.Plugin/ThemeData.cs
new file mode 100644
index 00000000000..d4a69ef09c5
--- /dev/null
+++ b/Flow.Launcher.Plugin/ThemeData.cs
@@ -0,0 +1,71 @@
+namespace Flow.Launcher.Plugin;
+
+///
+/// Theme data model
+///
+public class ThemeData
+{
+ ///
+ /// Theme file name without extension
+ ///
+ public string FileNameWithoutExtension { get; private init; }
+
+ ///
+ /// Theme name
+ ///
+ public string Name { get; private init; }
+
+ ///
+ /// Theme file path
+ ///
+ public bool? IsDark { get; private init; }
+
+ ///
+ /// Theme file path
+ ///
+ public bool? HasBlur { get; private init; }
+
+ ///
+ /// Theme data constructor
+ ///
+ public ThemeData(string fileNameWithoutExtension, string name, bool? isDark = null, bool? hasBlur = null)
+ {
+ FileNameWithoutExtension = fileNameWithoutExtension;
+ Name = name;
+ IsDark = isDark;
+ HasBlur = hasBlur;
+ }
+
+ ///
+ public static bool operator ==(ThemeData left, ThemeData right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ public static bool operator !=(ThemeData left, ThemeData right)
+ {
+ return !(left == right);
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ if (obj is not ThemeData other)
+ return false;
+ return FileNameWithoutExtension == other.FileNameWithoutExtension &&
+ Name == other.Name;
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return Name?.GetHashCode() ?? 0;
+ }
+
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index d88eeb7c9e3..96ccb55c44c 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -37,6 +37,9 @@ public class PublicAPIInstance : IPublicAPI
private readonly Internationalization _translater;
private readonly MainViewModel _mainVM;
+ private Theme _theme;
+ private Theme Theme => _theme ??= Ioc.Default.GetRequiredService();
+
private readonly object _saveSettingsLock = new();
#region Constructor
@@ -354,6 +357,16 @@ public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", M
public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action cancelProgress = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, cancelProgress);
+ public List GetAvailableThemes() => Theme.GetAvailableThemes();
+
+ public ThemeData GetCurrentTheme() => Theme.GetCurrentTheme();
+
+ public void SetCurrentTheme(ThemeData theme)
+ {
+ Theme.ChangeTheme(theme.FileNameWithoutExtension);
+ _ = _theme.RefreshFrameAsync();
+ }
+
#endregion
#region Private Methods
From 9b9704e938f1e74584c8bc7688bc333387700c6b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:11:01 +0800
Subject: [PATCH 0846/1335] Improve settings panel theme page & theme selector
---
.../ViewModels/SettingsPaneThemeViewModel.cs | 14 +++---
.../Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 47 +++++--------------
2 files changed, 17 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 6e2488fe1d1..58cf3a314b5 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -28,25 +28,23 @@ public partial class SettingsPaneThemeViewModel : BaseModel
public static string LinkHowToCreateTheme => @"https://www.flowlauncher.com/theme-builder/";
public static string LinkThemeGallery => "https://github.com/Flow-Launcher/Flow.Launcher/discussions/1438";
- private List _themes;
- public List Themes => _themes ??= _theme.LoadAvailableThemes();
+ private List _themes;
+ public List Themes => _themes ??= App.API.GetAvailableThemes();
- private Theme.ThemeData _selectedTheme;
- public Theme.ThemeData SelectedTheme
+ private ThemeData _selectedTheme;
+ public ThemeData SelectedTheme
{
- get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == _theme.GetCurrentTheme());
+ get => _selectedTheme ??= Themes.Find(v => v == App.API.GetCurrentTheme());
set
{
_selectedTheme = value;
- _theme.ChangeTheme(value.FileNameWithoutExtension);
+ App.API.SetCurrentTheme(value);
// Update UI state
OnPropertyChanged(nameof(BackdropType));
OnPropertyChanged(nameof(IsBackdropEnabled));
OnPropertyChanged(nameof(IsDropShadowEnabled));
OnPropertyChanged(nameof(DropShadowEffect));
-
- _ = _theme.RefreshFrameAsync();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 31faeba5231..84bfa218e4b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core.Resource;
namespace Flow.Launcher.Plugin.Sys
{
@@ -11,32 +9,6 @@ public class ThemeSelector
private readonly PluginInitContext _context;
- // Do not initialize it in the constructor, because it will cause null reference in
- // var dicts = Application.Current.Resources.MergedDictionaries; line of Theme
- private Theme theme = null;
- private Theme Theme => theme ??= Ioc.Default.GetRequiredService();
-
- #region Theme Selection
-
- // Theme select codes simplified from SettingsPaneThemeViewModel.cs
-
- private Theme.ThemeData _selectedTheme;
- public Theme.ThemeData SelectedTheme
- {
- get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == Theme.GetCurrentTheme());
- set
- {
- _selectedTheme = value;
- Theme.ChangeTheme(value.FileNameWithoutExtension);
-
- _ = Theme.RefreshFrameAsync();
- }
- }
-
- private List Themes => Theme.LoadAvailableThemes();
-
- #endregion
-
public ThemeSelector(PluginInitContext context)
{
_context = context;
@@ -44,28 +16,31 @@ public ThemeSelector(PluginInitContext context)
public List Query(Query query)
{
+ var themes = _context.API.GetAvailableThemes();
+ var selectedTheme = _context.API.GetCurrentTheme();
+
var search = query.SecondToEndSearch;
if (string.IsNullOrWhiteSpace(search))
{
- return Themes.Select(CreateThemeResult)
+ return themes.Select(x => CreateThemeResult(x, selectedTheme))
.OrderBy(x => x.Title)
.ToList();
}
- return Themes.Select(theme => (theme, matchResult: _context.API.FuzzySearch(search, theme.Name)))
+ return themes.Select(theme => (theme, matchResult: _context.API.FuzzySearch(search, theme.Name)))
.Where(x => x.matchResult.IsSearchPrecisionScoreMet())
- .Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
+ .Select(x => CreateThemeResult(x.theme, selectedTheme, x.matchResult.Score, x.matchResult.MatchData))
.OrderBy(x => x.Title)
.ToList();
}
- private Result CreateThemeResult(Theme.ThemeData theme) => CreateThemeResult(theme, 0, null);
+ private Result CreateThemeResult(ThemeData theme, ThemeData selectedTheme) => CreateThemeResult(theme, selectedTheme, 0, null);
- private Result CreateThemeResult(Theme.ThemeData theme, int score, IList highlightData)
+ private Result CreateThemeResult(ThemeData theme, ThemeData selectedTheme, int score, IList highlightData)
{
- string themeName = theme.Name;
+ var themeName = theme.FileNameWithoutExtension;
string title;
- if (theme == SelectedTheme)
+ if (theme == selectedTheme)
{
title = $"{theme.Name} ★";
// Set current theme to the top
@@ -101,7 +76,7 @@ private Result CreateThemeResult(Theme.ThemeData theme, int score, IList hi
Score = score,
Action = c =>
{
- SelectedTheme = theme;
+ _context.API.SetCurrentTheme(theme);
_context.API.ReQuery();
return false;
}
From 1611ad37f37fde5ac054529cfa3a136e28fa3168 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:15:47 +0800
Subject: [PATCH 0847/1335] Fix ThemeData hashcode issue
---
Flow.Launcher.Plugin/ThemeData.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/ThemeData.cs b/Flow.Launcher.Plugin/ThemeData.cs
index d4a69ef09c5..6cbd0fe740b 100644
--- a/Flow.Launcher.Plugin/ThemeData.cs
+++ b/Flow.Launcher.Plugin/ThemeData.cs
@@ -1,4 +1,6 @@
-namespace Flow.Launcher.Plugin;
+using System;
+
+namespace Flow.Launcher.Plugin;
///
/// Theme data model
@@ -60,7 +62,7 @@ public override bool Equals(object obj)
///
public override int GetHashCode()
{
- return Name?.GetHashCode() ?? 0;
+ return HashCode.Combine(FileNameWithoutExtension, Name);
}
///
From 514fa0037a0f0ad6b78ad6ae17d943764cf696c7 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:23:07 +0800
Subject: [PATCH 0848/1335] Improve documents
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Plugin/ThemeData.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/ThemeData.cs b/Flow.Launcher.Plugin/ThemeData.cs
index 6cbd0fe740b..90a45182c8f 100644
--- a/Flow.Launcher.Plugin/ThemeData.cs
+++ b/Flow.Launcher.Plugin/ThemeData.cs
@@ -23,7 +23,7 @@ public class ThemeData
public bool? IsDark { get; private init; }
///
- /// Theme file path
+ /// Indicates whether the theme supports blur effects
///
public bool? HasBlur { get; private init; }
From 28d92c789f181acb2060f7ff0b1c9f226bdb4905 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:23:36 +0800
Subject: [PATCH 0849/1335] Improve documents
---
Flow.Launcher.Plugin/ThemeData.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/ThemeData.cs b/Flow.Launcher.Plugin/ThemeData.cs
index 90a45182c8f..1888be65e1d 100644
--- a/Flow.Launcher.Plugin/ThemeData.cs
+++ b/Flow.Launcher.Plugin/ThemeData.cs
@@ -18,7 +18,7 @@ public class ThemeData
public string Name { get; private init; }
///
- /// Theme file path
+ /// Indicates whether the theme supports dark mode
///
public bool? IsDark { get; private init; }
From 2e885ea5ccec4a42de61e1d1fe6ced1e319656ce Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 20:45:24 +0800
Subject: [PATCH 0850/1335] Remove useless variable
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 84bfa218e4b..4b99efe3b1a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -38,7 +38,6 @@ public List Query(Query query)
private Result CreateThemeResult(ThemeData theme, ThemeData selectedTheme, int score, IList highlightData)
{
- var themeName = theme.FileNameWithoutExtension;
string title;
if (theme == selectedTheme)
{
From a65e89b86fbe3e1134c1a098f9af85ed4ea8bf71 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 5 Apr 2025 01:06:06 +0900
Subject: [PATCH 0851/1335] Adjust advanced control UI
---
.../SettingsPanePluginsViewModel.cs | 22 +++++
.../Views/SettingsPaneGeneral.xaml | 21 ++++
.../Views/SettingsPanePlugins.xaml | 97 +++++++++++++------
.../Views/SettingsPanePlugins.xaml.cs | 9 ++
4 files changed, 117 insertions(+), 32 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 5cd14ba7edb..69d31a98d28 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -14,6 +14,28 @@ public class SettingsPanePluginsViewModel : BaseModel
{
private readonly Settings _settings;
+ public void UpdateDisplayModeFromSelection()
+ {
+ switch (CurrentDisplayMode)
+ {
+ case "OnOff":
+ IsOnOffSelected = true;
+ IsPrioritySelected = false;
+ IsSearchDelaySelected = false;
+ break;
+ case "Priority":
+ IsOnOffSelected = false;
+ IsPrioritySelected = true;
+ IsSearchDelaySelected = false;
+ break;
+ case "SearchDelay":
+ IsOnOffSelected = false;
+ IsPrioritySelected = false;
+ IsSearchDelaySelected = true;
+ break;
+ }
+ }
+
private bool _isOnOffSelected = true;
public bool IsOnOffSelected
{
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 3f8272ddafe..e36c647a2bb 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -196,6 +196,27 @@
+
+
+
+
+
+
+
+
+
@@ -34,34 +34,35 @@
Text="{DynamicResource plugins}"
TextAlignment="Left" />
-
-
+
+
-
+
+
+
+
+
+ Margin="0 0 20 0"
+ Content="?"
+ FontSize="14" />
+
+
+
-
-
+
+
Date: Sat, 5 Apr 2025 01:46:47 +0900
Subject: [PATCH 0852/1335] - Add strings - Adjust combobox
---
Flow.Launcher/Languages/en.xaml | 4 ++++
.../SettingsPanePluginsViewModel.cs | 17 ++++++++++++-
.../Views/SettingsPanePlugins.xaml | 24 ++++++++++++-------
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 24ab3cf9477..b869a82e1f4 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -134,6 +134,10 @@
Change Action Keywords
Plugin seach delay time
Change Plugin Seach Delay Time
+ Advanced Settings:
+ Enabled
+ Priority
+ Search Delay
Current Priority
New Priority
Priority
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 69d31a98d28..5d55e8e2fb6 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -14,9 +14,24 @@ public class SettingsPanePluginsViewModel : BaseModel
{
private readonly Settings _settings;
+ private string _selectedDisplayMode = "OnOff";
+ public string SelectedDisplayMode
+ {
+ get => _selectedDisplayMode;
+ set
+ {
+ if (_selectedDisplayMode != value)
+ {
+ _selectedDisplayMode = value;
+ OnPropertyChanged(nameof(SelectedDisplayMode));
+ UpdateDisplayModeFromSelection();
+ }
+ }
+ }
+
public void UpdateDisplayModeFromSelection()
{
- switch (CurrentDisplayMode)
+ switch (SelectedDisplayMode)
{
case "OnOff":
IsOnOffSelected = true;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index 23ec6d24252..bfab94f2099 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -43,25 +43,31 @@
VerticalAlignment="Center"
FontSize="14"
Foreground="{DynamicResource Color15B}"
- Text="Advanced Settings:" />
+ Text="{DynamicResource FilterComboboxLabel}" />
-
-
-
+
+
+
+
+
+
+
+
+
Date: Sat, 5 Apr 2025 02:28:07 +0900
Subject: [PATCH 0853/1335] Remove Delay item in plugin setting page layout
---
.../Resources/Controls/InstalledPluginDisplay.xaml | 6 +++---
Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml | 4 +++-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index cb1d8dbc45f..a524dd7cb52 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -102,12 +102,12 @@
@@ -143,7 +143,7 @@
-
+
Date: Sat, 5 Apr 2025 05:28:38 +0900
Subject: [PATCH 0854/1335] Add help window with content dialogue style
---
.../Resources/CustomControlTemplate.xaml | 50 ++++++++++---------
Flow.Launcher/Resources/Dark.xaml | 2 +-
.../SettingsPanePluginsViewModel.cs | 3 +-
.../Views/SettingsPanePlugins.xaml | 2 +-
.../Views/SettingsPanePlugins.xaml.cs | 49 +++++++++++++++++-
5 files changed, 77 insertions(+), 29 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index aeb8f872fd2..31e9d1f13cb 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -3523,8 +3523,8 @@
-
-
-
-
- -->
-
-
-
+ Visibility="{Binding DataContext.IsPrioritySelected, RelativeSource={RelativeSource AncestorType=ListBox}, Converter={StaticResource BooleanToVisibilityConverter}}">
+ Margin="0 0 8 0"
+ VerticalAlignment="Center"
+ FontSize="13"
+ Foreground="{DynamicResource Color08B}"
+ Text="{DynamicResource priority}"
+ ToolTip="{DynamicResource priorityToolTip}" />
+ SpinButtonPlacementMode="Inline"
+ ToolTip="{DynamicResource priorityToolTip}" />
+ Orientation="Horizontal"
+ Visibility="{Binding DataContext.IsSearchDelaySelected, RelativeSource={RelativeSource AncestorType=ListBox}, Converter={StaticResource BooleanToVisibilityConverter}}">
-
+ Text="{DynamicResource searchDelay}"
+ ToolTip="{DynamicResource searchDelayToolTip}" />
+
+
-
+ Visibility="{Binding DataContext.IsOnOffSelected, RelativeSource={RelativeSource AncestorType=ListBox}, Converter={StaticResource BooleanToVisibilityConverter}}" />
+
@@ -148,8 +104,6 @@
-
-
-
+
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 754b1598971..af1653c93d0 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -19,8 +19,13 @@ public partial class SettingsPanePluginsViewModel : BaseModel
{
private readonly Settings _settings;
- private string _selectedDisplayMode = "OnOff";
- public string SelectedDisplayMode
+ public class DisplayModeData : DropdownDataGeneric { }
+
+ public List DisplayModes { get; } =
+ DropdownDataGeneric.GetValues("DisplayMode");
+
+ private DisplayMode _selectedDisplayMode = DisplayMode.OnOff;
+ public DisplayMode SelectedDisplayMode
{
get => _selectedDisplayMode;
set
@@ -28,34 +33,12 @@ public string SelectedDisplayMode
if (_selectedDisplayMode != value)
{
_selectedDisplayMode = value;
- OnPropertyChanged(nameof(SelectedDisplayMode));
+ OnPropertyChanged();
UpdateDisplayModeFromSelection();
}
}
}
- public void UpdateDisplayModeFromSelection()
- {
- switch (SelectedDisplayMode)
- {
- case "OnOff":
- IsOnOffSelected = true;
- IsPrioritySelected = false;
- IsSearchDelaySelected = false;
- break;
- case "Priority":
- IsOnOffSelected = false;
- IsPrioritySelected = true;
- IsSearchDelaySelected = false;
- break;
- case "SearchDelay":
- IsOnOffSelected = false;
- IsPrioritySelected = false;
- IsSearchDelaySelected = true;
- break;
- }
- }
-
private bool _isOnOffSelected = true;
public bool IsOnOffSelected
{
@@ -65,8 +48,7 @@ public bool IsOnOffSelected
if (_isOnOffSelected != value)
{
_isOnOffSelected = value;
- OnPropertyChanged(nameof(IsOnOffSelected));
- UpdateDisplayMode();
+ OnPropertyChanged();
}
}
}
@@ -80,8 +62,7 @@ public bool IsPrioritySelected
if (_isPrioritySelected != value)
{
_isPrioritySelected = value;
- OnPropertyChanged(nameof(IsPrioritySelected));
- UpdateDisplayMode();
+ OnPropertyChanged();
}
}
}
@@ -95,38 +76,15 @@ public bool IsSearchDelaySelected
if (_isSearchDelaySelected != value)
{
_isSearchDelaySelected = value;
- OnPropertyChanged(nameof(IsSearchDelaySelected));
- UpdateDisplayMode();
+ OnPropertyChanged();
}
}
}
- private string _currentDisplayMode = "OnOff";
- public string CurrentDisplayMode
- {
- get => _currentDisplayMode;
- set
- {
- if (_currentDisplayMode != value)
- {
- _currentDisplayMode = value;
- OnPropertyChanged(nameof(CurrentDisplayMode));
- }
- }
- }
-
- private void UpdateDisplayMode()
- {
- if (IsOnOffSelected)
- CurrentDisplayMode = "OnOff";
- else if (IsPrioritySelected)
- CurrentDisplayMode = "Priority";
- else if (IsSearchDelaySelected)
- CurrentDisplayMode = "SearchDelay";
- }
public SettingsPanePluginsViewModel(Settings settings)
{
_settings = settings;
+ UpdateEnumDropdownLocalizations();
}
public string FilterText { get; set; } = string.Empty;
@@ -196,4 +154,38 @@ private async Task OpenHelperAsync()
await helpDialog.ShowAsync();
}
+
+ private void UpdateEnumDropdownLocalizations()
+ {
+ DropdownDataGeneric.UpdateLabels(DisplayModes);
+ }
+
+ private void UpdateDisplayModeFromSelection()
+ {
+ switch (SelectedDisplayMode)
+ {
+ case DisplayMode.Priority:
+ IsOnOffSelected = false;
+ IsPrioritySelected = true;
+ IsSearchDelaySelected = false;
+ break;
+ case DisplayMode.SearchDelay:
+ IsOnOffSelected = false;
+ IsPrioritySelected = false;
+ IsSearchDelaySelected = true;
+ break;
+ default:
+ IsOnOffSelected = true;
+ IsPrioritySelected = false;
+ IsSearchDelaySelected = false;
+ break;
+ }
+ }
+}
+
+public enum DisplayMode
+{
+ OnOff,
+ Priority,
+ SearchDelay
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index 5498b293c76..f9f7083147b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -3,7 +3,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
- xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
@@ -16,10 +15,6 @@
FocusManager.FocusedElement="{Binding ElementName=PluginFilterTextbox}"
KeyDown="SettingsPanePlugins_OnKeyDown"
mc:Ignorable="d">
-
-
-
-
@@ -53,19 +48,10 @@
Margin="0 0 4 0"
HorizontalContentAlignment="Left"
Background="{DynamicResource Color00B}"
+ DisplayMemberPath="Display"
+ ItemsSource="{Binding DisplayModes}"
SelectedValue="{Binding SelectedDisplayMode, Mode=TwoWay}"
- SelectedValuePath="Tag"
- SelectionChanged="DisplayModeComboBox_SelectionChanged">
-
-
-
-
-
-
-
-
-
-
+ SelectedValuePath="Value" />
IsExpanded ? _bottomPart1 ??= new InstalledPluginDisplayKeyword() : null;
private Control _bottomPart2;
- public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginSearchDelay() : null;
-
- private Control _bottomPart3;
- public Control BottomPart3 => IsExpanded ? _bottomPart3 ??= new InstalledPluginDisplayBottomData() : null;
+ public Control BottomPart2 => IsExpanded ? _bottomPart2 ??= new InstalledPluginDisplayBottomData() : null;
public bool HasSettingControl => PluginPair.Plugin is ISettingProvider &&
(PluginPair.Plugin is not JsonRPCPluginBase jsonRPCPluginBase || jsonRPCPluginBase.NeedCreateSettingPanel());
From dc7b81207761aeddea4b2aed07bbd5ffc12789be Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 7 Apr 2025 14:16:17 +0800
Subject: [PATCH 0871/1335] Change search delay time to int & Improve code
quality & Improve strings
---
.../UserSettings/PluginSettings.cs | 5 +-
.../UserSettings/Settings.cs | 6 +-
Flow.Launcher.Plugin/PluginMetadata.cs | 5 +-
Flow.Launcher.Plugin/SearchDelayTime.cs | 32 ----
Flow.Launcher/Languages/en.xaml | 4 +-
.../Controls/InstalledPluginDisplay.xaml | 7 +-
.../Controls/InstalledPluginSearchDelay.xaml | 49 -------
.../InstalledPluginSearchDelay.xaml.cs | 11 --
.../InstalledPluginSearchDelayCombobox.xaml | 39 -----
...InstalledPluginSearchDelayCombobox.xaml.cs | 84 -----------
Flow.Launcher/SearchDelayTimeWindow.xaml | 138 ------------------
Flow.Launcher/SearchDelayTimeWindow.xaml.cs | 57 --------
.../SettingsPaneGeneralViewModel.cs | 34 +++--
.../Views/SettingsPaneGeneral.xaml | 17 ++-
Flow.Launcher/ViewModel/MainViewModel.cs | 10 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 9 +-
.../plugin.json | 2 +-
17 files changed, 52 insertions(+), 457 deletions(-)
delete mode 100644 Flow.Launcher.Plugin/SearchDelayTime.cs
delete mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
delete mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml.cs
delete mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
delete mode 100644 Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
delete mode 100644 Flow.Launcher/SearchDelayTimeWindow.xaml
delete mode 100644 Flow.Launcher/SearchDelayTimeWindow.xaml.cs
diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
index da92a358351..7fb9b895a24 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -120,10 +120,9 @@ public class Plugin
public int Priority { get; set; }
[JsonIgnore]
- public SearchDelayTime? DefaultSearchDelayTime { get; set; }
+ public int? DefaultSearchDelayTime { get; set; }
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelayTime? SearchDelayTime { get; set; }
+ public int? SearchDelayTime { get; set; }
///
/// Used only to save the state of the plugin in settings
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 6cb20d12fdd..d89340e1942 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -322,8 +322,10 @@ public bool HideNotifyIcon
public bool SearchQueryResultsWithDelay { get; set; }
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelayTime SearchDelayTime { get; set; } = SearchDelayTime.Normal;
+ [JsonIgnore]
+ public IEnumerable SearchDelayTimeRange = new List { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500 };
+
+ public int SearchDelayTime { get; set; } = 150;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
diff --git a/Flow.Launcher.Plugin/PluginMetadata.cs b/Flow.Launcher.Plugin/PluginMetadata.cs
index 1496765cea4..da10bc6a504 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -99,10 +99,9 @@ internal set
public bool HideActionKeywordPanel { get; set; }
///
- /// Plugin search delay time. Null means use default search delay time.
+ /// Plugin search delay time in ms. Null means use default search delay time.
///
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public SearchDelayTime? SearchDelayTime { get; set; } = null;
+ public int? SearchDelayTime { get; set; } = null;
///
/// Plugin icon path.
diff --git a/Flow.Launcher.Plugin/SearchDelayTime.cs b/Flow.Launcher.Plugin/SearchDelayTime.cs
deleted file mode 100644
index ae1daabe08a..00000000000
--- a/Flow.Launcher.Plugin/SearchDelayTime.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace Flow.Launcher.Plugin;
-
-///
-/// Enum for search delay time
-///
-public enum SearchDelayTime
-{
- ///
- /// Very long search delay time. 250ms.
- ///
- VeryLong,
-
- ///
- /// Long search delay time. 200ms.
- ///
- Long,
-
- ///
- /// Normal search delay time. 150ms. Default value.
- ///
- Normal,
-
- ///
- /// Short search delay time. 100ms.
- ///
- Short,
-
- ///
- /// Very short search delay time. 50ms.
- ///
- VeryShort
-}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 78486dad4e3..5d9b16e0b60 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -380,9 +380,7 @@
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
Custom Query Hotkey
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 615904d6601..5ba011fede7 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -85,7 +85,12 @@
Foreground="{DynamicResource Color08B}"
Text="{DynamicResource searchDelay}"
ToolTip="{DynamicResource searchDelayToolTip}" />
-
+
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
deleted file mode 100644
index 0fd98bfac42..00000000000
--- a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml.cs b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml.cs
deleted file mode 100644
index ad9284074d2..00000000000
--- a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelay.xaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Windows.Controls;
-
-namespace Flow.Launcher.Resources.Controls;
-
-public partial class InstalledPluginSearchDelay : UserControl
-{
- public InstalledPluginSearchDelay()
- {
- InitializeComponent();
- }
-}
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
deleted file mode 100644
index b379b875f53..00000000000
--- a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs b/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
deleted file mode 100644
index 649913872bb..00000000000
--- a/Flow.Launcher/Resources/Controls/InstalledPluginSearchDelayCombobox.xaml.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System.Collections.Generic;
-using System.Windows.Controls;
-using Flow.Launcher.Plugin;
-
-namespace Flow.Launcher.Resources.Controls
-{
- public partial class InstalledPluginSearchDelayCombobox
- {
- public InstalledPluginSearchDelayCombobox()
- {
- InitializeComponent();
- LoadDelayOptions();
- Loaded += InstalledPluginSearchDelayCombobox_Loaded;
- }
-
- private void InstalledPluginSearchDelayCombobox_Loaded(object sender, System.Windows.RoutedEventArgs e)
- {
- if (DataContext is ViewModel.PluginViewModel viewModel)
- {
- // 초기 값 설정
- int currentDelayMs = GetCurrentDelayMs(viewModel);
- foreach (DelayOption option in cbDelay.Items)
- {
- if (option.Value == currentDelayMs)
- {
- cbDelay.SelectedItem = option;
- break;
- }
- }
- }
- }
-
- private int GetCurrentDelayMs(ViewModel.PluginViewModel viewModel)
- {
- // SearchDelayTime enum 값을 int로 변환
- SearchDelayTime? delayTime = viewModel.PluginPair.Metadata.SearchDelayTime;
- if (delayTime.HasValue)
- {
- return (int)delayTime.Value;
- }
- return 0; // 기본값
- }
-
- private void LoadDelayOptions()
- {
- // 검색 지연 시간 옵션들 (SearchDelayTime enum 값에 맞춰야 함)
- var delayOptions = new List
- {
- new DelayOption { Display = "0 ms", Value = 0 },
- new DelayOption { Display = "50 ms", Value = 50 },
- new DelayOption { Display = "100 ms", Value = 100 },
- new DelayOption { Display = "150 ms", Value = 150 },
- new DelayOption { Display = "200 ms", Value = 200 },
- new DelayOption { Display = "250 ms", Value = 250 },
- new DelayOption { Display = "300 ms", Value = 300 },
- new DelayOption { Display = "350 ms", Value = 350 },
- new DelayOption { Display = "400 ms", Value = 400 },
- new DelayOption { Display = "450 ms", Value = 450 },
- new DelayOption { Display = "500 ms", Value = 500 },
- };
-
- cbDelay.ItemsSource = delayOptions;
- }
-
- private void CbDelay_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (DataContext is ViewModel.PluginViewModel viewModel && cbDelay.SelectedItem is DelayOption selectedOption)
- {
- // int 값을 SearchDelayTime enum으로 변환
- int delayValue = selectedOption.Value;
- viewModel.PluginPair.Metadata.SearchDelayTime = (SearchDelayTime)delayValue;
-
- // 설정 저장
- //How to save?
- }
- }
- }
-
- public class DelayOption
- {
- public string Display { get; set; }
- public int Value { get; set; }
- }
-}
diff --git a/Flow.Launcher/SearchDelayTimeWindow.xaml b/Flow.Launcher/SearchDelayTimeWindow.xaml
deleted file mode 100644
index 1c7ca58d0a0..00000000000
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs b/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
deleted file mode 100644
index 4a3c9f5a730..00000000000
--- a/Flow.Launcher/SearchDelayTimeWindow.xaml.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System.Linq;
-using System.Windows;
-using Flow.Launcher.Plugin;
-using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.ViewModel;
-using static Flow.Launcher.SettingPages.ViewModels.SettingsPaneGeneralViewModel;
-
-namespace Flow.Launcher;
-
-public partial class SearchDelayTimeWindow : Window
-{
- private readonly PluginViewModel _pluginViewModel;
-
- public SearchDelayTimeWindow(PluginViewModel pluginViewModel)
- {
- InitializeComponent();
- _pluginViewModel = pluginViewModel;
- }
-
- private void SearchDelayTimeWindow_OnLoaded(object sender, RoutedEventArgs e)
- {
- tbSearchDelayTimeTips.Text = string.Format(App.API.GetTranslation("searchDelayTime_tips"),
- App.API.GetTranslation("default"));
- tbOldSearchDelayTime.Text = _pluginViewModel.SearchDelayTimeText;
- var searchDelayTimes = DropdownDataGeneric.GetValues("SearchDelayTime");
- SearchDelayTimeData selected = null;
- // Because default value is SearchDelayTime.VeryShort, we need to get selected value before adding default value
- if (_pluginViewModel.PluginSearchDelayTime != null)
- {
- selected = searchDelayTimes.FirstOrDefault(x => x.Value == _pluginViewModel.PluginSearchDelayTime);
- }
- // Add default value to the beginning of the list
- // When _pluginViewModel.PluginSearchDelayTime equals null, we will select this
- searchDelayTimes.Insert(0, new SearchDelayTimeData { Display = App.API.GetTranslation("default"), LocalizationKey = "default" });
- selected ??= searchDelayTimes.FirstOrDefault();
- cbDelay.ItemsSource = searchDelayTimes;
- cbDelay.SelectedItem = selected;
- cbDelay.Focus();
- }
-
- private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
- {
- Close();
- }
-
- private void btnDone_OnClick(object sender, RoutedEventArgs _)
- {
- // Update search delay time
- var selected = cbDelay.SelectedItem as SearchDelayTimeData;
- SearchDelayTime? changedValue = selected?.LocalizationKey != "default" ? selected.Value : null;
- _pluginViewModel.PluginSearchDelayTime = changedValue;
-
- // Update search delay time text and close window
- _pluginViewModel.OnSearchDelayTimeChanged();
- Close();
- }
-}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index cec8c318c59..74e2d834072 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
+using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
@@ -31,7 +32,25 @@ public class SearchWindowScreenData : DropdownDataGeneric {
public class SearchWindowAlignData : DropdownDataGeneric { }
public class SearchPrecisionData : DropdownDataGeneric { }
public class LastQueryModeData : DropdownDataGeneric { }
- public class SearchDelayTimeData : DropdownDataGeneric { }
+ public class SearchDelayTimeData
+ {
+ public string Display { get; set; }
+ public int Value { get; set; }
+
+ public static List GetValues()
+ {
+ var settings = Ioc.Default.GetRequiredService();
+ var data = new List();
+
+ foreach (var value in settings.SearchDelayTimeRange)
+ {
+ var display = $"{value}ms";
+ data.Add(new SearchDelayTimeData { Display = display, Value = value });
+ }
+
+ return data;
+ }
+ }
public bool StartFlowLauncherOnSystemStartup
{
@@ -144,19 +163,15 @@ public bool PortableMode
public List LastQueryModes { get; } =
DropdownDataGeneric.GetValues("LastQuery");
- public List SearchDelayTimes { get; } =
- DropdownDataGeneric.GetValues("SearchDelayTime");
+ public List SearchDelayTimes { get; } = SearchDelayTimeData.GetValues();
public SearchDelayTimeData SearchDelayTime
{
- get => SearchDelayTimes.FirstOrDefault(x => x.Value == Settings.SearchDelayTime) ??
- SearchDelayTimes.FirstOrDefault(x => x.Value == Plugin.SearchDelayTime.Normal) ??
- SearchDelayTimes.FirstOrDefault();
+ get => SearchDelayTimes.FirstOrDefault(x => x.Value == Settings.SearchDelayTime);
set
{
- if (value == null)
- return;
-
+ if (value == null) return;
+
if (Settings.SearchDelayTime != value.Value)
{
Settings.SearchDelayTime = value.Value;
@@ -170,7 +185,6 @@ private void UpdateEnumDropdownLocalizations()
DropdownDataGeneric.UpdateLabels(SearchWindowAligns);
DropdownDataGeneric.UpdateLabels(SearchPrecisionScores);
DropdownDataGeneric.UpdateLabels(LastQueryModes);
- DropdownDataGeneric.UpdateLabels(SearchDelayTimes);
}
public string Language
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index e36c647a2bb..10e2b549a50 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -196,18 +196,21 @@
-
+
-
-
+ Sub="{DynamicResource searchDelayTimeToolTip}"
+ Type="InsideFit">
-
+
250,
- SearchDelayTime.Long => 200,
- SearchDelayTime.Normal => 150,
- SearchDelayTime.Short => 100,
- SearchDelayTime.VeryShort => 50,
- _ => 150
- };
+ var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
await Task.Delay(searchDelayTime, token);
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 2016d9c98bc..bf61b190294 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -95,7 +95,7 @@ public int Priority
}
}
- public SearchDelayTime? PluginSearchDelayTime
+ public int? PluginSearchDelayTime
{
get => PluginPair.Metadata.SearchDelayTime;
set
@@ -192,12 +192,5 @@ private void SetActionKeywords()
var changeKeywordsWindow = new ActionKeywords(this);
changeKeywordsWindow.ShowDialog();
}
-
- [RelayCommand]
- private void SetSearchDelayTime()
- {
- var searchDelayTimeWindow = new SearchDelayTimeWindow(this);
- searchDelayTimeWindow.ShowDialog();
- }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
index 64681f803b8..c8b6310a7c0 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
@@ -32,5 +32,5 @@
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
"IcoPath": "Images\\web_search.png",
- "SearchDelayTime": "VeryLong"
+ "SearchDelayTime": 450
}
From dfb6b0a3a300386fe668148d0429de9db7ea9b3a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 7 Apr 2025 14:26:35 +0800
Subject: [PATCH 0872/1335] Fix string resource issue
---
.../SettingPages/ViewModels/SettingsPanePluginsViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index af1653c93d0..46e398eb544 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -141,7 +141,7 @@ private async Task OpenHelperAsync()
},
new TextBlock
{
- Text = (string)Application.Current.Resources["searchDelayTime_tips"],
+ Text = (string)Application.Current.Resources["searchDelayTimeTips"],
TextWrapping = TextWrapping.Wrap
}
}
From 24bbfcc4139596ac6d3929da44e353508f426974 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 7 Apr 2025 14:27:33 +0800
Subject: [PATCH 0873/1335] Support numerical box for priority
---
Flow.Launcher/PriorityChangeWindow.xaml | 121 ------------------
Flow.Launcher/PriorityChangeWindow.xaml.cs | 67 ----------
.../Controls/InstalledPluginDisplay.xaml | 3 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 20 +--
4 files changed, 4 insertions(+), 207 deletions(-)
delete mode 100644 Flow.Launcher/PriorityChangeWindow.xaml
delete mode 100644 Flow.Launcher/PriorityChangeWindow.xaml.cs
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml b/Flow.Launcher/PriorityChangeWindow.xaml
deleted file mode 100644
index 33ed54bb4fa..00000000000
--- a/Flow.Launcher/PriorityChangeWindow.xaml
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs
deleted file mode 100644
index fbe2a941d26..00000000000
--- a/Flow.Launcher/PriorityChangeWindow.xaml.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Plugin;
-using Flow.Launcher.ViewModel;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using Flow.Launcher.Core;
-
-namespace Flow.Launcher
-{
- ///
- /// Interaction Logic of PriorityChangeWindow.xaml
- ///
- public partial class PriorityChangeWindow : Window
- {
- private readonly PluginPair plugin;
- private readonly Internationalization translater = InternationalizationManager.Instance;
- private readonly PluginViewModel pluginViewModel;
- public PriorityChangeWindow(string pluginId, PluginViewModel pluginViewModel)
- {
- InitializeComponent();
- plugin = PluginManager.GetPluginForId(pluginId);
- this.pluginViewModel = pluginViewModel;
- if (plugin == null)
- {
- App.API.ShowMsgBox(translater.GetTranslation("cannotFindSpecifiedPlugin"));
- Close();
- }
- }
-
- private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
- {
- Close();
- }
-
- private void btnDone_OnClick(object sender, RoutedEventArgs e)
- {
- if (int.TryParse(tbAction.Text.Trim(), out var newPriority))
- {
- pluginViewModel.ChangePriority(newPriority);
- Close();
- }
- else
- {
- string msg = translater.GetTranslation("invalidPriority");
- App.API.ShowMsgBox(msg);
- }
-
- }
-
- private void PriorityChangeWindow_Loaded(object sender, RoutedEventArgs e)
- {
- tbAction.Text = pluginViewModel.Priority.ToString();
- tbAction.Focus();
- }
- private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
- {
- TextBox textBox = Keyboard.FocusedElement as TextBox;
- if (textBox != null)
- {
- TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next);
- textBox.MoveFocus(tRequest);
- }
- }
- }
-}
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 5ba011fede7..778f0016050 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -70,7 +70,8 @@
Maximum="999"
Minimum="-999"
SpinButtonPlacementMode="Inline"
- ToolTip="{DynamicResource priorityToolTip}" />
+ ToolTip="{DynamicResource priorityToolTip}"
+ Value="{Binding Priority, Mode=TwoWay}" />
PluginPair.Metadata.Priority;
set
{
- if (PluginPair.Metadata.Priority != value)
- {
- ChangePriority(value);
- }
+ PluginPair.Metadata.Priority = value;
+ PluginSettingsObject.Priority = value;
}
}
@@ -151,20 +149,6 @@ public void OnSearchDelayTimeChanged()
OnPropertyChanged(nameof(SearchDelayTimeText));
}
- public void ChangePriority(int newPriority)
- {
- PluginPair.Metadata.Priority = newPriority;
- PluginSettingsObject.Priority = newPriority;
- OnPropertyChanged(nameof(Priority));
- }
-
- [RelayCommand]
- private void EditPluginPriority()
- {
- var priorityChangeWindow = new PriorityChangeWindow(PluginPair. Metadata.ID, this);
- priorityChangeWindow.ShowDialog();
- }
-
[RelayCommand]
private void OpenPluginDirectory()
{
From 67268284e0e4ae612a5395973a58b6674b203c4f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 7 Apr 2025 14:40:27 +0800
Subject: [PATCH 0874/1335] Support numerical box for search delay
---
.../Controls/InstalledPluginDisplay.xaml | 3 ++-
Flow.Launcher/ViewModel/PluginViewModel.cs | 18 ++++++++++++++----
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 778f0016050..f57c0e2d967 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -91,7 +91,8 @@
Maximum="1000"
Minimum="0"
SpinButtonPlacementMode="Inline"
- ToolTip="{DynamicResource searchDelayToolTip}" />
+ ToolTip="{DynamicResource searchDelayToolTip}"
+ Value="{Binding PluginSearchDelayTime, Mode=TwoWay}" />
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 22a69592b9e..2dff72ac52b 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -93,13 +93,23 @@ public int Priority
}
}
- public int? PluginSearchDelayTime
+ public double PluginSearchDelayTime
{
- get => PluginPair.Metadata.SearchDelayTime;
+ get => PluginPair.Metadata.SearchDelayTime == null ?
+ double.NaN :
+ PluginPair.Metadata.SearchDelayTime.Value;
set
{
- PluginPair.Metadata.SearchDelayTime = value;
- PluginSettingsObject.SearchDelayTime = value;
+ if (double.IsNaN(value))
+ {
+ PluginPair.Metadata.SearchDelayTime = null;
+ PluginSettingsObject.SearchDelayTime = null;
+ }
+ else
+ {
+ PluginPair.Metadata.SearchDelayTime = (int)value;
+ PluginSettingsObject.SearchDelayTime = (int)value;
+ }
}
}
From 5c09598f213f3eb4af993364d55e95f48b4a8f8a Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 7 Apr 2025 15:47:40 +0900
Subject: [PATCH 0875/1335] Add Infobar strings for korean
---
Flow.Launcher/Languages/en.xaml | 10 ++++++++++
.../SettingPages/Views/SettingsPaneGeneral.xaml | 10 +++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 24ab3cf9477..3de278eca86 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -116,6 +116,16 @@
Normal
Short
Very short
+ Information for Korean IME user
+
+ You're using the Korean language! The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+ If you experience any problems, you may need to enable compatibility mode for the Korean IME.
+ Open Setting in Windows 11 and go to:
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+ and enable "Use previous version of Microsoft IME".
+ You can open the relevant menu using the option below, or change the setting directly without manually opening the settings page.
+
+ Very short
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 91f64858657..431293a5066 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -56,12 +56,12 @@
Message="This is a success message."
Type="Error" />
+ IsIconVisible="True"
+ Length="Long"
+ Message="{DynamicResource KoreanImeGuide}"
+ Type="Warning" />
Date: Mon, 7 Apr 2025 14:54:09 +0800
Subject: [PATCH 0876/1335] Force priority to 0 when inputing empty
---
.../Resources/Controls/InstalledPluginDisplay.xaml | 1 +
.../Controls/InstalledPluginDisplay.xaml.cs | 12 +++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index f57c0e2d967..ece66034c40 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -71,6 +71,7 @@
Minimum="-999"
SpinButtonPlacementMode="Inline"
ToolTip="{DynamicResource priorityToolTip}"
+ ValueChanged="NumberBox_OnValueChanged"
Value="{Binding Priority, Mode=TwoWay}" />
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
index dfa03a2043f..ab9496266f3 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
@@ -1,4 +1,6 @@
-namespace Flow.Launcher.Resources.Controls;
+using ModernWpf.Controls;
+
+namespace Flow.Launcher.Resources.Controls;
public partial class InstalledPluginDisplay
{
@@ -6,4 +8,12 @@ public InstalledPluginDisplay()
{
InitializeComponent();
}
+
+ private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
+ {
+ if (double.IsNaN(args.NewValue))
+ {
+ sender.Value = 0;
+ }
+ }
}
From e955e47e5fafcf54b6aa651dcc04db7ed9355523 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 7 Apr 2025 22:47:39 +0900
Subject: [PATCH 0877/1335] - Change combobox to numberbox - Adjust Numberbox
Style - Add small change value(10) - Adjust strings
---
.../UserSettings/Settings.cs | 4 ---
Flow.Launcher/Languages/en.xaml | 10 ++----
.../Controls/InstalledPluginDisplay.xaml | 7 ++--
.../Resources/CustomControlTemplate.xaml | 28 ++++++++++-----
.../SettingsPaneGeneralViewModel.cs | 35 +++++--------------
.../SettingsPanePluginsViewModel.cs | 4 +--
.../Views/SettingsPaneGeneral.xaml | 17 +++++----
7 files changed, 49 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index d89340e1942..e304a1b5040 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -321,10 +321,6 @@ public bool HideNotifyIcon
public bool HideWhenDeactivated { get; set; } = true;
public bool SearchQueryResultsWithDelay { get; set; }
-
- [JsonIgnore]
- public IEnumerable SearchDelayTimeRange = new List { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500 };
-
public int SearchDelayTime { get; set; } = 150;
[JsonConverter(typeof(JsonStringEnumConverter))]
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 5d9b16e0b60..f01d0575a83 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -108,14 +108,10 @@
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Default
Search Plugin
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index ece66034c40..9a4e3b7b057 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -88,12 +88,15 @@
Text="{DynamicResource searchDelay}"
ToolTip="{DynamicResource searchDelayToolTip}" />
+ Value="{Binding PluginSearchDelayTime, Mode=TwoWay}">
+
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index b51e5fec063..157910b4a1a 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -1503,7 +1503,7 @@
-
+
@@ -2689,10 +2689,20 @@
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
ui:ValidationHelper.IsTemplateValidationAdornerSite="True"
- Background="{TemplateBinding Background}"
- BorderBrush="{TemplateBinding BorderBrush}"
- BorderThickness="{TemplateBinding BorderThickness}"
- CornerRadius="{TemplateBinding ui:ControlHelper.CornerRadius}" />
+ Background="{DynamicResource CustomTextBoxBG}"
+ BorderBrush="{DynamicResource CustomTextBoxOutline}"
+ BorderThickness="{DynamicResource CustomTextBoxOutlineThickness}"
+ CornerRadius="4">
+
+
-
+
@@ -2788,8 +2798,10 @@
-
-
+
+
+
+
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 74e2d834072..35dbab64776 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -32,25 +32,7 @@ public class SearchWindowScreenData : DropdownDataGeneric {
public class SearchWindowAlignData : DropdownDataGeneric { }
public class SearchPrecisionData : DropdownDataGeneric { }
public class LastQueryModeData : DropdownDataGeneric { }
- public class SearchDelayTimeData
- {
- public string Display { get; set; }
- public int Value { get; set; }
-
- public static List GetValues()
- {
- var settings = Ioc.Default.GetRequiredService();
- var data = new List();
-
- foreach (var value in settings.SearchDelayTimeRange)
- {
- var display = $"{value}ms";
- data.Add(new SearchDelayTimeData { Display = display, Value = value });
- }
-
- return data;
- }
- }
+
public bool StartFlowLauncherOnSystemStartup
{
@@ -163,21 +145,20 @@ public bool PortableMode
public List LastQueryModes { get; } =
DropdownDataGeneric.GetValues("LastQuery");
- public List SearchDelayTimes { get; } = SearchDelayTimeData.GetValues();
-
- public SearchDelayTimeData SearchDelayTime
+ public int SearchDelayTimeValue
{
- get => SearchDelayTimes.FirstOrDefault(x => x.Value == Settings.SearchDelayTime);
+ get => Settings.SearchDelayTime;
set
{
- if (value == null) return;
-
- if (Settings.SearchDelayTime != value.Value)
+ if (Settings.SearchDelayTime != value)
{
- Settings.SearchDelayTime = value.Value;
+ Settings.SearchDelayTime = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(SearchDelayTimeDisplay));
}
}
}
+ public string SearchDelayTimeDisplay => $"{SearchDelayTimeValue}ms";
private void UpdateEnumDropdownLocalizations()
{
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 46e398eb544..4958bb7b748 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -122,7 +122,7 @@ private async Task OpenHelperAsync()
{
new TextBlock
{
- Text = (string)Application.Current.Resources["changePriorityWindow"],
+ Text = (string)Application.Current.Resources["priority"],
FontSize = 18,
Margin = new Thickness(0, 0, 0, 10),
TextWrapping = TextWrapping.Wrap
@@ -134,7 +134,7 @@ private async Task OpenHelperAsync()
},
new TextBlock
{
- Text = (string)Application.Current.Resources["searchDelayTimeTitle"],
+ Text = (string)Application.Current.Resources["searchDelay"],
FontSize = 18,
Margin = new Thickness(0, 24, 0, 10),
TextWrapping = TextWrapping.Wrap
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 10e2b549a50..657e97f30a8 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -211,12 +211,17 @@
Title="{DynamicResource searchDelayTime}"
Sub="{DynamicResource searchDelayTimeToolTip}"
Type="InsideFit">
-
+
+
+
From cbf50317d3cb87bd62dbb42ee39adcd6719bbeee Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 8 Apr 2025 00:02:59 +0900
Subject: [PATCH 0878/1335] Fix content dialog style
---
.../Resources/CustomControlTemplate.xaml | 24 ++++++++++++-------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index 157910b4a1a..d788294716d 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -3587,7 +3587,7 @@
-
+
-
+
+
+
+
+
+
+
+
From 736837ebe8c3ce2babe80d5f1b5a95905aae3ca2 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 8 Apr 2025 15:23:23 +0900
Subject: [PATCH 0879/1335] Add function for switch and button
---
Flow.Launcher/Languages/en.xaml | 6 +-
.../SettingsPaneGeneralViewModel.cs | 118 +++++++++++++++---
.../Views/SettingsPaneGeneral.xaml | 62 +++++----
3 files changed, 131 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 3de278eca86..c4c87dbc4e2 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -125,7 +125,11 @@
and enable "Use previous version of Microsoft IME".
You can open the relevant menu using the option below, or change the setting directly without manually opening the settings page.
- Very short
+ Open Language and Region System Settings
+ Opens the Korean IME setting locationKorean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Open
+ Use Legacy Korean IME
+ You can change the IME settings directly from here without opening a separate settings window
Search Plugin
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index a1b38a53cfc..dcd17cf246d 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -13,6 +13,8 @@
using Flow.Launcher.Plugin.SharedModels;
using Microsoft.Win32;
using OpenFileDialog = System.Windows.Forms.OpenFileDialog;
+using System.Windows.Input;
+
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -21,7 +23,8 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
public Settings Settings { get; }
private readonly Updater _updater;
private readonly IPortable _portable;
-
+ public ICommand OpenImeSettingsCommand { get; }
+
public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable)
{
Settings = settings;
@@ -29,6 +32,7 @@ public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortabl
_portable = portable;
UpdateEnumDropdownLocalizations();
IsLegacyKoreanIMEEnabled();
+ OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
public class SearchWindowScreenData : DropdownDataGeneric { }
@@ -190,37 +194,100 @@ public string Language
UpdateEnumDropdownLocalizations();
}
}
+
+ public bool LegacyKoreanIMEEnabled
+ {
+ get => IsLegacyKoreanIMEEnabled();
+ set
+ {
+ SetLegacyKoreanIMEEnabled(value);
+ OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ }
+ }
+
+ public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+
+ public bool KoreanIMERegistryValueIsZero
+ {
+ get
+ {
+ object value = GetLegacyKoreanIMERegistryValue();
+ if (value is int intValue)
+ {
+ return intValue == 0;
+ }
+ else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ {
+ return parsedValue == 0;
+ }
+
+ return false;
+ }
+ }
+
+ bool IsKoreanIMEExist()
+ {
+ return GetLegacyKoreanIMERegistryValue() != null;
+ }
bool IsLegacyKoreanIMEEnabled()
+ {
+ object value = GetLegacyKoreanIMERegistryValue();
+
+ if (value is int intValue)
+ {
+ return intValue == 1;
+ }
+ else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ {
+ return parsedValue == 1;
+ }
+
+ return false;
+ }
+
+ bool SetLegacyKoreanIMEEnabled(bool enable)
{
const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
const string valueName = "NoTsf3Override5";
try
{
- using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
+ using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
{
if (key != null)
{
- object value = key.GetValue(valueName);
- if (value != null)
- {
- Debug.WriteLine($"[IME DEBUG] '{valueName}' 값: {value} (타입: {value.GetType()})");
-
- if (value is int intValue)
- return intValue == 1;
-
- if (int.TryParse(value.ToString(), out int parsed))
- return parsed == 1;
- }
- else
- {
- Debug.WriteLine($"[IME DEBUG] '{valueName}' 값이 존재하지 않습니다.");
- }
+ int value = enable ? 1 : 0;
+ key.SetValue(valueName, value, RegistryValueKind.DWord);
+ return true;
}
else
{
- Debug.WriteLine($"[IME DEBUG] 레지스트리 키를 찾을 수 없습니다: {subKeyPath}");
+ Debug.WriteLine($"[IME DEBUG] 레지스트리 키 생성 또는 열기 실패: {subKeyPath}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[IME DEBUG] 레지스트리 설정 중 예외 발생: {ex.Message}");
+ }
+
+ return false;
+ }
+
+ private object GetLegacyKoreanIMERegistryValue()
+ {
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
+ {
+ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
+ {
+ if (key != null)
+ {
+ return key.GetValue(valueName);
}
}
}
@@ -229,10 +296,21 @@ bool IsLegacyKoreanIMEEnabled()
Debug.WriteLine($"[IME DEBUG] 예외 발생: {ex.Message}");
}
- return false; // 기본적으로 새 IME 사용 중으로 간주
+ return null;
+ }
+
+ private void OpenImeSettings()
+ {
+ try
+ {
+ Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine($"Error opening IME settings: {e.Message}");
+ }
}
-
public bool ShouldUsePinyin
{
get => Settings.ShouldUsePinyin;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 431293a5066..1d4dfd8ae84 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -8,12 +8,16 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:settingsViewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels"
xmlns:ui="http://schemas.modernwpf.com/2019"
+ xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
Title="General"
d:DataContext="{d:DesignInstance settingsViewModels:SettingsPaneGeneralViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
From ecd019dd6b0c286a6cf223cf598bc1fc57dd4279 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 15:56:54 +0800
Subject: [PATCH 0880/1335] Move ThemeData class to SharedModels
---
Flow.Launcher.Core/Resource/Theme.cs | 1 +
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 +++---
Flow.Launcher.Plugin/{ => SharedModels}/ThemeData.cs | 2 +-
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 1 +
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 1 +
5 files changed, 7 insertions(+), 4 deletions(-)
rename Flow.Launcher.Plugin/{ => SharedModels}/ThemeData.cs (97%)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 4cf9ce7a714..f3eba7ba7fd 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -16,6 +16,7 @@
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedModels;
using Microsoft.Win32;
namespace Flow.Launcher.Core.Resource
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 64bdcec3474..1090a3a1e9f 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -1,6 +1,4 @@
-using Flow.Launcher.Plugin.SharedModels;
-using JetBrains.Annotations;
-using System;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
@@ -8,6 +6,8 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using Flow.Launcher.Plugin.SharedModels;
+using JetBrains.Annotations;
namespace Flow.Launcher.Plugin
{
diff --git a/Flow.Launcher.Plugin/ThemeData.cs b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
similarity index 97%
rename from Flow.Launcher.Plugin/ThemeData.cs
rename to Flow.Launcher.Plugin/SharedModels/ThemeData.cs
index 1888be65e1d..6a5e54f5508 100644
--- a/Flow.Launcher.Plugin/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Plugin;
+namespace Flow.Launcher.Plugin.SharedModels;
///
/// Theme data model
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 58cf3a314b5..f78704ef2d5 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -12,6 +12,7 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using ModernWpf;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index 4b99efe3b1a..feacc3f9921 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using Flow.Launcher.Plugin.SharedModels;
namespace Flow.Launcher.Plugin.Sys
{
From 6c458828bc9d24a58de29240f1417c253c64a7d6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:01:46 +0800
Subject: [PATCH 0881/1335] Fix possible NullReferenceException
---
Flow.Launcher.Plugin/SharedModels/ThemeData.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
index 6a5e54f5508..322985f3a9b 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -41,12 +41,16 @@ public ThemeData(string fileNameWithoutExtension, string name, bool? isDark = nu
///
public static bool operator ==(ThemeData left, ThemeData right)
{
+ if (left is null && right is null)
+ return true;
return left.Equals(right);
}
///
public static bool operator !=(ThemeData left, ThemeData right)
{
+ if (left is null && right is null)
+ return false;
return !(left == right);
}
From 6c5bb7d184d1f5a1284f94647e6f34ce1f0b2b84 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 8 Apr 2025 18:12:10 +1000
Subject: [PATCH 0882/1335] update summary
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 30004952e97..111bc716c97 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -228,7 +228,7 @@ public interface IPublicAPI
void LogWarn(string className, string message, [CallerMemberName] string methodName = "");
///
- /// Log error message
+ /// Log error message. Preferred error logging method for plugins.
///
void LogError(string className, string message, [CallerMemberName] string methodName = "");
From 537c03f2d751345176bbeacf1d58a657da3aef31 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:13:58 +0800
Subject: [PATCH 0883/1335] Fix null check issue
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher.Plugin/SharedModels/ThemeData.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
index 322985f3a9b..093e1ee8e55 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -43,6 +43,8 @@ public ThemeData(string fileNameWithoutExtension, string name, bool? isDark = nu
{
if (left is null && right is null)
return true;
+ if (left is null || right is null)
+ return false;
return left.Equals(right);
}
From b3aa89773ce1fdfadc9dfd06b13acc596d504265 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:14:17 +0800
Subject: [PATCH 0884/1335] Use == for != operator
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher.Plugin/SharedModels/ThemeData.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
index 093e1ee8e55..cb389c21fbc 100644
--- a/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
+++ b/Flow.Launcher.Plugin/SharedModels/ThemeData.cs
@@ -51,8 +51,6 @@ public ThemeData(string fileNameWithoutExtension, string name, bool? isDark = nu
///
public static bool operator !=(ThemeData left, ThemeData right)
{
- if (left is null && right is null)
- return false;
return !(left == right);
}
From a2d99573855b145a4ac68f270494c05f07ea06a6 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:20:11 +0800
Subject: [PATCH 0885/1335] Log warning if cannot find matched theme
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Core/Resource/Theme.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index f3eba7ba7fd..d7c6193302e 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -384,7 +384,12 @@ private string GetThemePath(string themeName)
public ThemeData GetCurrentTheme()
{
var themes = GetAvailableThemes();
- return themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme) ?? themes.FirstOrDefault();
+ var matchingTheme = themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme);
+ if (matchingTheme == null)
+ {
+ Log.Warn($"No matching theme found for '{_settings.Theme}'. Falling back to the first available theme.");
+ }
+ return matchingTheme ?? themes.FirstOrDefault();
}
public List GetAvailableThemes()
From 7da2884e84ebd45dc70c16cd3dde6f6ef1e2b4af Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:29:03 +0800
Subject: [PATCH 0886/1335] Add locks for win32s & uwps
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 61 +++++++++++++++----
.../Views/Commands/ProgramSettingDisplay.cs | 34 ++++++++---
.../Views/ProgramSetting.xaml.cs | 18 +++---
3 files changed, 83 insertions(+), 30 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index d3c50b40649..6d2ae70fcdd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -27,6 +27,9 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
internal static List _uwps { get; private set; }
internal static Settings _settings { get; private set; }
+ internal static SemaphoreSlim _win32sLock = new(1, 1);
+ internal static SemaphoreSlim _uwpsLock = new(1, 1);
+
internal static PluginInitContext Context { get; private set; }
private static readonly List emptyResults = new();
@@ -82,8 +85,11 @@ public async Task> QueryAsync(Query query, CancellationToken token)
{
var result = await cache.GetOrCreateAsync(query.Search, async entry =>
{
- var resultList = await Task.Run(() =>
+ var resultList = await Task.Run(async () =>
{
+ await _win32sLock.WaitAsync(token);
+ await _uwpsLock.WaitAsync(token);
+
try
{
// Collect all UWP Windows app directories
@@ -95,22 +101,26 @@ public async Task> QueryAsync(Query query, CancellationToken token)
.ToArray() : null;
return _win32s.Cast()
- .Concat(_uwps)
- .AsParallel()
- .WithCancellation(token)
- .Where(HideUninstallersFilter)
- .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
- .Where(p => p.Enabled)
- .Select(p => p.Result(query.Search, Context.API))
- .Where(r => r?.Score > 0)
- .ToList();
+ .Concat(_uwps)
+ .AsParallel()
+ .WithCancellation(token)
+ .Where(HideUninstallersFilter)
+ .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
+ .Where(p => p.Enabled)
+ .Select(p => p.Result(query.Search, Context.API))
+ .Where(r => r?.Score > 0)
+ .ToList();
}
catch (OperationCanceledException)
{
Log.Debug("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
return emptyResults;
}
-
+ finally
+ {
+ _uwpsLock.Release();
+ _win32sLock.Release();
+ }
}, token);
resultList = resultList.Any() ? resultList : emptyResults;
@@ -236,14 +246,25 @@ static void MoveFile(string sourcePath, string destinationPath)
var newUWPCacheFile = Path.Combine(pluginCachePath, $"{UwpCacheName}.cache");
MoveFile(oldUWPCacheFile, newUWPCacheFile);
+ await _win32sLock.WaitAsync();
_win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCachePath, new List());
+ _win32sLock.Release();
+
+ await _uwpsLock.WaitAsync();
_uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCachePath, new List());
+ _uwpsLock.Release();
});
+ await _win32sLock.WaitAsync();
+ await _uwpsLock.WaitAsync();
+
Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Count}>");
Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwps.Count}>");
bool cacheEmpty = !_win32s.Any() || !_uwps.Any();
+ _win32sLock.Release();
+ _uwpsLock.Release();
+
if (cacheEmpty || _settings.LastIndexTime.AddHours(30) < DateTime.Now)
{
_ = Task.Run(async () =>
@@ -267,11 +288,13 @@ static void WatchProgramUpdate()
public static async Task IndexWin32ProgramsAsync()
{
var win32S = Win32.All(_settings);
+ await _win32sLock.WaitAsync();
_win32s.Clear();
foreach (var win32 in win32S)
{
_win32s.Add(win32);
}
+ _win32sLock.Release();
ResetCache();
await Context.API.SaveCacheBinaryStorageAsync>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
@@ -280,11 +303,13 @@ public static async Task IndexWin32ProgramsAsync()
public static async Task IndexUwpProgramsAsync()
{
var uwps = UWPPackage.All(_settings);
+ await _uwpsLock.WaitAsync();
_uwps.Clear();
foreach (var uwp in uwps)
{
_uwps.Add(uwp);
}
+ _uwpsLock.Release();
ResetCache();
await Context.API.SaveCacheBinaryStorageAsync>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
@@ -358,26 +383,36 @@ public List LoadContextMenus(Result selectedResult)
return menuOptions;
}
- private static void DisableProgram(IProgram programToDelete)
+ private static async Task DisableProgram(IProgram programToDelete)
{
if (_settings.DisabledProgramSources.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
return;
+ await _uwpsLock.WaitAsync();
if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
{
var program = _uwps.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
+ _uwpsLock.Release();
+
+ // Reindex UWP programs
_ = Task.Run(() =>
{
_ = IndexUwpProgramsAsync();
});
+ return;
}
- else if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
+
+ await _win32sLock.WaitAsync();
+ if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
{
var program = _win32s.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
+ _win32sLock.Release();
+
+ // Reindex Win32 programs
_ = Task.Run(() =>
{
_ = IndexWin32ProgramsAsync();
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs
index e4d7c323a5f..b89a2a6ba9e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/Commands/ProgramSettingDisplay.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using Flow.Launcher.Plugin.Program.Views.Models;
namespace Flow.Launcher.Plugin.Program.Views.Commands
@@ -15,21 +16,24 @@ internal static List LoadProgramSources()
.ToList();
}
- internal static void DisplayAllPrograms()
+ internal static async Task DisplayAllProgramsAsync()
{
+ await Main._win32sLock.WaitAsync();
var win32 = Main._win32s
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
.Select(x => new ProgramSource(x));
+ ProgramSetting.ProgramSettingDisplayList.AddRange(win32);
+ Main._win32sLock.Release();
+ await Main._uwpsLock.WaitAsync();
var uwp = Main._uwps
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
.Select(x => new ProgramSource(x));
-
- ProgramSetting.ProgramSettingDisplayList.AddRange(win32);
ProgramSetting.ProgramSettingDisplayList.AddRange(uwp);
+ Main._uwpsLock.Release();
}
- internal static void SetProgramSourcesStatus(List selectedProgramSourcesToDisable, bool status)
+ internal static async Task SetProgramSourcesStatusAsync(List selectedProgramSourcesToDisable, bool status)
{
foreach(var program in ProgramSetting.ProgramSettingDisplayList)
{
@@ -39,14 +43,17 @@ internal static void SetProgramSourcesStatus(List selectedProgram
}
}
- foreach(var program in Main._win32s)
+ await Main._win32sLock.WaitAsync();
+ foreach (var program in Main._win32s)
{
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
{
program.Enabled = status;
}
}
+ Main._win32sLock.Release();
+ await Main._uwpsLock.WaitAsync();
foreach (var program in Main._uwps)
{
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
@@ -54,6 +61,7 @@ internal static void SetProgramSourcesStatus(List selectedProgram
program.Enabled = status;
}
}
+ Main._uwpsLock.Release();
}
internal static void StoreDisabledInSettings()
@@ -72,12 +80,22 @@ internal static void RemoveDisabledFromSettings()
Main._settings.DisabledProgramSources.RemoveAll(t1 => t1.Enabled);
}
- internal static bool IsReindexRequired(this List selectedItems)
+ internal static async Task IsReindexRequiredAsync(this List selectedItems)
{
// Not in cache
- if (selectedItems.Any(t1 => t1.Enabled && !Main._uwps.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier))
+ await Main._win32sLock.WaitAsync();
+ await Main._uwpsLock.WaitAsync();
+ try
+ {
+ if (selectedItems.Any(t1 => t1.Enabled && !Main._uwps.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier))
&& selectedItems.Any(t1 => t1.Enabled && !Main._win32s.Any(x => t1.UniqueIdentifier == x.UniqueIdentifier)))
- return true;
+ return true;
+ }
+ finally
+ {
+ Main._win32sLock.Release();
+ Main._uwpsLock.Release();
+ }
// ProgramSources holds list of user added directories,
// so when we enable/disable we need to reindex to show/not show the programs
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 5ad7fcea369..c42bd4f305d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -183,7 +183,7 @@ private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
EditProgramSource(selectedProgramSource);
}
- private void EditProgramSource(ProgramSource selectedProgramSource)
+ private async void EditProgramSource(ProgramSource selectedProgramSource)
{
if (selectedProgramSource == null)
{
@@ -202,13 +202,13 @@ private void EditProgramSource(ProgramSource selectedProgramSource)
{
if (selectedProgramSource.Enabled)
{
- ProgramSettingDisplay.SetProgramSourcesStatus(new List { selectedProgramSource },
+ await ProgramSettingDisplay.SetProgramSourcesStatusAsync(new List { selectedProgramSource },
true); // sync status in win32, uwp and disabled
ProgramSettingDisplay.RemoveDisabledFromSettings();
}
else
{
- ProgramSettingDisplay.SetProgramSourcesStatus(new List { selectedProgramSource },
+ await ProgramSettingDisplay.SetProgramSourcesStatusAsync(new List { selectedProgramSource },
false);
ProgramSettingDisplay.StoreDisabledInSettings();
}
@@ -277,14 +277,14 @@ private void programSourceView_Drop(object sender, DragEventArgs e)
}
}
- private void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArgs e)
+ private async void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArgs e)
{
- ProgramSettingDisplay.DisplayAllPrograms();
+ await ProgramSettingDisplay.DisplayAllProgramsAsync();
ViewRefresh();
}
- private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
+ private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
{
var selectedItems = programSourceView
.SelectedItems.Cast()
@@ -311,18 +311,18 @@ private void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
}
else if (HasMoreOrEqualEnabledItems(selectedItems))
{
- ProgramSettingDisplay.SetProgramSourcesStatus(selectedItems, false);
+ await ProgramSettingDisplay.SetProgramSourcesStatusAsync(selectedItems, false);
ProgramSettingDisplay.StoreDisabledInSettings();
}
else
{
- ProgramSettingDisplay.SetProgramSourcesStatus(selectedItems, true);
+ await ProgramSettingDisplay.SetProgramSourcesStatusAsync(selectedItems, true);
ProgramSettingDisplay.RemoveDisabledFromSettings();
}
- if (selectedItems.IsReindexRequired())
+ if (await selectedItems.IsReindexRequiredAsync())
ReIndexing();
programSourceView.SelectedItems.Clear();
From dd210ad41968a1e9112fb6b364a08093534ae136 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:41:06 +0800
Subject: [PATCH 0887/1335] Remove RefreshFrameAsync since ChangeTheme calls
this function
---
Flow.Launcher.Core/Resource/Theme.cs | 2 +-
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 6 ++++--
Flow.Launcher/PublicAPIInstance.cs | 5 +----
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index d7c6193302e..59e76e2d2e9 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -433,7 +433,7 @@ public bool ChangeTheme(string theme = null)
BlurEnabled = IsBlurTheme();
- // Can only apply blur but here also apply drop shadow effect to avoid possible drop shadow effect issues
+ // Apply blur and drop shadow effect so that we do not need to call it again
_ = RefreshFrameAsync();
return true;
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 056c4a437b0..7701fcdd05a 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -367,8 +367,10 @@ public interface IPublicAPI
/// Set the current theme
///
///
- ///
- public void SetCurrentTheme(ThemeData theme);
+ ///
+ /// True if the theme is set successfully, false otherwise.
+ ///
+ public bool SetCurrentTheme(ThemeData theme);
/// Load image from path. Support local, remote and data:image url.
/// If image path is missing, it will return a missing icon.
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b19b21db12c..8cce460d7e0 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -377,11 +377,8 @@ public Task ShowProgressBoxAsync(string caption, Func, Task> repo
public ThemeData GetCurrentTheme() => Theme.GetCurrentTheme();
- public void SetCurrentTheme(ThemeData theme)
- {
+ public bool SetCurrentTheme(ThemeData theme) =>
Theme.ChangeTheme(theme.FileNameWithoutExtension);
- _ = _theme.RefreshFrameAsync();
- }
public ValueTask LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true) =>
ImageLoader.LoadAsync(path, loadFullImage, cacheImage);
From a3c7be95597f8c0765f0e62749b7f263749e78cd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:49:29 +0800
Subject: [PATCH 0888/1335] Handle results from SetCurrentTheme
---
Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
index feacc3f9921..f8aeaeafdff 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -76,8 +76,10 @@ private Result CreateThemeResult(ThemeData theme, ThemeData selectedTheme, int s
Score = score,
Action = c =>
{
- _context.API.SetCurrentTheme(theme);
- _context.API.ReQuery();
+ if (_context.API.SetCurrentTheme(theme))
+ {
+ _context.API.ReQuery();
+ }
return false;
}
};
From 734c5bb67deb769190fa46572083e64ffcef8cf8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 16:59:27 +0800
Subject: [PATCH 0889/1335] Fix lock release issue
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 6d2ae70fcdd..a5fbc6c70cb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -367,7 +367,7 @@ public List LoadContextMenus(Result selectedResult)
Title = Context.API.GetTranslation("flowlauncher_plugin_program_disable_program"),
Action = c =>
{
- DisableProgram(program);
+ _ = DisableProgramAsync(program);
Context.API.ShowMsg(
Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_success"),
Context.API.GetTranslation(
@@ -383,7 +383,7 @@ public List LoadContextMenus(Result selectedResult)
return menuOptions;
}
- private static async Task DisableProgram(IProgram programToDelete)
+ private static async Task DisableProgramAsync(IProgram programToDelete)
{
if (_settings.DisabledProgramSources.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
return;
@@ -403,7 +403,12 @@ private static async Task DisableProgram(IProgram programToDelete)
});
return;
}
-
+ else
+ {
+ // Release the lock if we cannot find the program
+ _uwpsLock.Release();
+ }
+
await _win32sLock.WaitAsync();
if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
{
@@ -418,6 +423,11 @@ private static async Task DisableProgram(IProgram programToDelete)
_ = IndexWin32ProgramsAsync();
});
}
+ else
+ {
+ // Release the lock if we cannot find the program
+ _win32sLock.Release();
+ }
}
public static void StartProcess(Func runProcess, ProcessStartInfo info)
From c11ee2f9e78fa626bd7801fed293d990fdfaf682 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 17:20:57 +0800
Subject: [PATCH 0890/1335] Improve code quality & comments & Fix lock issue
---
.../Storage/BinaryStorage.cs | 6 ++--
.../Storage/PluginJsonStorage.cs | 1 +
Flow.Launcher.Plugin/Interfaces/ISavable.cs | 9 ++++--
Flow.Launcher/PublicAPIInstance.cs | 6 ----
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 29 +++++++------------
5 files changed, 20 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index f218c5d8d0d..b5de3b50ff1 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -42,8 +42,7 @@ public BinaryStorage(string filename)
public async ValueTask TryLoadAsync(T defaultData)
{
- if (Data != null)
- return Data;
+ if (Data != null) return Data;
if (File.Exists(FilePath))
{
@@ -55,8 +54,7 @@ public async ValueTask TryLoadAsync(T defaultData)
}
await using var stream = new FileStream(FilePath, FileMode.Open);
- var d = await DeserializeAsync(stream, defaultData);
- Data = d;
+ Data = await DeserializeAsync(stream, defaultData);
}
else
{
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index b63e8c1ef70..e8cbd70fb98 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -20,6 +20,7 @@ namespace Flow.Launcher.Infrastructure.Storage
public PluginJsonStorage()
{
+ // C# related, add python related below
var dataType = typeof(T);
AssemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, AssemblyName);
diff --git a/Flow.Launcher.Plugin/Interfaces/ISavable.cs b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
index cabd269624e..0d23c0fc8cd 100644
--- a/Flow.Launcher.Plugin/Interfaces/ISavable.cs
+++ b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
@@ -1,18 +1,21 @@
namespace Flow.Launcher.Plugin
{
///
- /// Inherit this interface if additional data e.g. cache needs to be saved.
+ /// Inherit this interface if additional data.
+ /// If you need to save data which is not a setting or cache,
+ /// please implement this interface.
///
///
/// For storing plugin settings, prefer
/// or .
+ /// For storing plugin caches, prefer
/// or .
- /// Once called, your settings will be automatically saved by Flow.
+ /// Once called, those settings and caches will be automatically saved by Flow.
///
public interface ISavable : IFeatures
{
///
- /// Save additional plugin data, such as cache.
+ /// Save additional plugin data.
///
void Save();
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 4dd0268d25c..a523f90bb8f 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -229,9 +229,6 @@ public void RemovePluginSettings(string assemblyName)
}
}
- ///
- /// Save plugin settings.
- ///
public void SavePluginSettings()
{
foreach (var value in _pluginJsonStorages.Values)
@@ -378,9 +375,6 @@ public void RemovePluginCaches(string cacheDirectory)
}
}
- ///
- /// Save plugin caches.
- ///
public void SavePluginCaches()
{
foreach (var value in _pluginBinaryStorages.Values)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index a5fbc6c70cb..561044981f5 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -77,10 +77,6 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
private static readonly string WindowsAppPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsApps");
- static Main()
- {
- }
-
public async Task> QueryAsync(Query query, CancellationToken token)
{
var result = await cache.GetOrCreateAsync(query.Search, async entry =>
@@ -101,15 +97,15 @@ public async Task> QueryAsync(Query query, CancellationToken token)
.ToArray() : null;
return _win32s.Cast()
- .Concat(_uwps)
- .AsParallel()
- .WithCancellation(token)
- .Where(HideUninstallersFilter)
- .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
- .Where(p => p.Enabled)
- .Select(p => p.Result(query.Search, Context.API))
- .Where(r => r?.Score > 0)
- .ToList();
+ .Concat(_uwps)
+ .AsParallel()
+ .WithCancellation(token)
+ .Where(HideUninstallersFilter)
+ .Where(p => HideDuplicatedWindowsAppFilter(p, uwpsDirectories))
+ .Where(p => p.Enabled)
+ .Select(p => p.Result(query.Search, Context.API))
+ .Where(r => r?.Score > 0)
+ .ToList();
}
catch (OperationCanceledException)
{
@@ -193,7 +189,6 @@ public async Task InitAsync(PluginInitContext context)
await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
{
var pluginCachePath = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
-
FilesFolders.ValidateDirectory(pluginCachePath);
static void MoveFile(string sourcePath, string destinationPath)
@@ -294,10 +289,10 @@ public static async Task IndexWin32ProgramsAsync()
{
_win32s.Add(win32);
}
- _win32sLock.Release();
ResetCache();
await Context.API.SaveCacheBinaryStorageAsync>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
+ _win32sLock.Release();
}
public static async Task IndexUwpProgramsAsync()
@@ -309,10 +304,10 @@ public static async Task IndexUwpProgramsAsync()
{
_uwps.Add(uwp);
}
- _uwpsLock.Release();
ResetCache();
await Context.API.SaveCacheBinaryStorageAsync>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
_settings.LastIndexTime = DateTime.Now;
+ _uwpsLock.Release();
}
public static async Task IndexProgramsAsync()
@@ -405,7 +400,6 @@ private static async Task DisableProgramAsync(IProgram programToDelete)
}
else
{
- // Release the lock if we cannot find the program
_uwpsLock.Release();
}
@@ -425,7 +419,6 @@ private static async Task DisableProgramAsync(IProgram programToDelete)
}
else
{
- // Release the lock if we cannot find the program
_win32sLock.Release();
}
}
From 54e7652084245900e06c4513a1c6926ae13cf3b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 17:22:32 +0800
Subject: [PATCH 0891/1335] Fix see cref issue
---
Flow.Launcher.Core/Storage/IRemovable.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Storage/IRemovable.cs b/Flow.Launcher.Core/Storage/IRemovable.cs
index fc34395e062..bcf1cdd5e48 100644
--- a/Flow.Launcher.Core/Storage/IRemovable.cs
+++ b/Flow.Launcher.Core/Storage/IRemovable.cs
@@ -1,18 +1,18 @@
namespace Flow.Launcher.Core.Storage;
///
-/// Remove storage instances from instance
+/// Remove storage instances from instance
///
public interface IRemovable
{
///
- /// Remove all instances of one plugin
+ /// Remove all instances of one plugin
///
///
public void RemovePluginSettings(string assemblyName);
///
- /// Remove all instances of one plugin
+ /// Remove all instances of one plugin
///
///
public void RemovePluginCaches(string cacheDirectory);
From 68268026de3261ea5eb7a28ff09f943adc816d0c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:21:03 +0800
Subject: [PATCH 0892/1335] Improve performance
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 561044981f5..c235fb5875f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -186,6 +186,8 @@ public async Task InitAsync(PluginInitContext context)
_settings = context.API.LoadSettingJsonStorage();
+ var _win32sCount = 0;
+ var _uwpsCount = 0;
await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
{
var pluginCachePath = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
@@ -243,19 +245,18 @@ static void MoveFile(string sourcePath, string destinationPath)
await _win32sLock.WaitAsync();
_win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCachePath, new List());
+ _win32sCount = _win32s.Count;
_win32sLock.Release();
await _uwpsLock.WaitAsync();
_uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCachePath, new List());
+ _uwpsCount = _uwps.Count;
_uwpsLock.Release();
});
- await _win32sLock.WaitAsync();
- await _uwpsLock.WaitAsync();
-
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Count}>");
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwps.Count}>");
+ Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32sCount}>");
+ Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwpsCount}>");
- bool cacheEmpty = !_win32s.Any() || !_uwps.Any();
+ var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
_win32sLock.Release();
_uwpsLock.Release();
From 4c4a6c0e22f65a7c1fd0865c70ad69b86e8a0aea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:27:53 +0800
Subject: [PATCH 0893/1335] Add log handler for indexing
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 52 ++++++++++++++------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index c235fb5875f..11deb710d5f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -283,32 +283,52 @@ static void WatchProgramUpdate()
public static async Task IndexWin32ProgramsAsync()
{
- var win32S = Win32.All(_settings);
await _win32sLock.WaitAsync();
- _win32s.Clear();
- foreach (var win32 in win32S)
+ try
{
- _win32s.Add(win32);
+ var win32S = Win32.All(_settings);
+ _win32s.Clear();
+ foreach (var win32 in win32S)
+ {
+ _win32s.Add(win32);
+ }
+ ResetCache();
+ await Context.API.SaveCacheBinaryStorageAsync>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
+ _settings.LastIndexTime = DateTime.Now;
+ }
+ catch (Exception e)
+ {
+ Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Win32 programs", e);
+ }
+ finally
+ {
+ _win32sLock.Release();
}
- ResetCache();
- await Context.API.SaveCacheBinaryStorageAsync>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
- _settings.LastIndexTime = DateTime.Now;
- _win32sLock.Release();
}
public static async Task IndexUwpProgramsAsync()
{
- var uwps = UWPPackage.All(_settings);
await _uwpsLock.WaitAsync();
- _uwps.Clear();
- foreach (var uwp in uwps)
+ try
{
- _uwps.Add(uwp);
+ var uwps = UWPPackage.All(_settings);
+ _uwps.Clear();
+ foreach (var uwp in uwps)
+ {
+ _uwps.Add(uwp);
+ }
+ ResetCache();
+ await Context.API.SaveCacheBinaryStorageAsync>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
+ _settings.LastIndexTime = DateTime.Now;
+ }
+ catch (Exception e)
+ {
+ Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Uwp programs", e);
+ }
+ finally
+ {
+ _uwpsLock.Release();
}
- ResetCache();
- await Context.API.SaveCacheBinaryStorageAsync>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
- _settings.LastIndexTime = DateTime.Now;
- _uwpsLock.Release();
}
public static async Task IndexProgramsAsync()
From aaadf167777a9374f07a523a11b3c102c403ee5b Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:28:29 +0800
Subject: [PATCH 0894/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 2f8672e137c..85c48f8a4ce 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -366,7 +366,7 @@ public interface IPublicAPI
/// Default data to return
///
///
- /// BinaryStorage utilize MemoryPack, which means the object must be MemoryPackSerializable
+ /// BinaryStorage utilizes MemoryPack, which means the object must be MemoryPackSerializable
///
Task LoadCacheBinaryStorageAsync(string cacheName, string cacheDirectory, T defaultData) where T : new();
From 4749ca208abe9dbcfeb4f80470e2e6e489300e12 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:33:48 +0800
Subject: [PATCH 0895/1335] Improve code comments
---
Flow.Launcher.Plugin/Interfaces/ISavable.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/ISavable.cs b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
index 0d23c0fc8cd..38cbf8e08f5 100644
--- a/Flow.Launcher.Plugin/Interfaces/ISavable.cs
+++ b/Flow.Launcher.Plugin/Interfaces/ISavable.cs
@@ -1,8 +1,7 @@
namespace Flow.Launcher.Plugin
{
///
- /// Inherit this interface if additional data.
- /// If you need to save data which is not a setting or cache,
+ /// Inherit this interface if you need to save additional data which is not a setting or cache,
/// please implement this interface.
///
///
From 2ff09cf9b0acb61e3323c80481e6eac5e2873891 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:41:02 +0800
Subject: [PATCH 0896/1335] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 11deb710d5f..107673f8943 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -413,10 +413,7 @@ private static async Task DisableProgramAsync(IProgram programToDelete)
_uwpsLock.Release();
// Reindex UWP programs
- _ = Task.Run(() =>
- {
- _ = IndexUwpProgramsAsync();
- });
+ _ = Task.Run(IndexUwpProgramsAsync);
return;
}
else
@@ -433,10 +430,8 @@ private static async Task DisableProgramAsync(IProgram programToDelete)
_win32sLock.Release();
// Reindex Win32 programs
- _ = Task.Run(() =>
- {
- _ = IndexWin32ProgramsAsync();
- });
+ _ = Task.Run(IndexWin32ProgramsAsync);
+ return;
}
else
{
From 653b8335700290f175b7f9bce369a849d0d48f81 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:42:59 +0800
Subject: [PATCH 0897/1335] Fix typos
---
Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 2 +-
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index b5de3b50ff1..43bb8dadecb 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -15,7 +15,7 @@ namespace Flow.Launcher.Infrastructure.Storage
/// Normally, it has better performance, but not readable
///
///
- /// It utilize MemoryPack, which means the object must be MemoryPackSerializable
+ /// It utilizes MemoryPack, which means the object must be MemoryPackSerializable
///
public class BinaryStorage : ISavable
{
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 85c48f8a4ce..a3020b60725 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -380,7 +380,7 @@ public interface IPublicAPI
/// Cache directory from plugin metadata
///
///
- /// BinaryStorage utilize MemoryPack, which means the object must be MemoryPackSerializable
+ /// BinaryStorage utilizes MemoryPack, which means the object must be MemoryPackSerializable
///
Task SaveCacheBinaryStorageAsync(string cacheName, string cacheDirectory) where T : new();
From d7ca36e60a39892295fe2c42c9e2f81e56b59a66 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:44:30 +0800
Subject: [PATCH 0898/1335] Change variable name
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 107673f8943..745b042e6a1 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -190,8 +190,8 @@ public async Task InitAsync(PluginInitContext context)
var _uwpsCount = 0;
await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
{
- var pluginCachePath = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
- FilesFolders.ValidateDirectory(pluginCachePath);
+ var pluginCacheDirectory = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
+ FilesFolders.ValidateDirectory(pluginCacheDirectory);
static void MoveFile(string sourcePath, string destinationPath)
{
@@ -237,19 +237,19 @@ static void MoveFile(string sourcePath, string destinationPath)
// Move old cache files to the new cache directory
var oldWin32CacheFile = Path.Combine(DataLocation.CacheDirectory, $"{Win32CacheName}.cache");
- var newWin32CacheFile = Path.Combine(pluginCachePath, $"{Win32CacheName}.cache");
+ var newWin32CacheFile = Path.Combine(pluginCacheDirectory, $"{Win32CacheName}.cache");
MoveFile(oldWin32CacheFile, newWin32CacheFile);
var oldUWPCacheFile = Path.Combine(DataLocation.CacheDirectory, $"{UwpCacheName}.cache");
- var newUWPCacheFile = Path.Combine(pluginCachePath, $"{UwpCacheName}.cache");
+ var newUWPCacheFile = Path.Combine(pluginCacheDirectory, $"{UwpCacheName}.cache");
MoveFile(oldUWPCacheFile, newUWPCacheFile);
await _win32sLock.WaitAsync();
- _win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCachePath, new List());
+ _win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCacheDirectory, new List());
_win32sCount = _win32s.Count;
_win32sLock.Release();
await _uwpsLock.WaitAsync();
- _uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCachePath, new List());
+ _uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCacheDirectory, new List());
_uwpsCount = _uwps.Count;
_uwpsLock.Release();
});
From 482e37316a1fee76b924e3b151a4507a42ad2cb7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 19:46:40 +0800
Subject: [PATCH 0899/1335] Remove useless releases
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 745b042e6a1..a50868b69dd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -258,9 +258,6 @@ static void MoveFile(string sourcePath, string destinationPath)
var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
- _win32sLock.Release();
- _uwpsLock.Release();
-
if (cacheEmpty || _settings.LastIndexTime.AddHours(30) < DateTime.Now)
{
_ = Task.Run(async () =>
From d30f292e3129aeab196b21380a3076f860a976e3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 20:19:04 +0800
Subject: [PATCH 0900/1335] Remove unused string
---
Flow.Launcher/Languages/en.xaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index f01d0575a83..7e5a554a9fb 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -149,7 +149,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Plugin Store
From 970bb3ac1268f8e3e443f48aef77d80324b2da15 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 20:30:40 +0800
Subject: [PATCH 0901/1335] Add code comments
---
Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
index ab9496266f3..a27a007823c 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml.cs
@@ -9,6 +9,7 @@ public InstalledPluginDisplay()
InitializeComponent();
}
+ // This is used for PriorityControl to force its value to be 0 when the user clears the value
private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
{
if (double.IsNaN(args.NewValue))
From 61fa4602d529c345616aaea87dd65af14589f77c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:02:42 +0800
Subject: [PATCH 0902/1335] Disable search delay number box when search delay
is disabled
---
.../Resources/Controls/InstalledPluginDisplay.xaml | 9 +++++----
Flow.Launcher/ViewModel/PluginViewModel.cs | 5 +++++
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 9a4e3b7b057..63d1af6b138 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -90,13 +90,14 @@
-
+ Value="{Binding PluginSearchDelayTime, Mode=TwoWay}" />
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 2dff72ac52b..5f19459c9da 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -3,9 +3,11 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
+using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.Image;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Resources.Controls;
@@ -13,6 +15,8 @@ namespace Flow.Launcher.ViewModel
{
public partial class PluginViewModel : BaseModel
{
+ private static readonly Settings Settings = Ioc.Default.GetRequiredService();
+
private readonly PluginPair _pluginPair;
public PluginPair PluginPair
{
@@ -148,6 +152,7 @@ public Control SettingControl
App.API.GetTranslation("default") :
App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
+ public bool SearchDelayEnabled => Settings.SearchQueryResultsWithDelay;
public void OnActionKeywordsChanged()
{
From ade4fbf7f2a905ef41cdf98e82dcd484d1400367 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:02:56 +0800
Subject: [PATCH 0903/1335] Adjust number box width
---
Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 63d1af6b138..4a89d811fd1 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -88,7 +88,7 @@
Text="{DynamicResource searchDelay}"
ToolTip="{DynamicResource searchDelayToolTip}" />
Date: Tue, 8 Apr 2025 21:04:04 +0800
Subject: [PATCH 0904/1335] Change default search delay time to value
---
Flow.Launcher/Languages/en.xaml | 1 -
Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 1 +
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 7e5a554a9fb..609859d0dab 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -111,7 +111,6 @@
Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
Default Search Delay Time
Wait time before showing results after typing stops. Higher values wait longer. (ms)
- Default
Search Plugin
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 4a89d811fd1..2310362443a 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -93,7 +93,7 @@
IsEnabled="{Binding SearchDelayEnabled}"
Maximum="1000"
Minimum="0"
- PlaceholderText="{DynamicResource searchDelayPlaceHolder}"
+ PlaceholderText="{Binding DefaultSearchDelay}"
SmallChange="10"
SpinButtonPlacementMode="Compact"
ToolTip="{DynamicResource searchDelayToolTip}"
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 5f19459c9da..da0ed70fab8 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -153,6 +153,7 @@ public Control SettingControl
App.API.GetTranslation($"SearchDelayTime{PluginPair.Metadata.SearchDelayTime}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public bool SearchDelayEnabled => Settings.SearchQueryResultsWithDelay;
+ public string DefaultSearchDelay => Settings.SearchDelayTime.ToString();
public void OnActionKeywordsChanged()
{
From 2589fac0bcb1cd28b0e3074c7bacd3e6baaad27e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:23:02 +0800
Subject: [PATCH 0905/1335] Remove useless function
---
Flow.Launcher.Infrastructure/Stopwatch.cs | 34 -----------------------
1 file changed, 34 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Stopwatch.cs b/Flow.Launcher.Infrastructure/Stopwatch.cs
index dd6edaff93b..784d323fe52 100644
--- a/Flow.Launcher.Infrastructure/Stopwatch.cs
+++ b/Flow.Launcher.Infrastructure/Stopwatch.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
@@ -7,8 +6,6 @@ namespace Flow.Launcher.Infrastructure
{
public static class Stopwatch
{
- private static readonly Dictionary Count = new Dictionary();
- private static readonly object Locker = new object();
///
/// This stopwatch will appear only in Debug mode
///
@@ -62,36 +59,5 @@ public static async Task NormalAsync(string message, Func action)
Log.Info(info);
return milliseconds;
}
-
-
-
- public static void StartCount(string name, Action action)
- {
- var stopWatch = new System.Diagnostics.Stopwatch();
- stopWatch.Start();
- action();
- stopWatch.Stop();
- var milliseconds = stopWatch.ElapsedMilliseconds;
- lock (Locker)
- {
- if (Count.ContainsKey(name))
- {
- Count[name] += milliseconds;
- }
- else
- {
- Count[name] = 0;
- }
- }
- }
-
- public static void EndCount()
- {
- foreach (var key in Count.Keys)
- {
- string info = $"{key} already cost {Count[key]}ms";
- Log.Debug(info);
- }
- }
}
}
From d09899e15c32be3d1755b6222cdae4919735d2fd Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 8 Apr 2025 22:31:33 +0900
Subject: [PATCH 0906/1335] Adjust Placeholder color
---
.../Resources/CustomControlTemplate.xaml | 25 +++++++++++--------
Flow.Launcher/Resources/Dark.xaml | 1 +
Flow.Launcher/Resources/Light.xaml | 3 +++
3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index d788294716d..ffa5eea4122 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2777,7 +2777,7 @@
-
+
@@ -3587,7 +3587,7 @@
-
+
-
+
-
+
diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml
index e8629a98199..498e96bffd3 100644
--- a/Flow.Launcher/Resources/Dark.xaml
+++ b/Flow.Launcher/Resources/Dark.xaml
@@ -106,6 +106,7 @@
#f5f5f5
#464646
#ffffff
+
#272727
diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml
index aa6da9fb22d..0f1e98a6b95 100644
--- a/Flow.Launcher/Resources/Light.xaml
+++ b/Flow.Launcher/Resources/Light.xaml
@@ -97,8 +97,11 @@
#f5f5f5
#878787
#1b1b1b
+
#f6f6f6
+
+
From e753bb79b1985de78f21d68dfd02f0b1160f919d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:32:18 +0800
Subject: [PATCH 0907/1335] Add public methods
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 26 +++++++++++++++++++
Flow.Launcher/PublicAPIInstance.cs | 13 ++++++++++
2 files changed, 39 insertions(+)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 273676bfbd6..6d9e5f7552c 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -473,5 +473,31 @@ public interface IPublicAPI
///
///
public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePluginSettings = false);
+
+ ///
+ /// Log debug message of the time taken to execute a method
+ /// Message will only be logged in Debug mode
+ ///
+ /// The time taken to execute the method in milliseconds
+ public long StopWatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "");
+
+ ///
+ /// Log debug message of the time taken to execute a method asynchronously
+ /// Message will only be logged in Debug mode
+ ///
+ /// The time taken to execute the method in milliseconds
+ public Task StopWatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
+
+ ///
+ /// Log info message of the time taken to execute a method
+ ///
+ /// The time taken to execute the method in milliseconds
+ public long StopWatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "");
+
+ ///
+ /// Log info message of the time taken to execute a method asynchronously
+ ///
+ /// The time taken to execute the method in milliseconds
+ public Task StopWatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b67ef6ab6e5..b7aaef14371 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -31,6 +31,7 @@
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Squirrel;
+using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
@@ -431,6 +432,18 @@ public void InstallPlugin(UserPlugin plugin, string zipFilePath) =>
public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePluginSettings = false) =>
PluginManager.UninstallPluginAsync(pluginMetadata, removePluginSettings);
+ public long StopWatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
+ Stopwatch.Debug($"|{className}.{methodName}|{message}", action);
+
+ public Task StopWatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
+ Stopwatch.DebugAsync($"|{className}.{methodName}|{message}", action);
+
+ public long StopWatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
+ Stopwatch.Normal($"|{className}.{methodName}|{message}", action);
+
+ public Task StopWatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
+ Stopwatch.NormalAsync($"|{className}.{methodName}|{message}", action);
+
#endregion
#region Private Methods
From f99859ad1eb4fc5f94077327d60f689b8507b16a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:38:17 +0800
Subject: [PATCH 0908/1335] Change api function names
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 8 ++++----
Flow.Launcher/PublicAPIInstance.cs | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 6d9e5f7552c..55f09dc3b4d 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -479,25 +479,25 @@ public interface IPublicAPI
/// Message will only be logged in Debug mode
///
/// The time taken to execute the method in milliseconds
- public long StopWatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "");
+ public long StopwatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "");
///
/// Log debug message of the time taken to execute a method asynchronously
/// Message will only be logged in Debug mode
///
/// The time taken to execute the method in milliseconds
- public Task StopWatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
+ public Task StopwatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
///
/// Log info message of the time taken to execute a method
///
/// The time taken to execute the method in milliseconds
- public long StopWatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "");
+ public long StopwatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "");
///
/// Log info message of the time taken to execute a method asynchronously
///
/// The time taken to execute the method in milliseconds
- public Task StopWatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
+ public Task StopwatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b7aaef14371..95ef6c9f3bd 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -432,16 +432,16 @@ public void InstallPlugin(UserPlugin plugin, string zipFilePath) =>
public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePluginSettings = false) =>
PluginManager.UninstallPluginAsync(pluginMetadata, removePluginSettings);
- public long StopWatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
+ public long StopwatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
Stopwatch.Debug($"|{className}.{methodName}|{message}", action);
- public Task StopWatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
+ public Task StopwatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
Stopwatch.DebugAsync($"|{className}.{methodName}|{message}", action);
- public long StopWatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
+ public long StopwatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
Stopwatch.Normal($"|{className}.{methodName}|{message}", action);
- public Task StopWatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
+ public Task StopwatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
Stopwatch.NormalAsync($"|{className}.{methodName}|{message}", action);
#endregion
From 19aa42314b7d335768abe33733e9394429acdc56 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:38:33 +0800
Subject: [PATCH 0909/1335] Use api functions in ImageLoader
---
.../Image/ImageLoader.cs | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 41a33104b66..1483c58654e 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -7,13 +7,20 @@
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
-using Flow.Launcher.Infrastructure.Logger;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Storage;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Infrastructure.Image
{
public static class ImageLoader
{
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
+ private static readonly string ClassName = nameof(ImageLoader);
+
private static readonly ImageCache ImageCache = new();
private static SemaphoreSlim storageLock { get; } = new SemaphoreSlim(1, 1);
private static BinaryStorage> _storage;
@@ -47,15 +54,14 @@ public static async Task InitializeAsync()
_ = Task.Run(async () =>
{
- await Stopwatch.NormalAsync("|ImageLoader.Initialize|Preload images cost", async () =>
+ await API.StopwatchLogInfoAsync(ClassName, "Preload images cost", async () =>
{
foreach (var (path, isFullImage) in usage)
{
await LoadAsync(path, isFullImage);
}
});
- Log.Info(
- $"|ImageLoader.Initialize|Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
+ API.LogInfo(ClassName, $"Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
});
}
@@ -71,7 +77,7 @@ await _storage.SaveAsync(ImageCache.EnumerateEntries()
}
catch (System.Exception e)
{
- Log.Exception($"|ImageLoader.SaveAsync|Failed to save image cache to file", e);
+ API.LogException(ClassName, "Failed to save image cache to file", e);
}
finally
{
@@ -166,8 +172,8 @@ private static async ValueTask LoadInternalAsync(string path, bool
}
catch (System.Exception e2)
{
- Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
- Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
+ API.LogException(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
+ API.LogException(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
ImageSource image = ImageCache[Constant.MissingImgIcon, false];
ImageCache[path, false] = image;
From 9bc27a4ecd16a52d2d05a7baee1d33e5555128fd Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 8 Apr 2025 23:41:15 +1000
Subject: [PATCH 0910/1335] New Crowdin updates (#3348)
---
Flow.Launcher/Languages/ar.xaml | 47 +++++-
Flow.Launcher/Languages/cs.xaml | 47 +++++-
Flow.Launcher/Languages/da.xaml | 47 +++++-
Flow.Launcher/Languages/de.xaml | 69 +++++++--
Flow.Launcher/Languages/es-419.xaml | 47 +++++-
Flow.Launcher/Languages/es.xaml | 47 +++++-
Flow.Launcher/Languages/fr.xaml | 47 +++++-
Flow.Launcher/Languages/he.xaml | 57 +++++--
Flow.Launcher/Languages/it.xaml | 47 +++++-
Flow.Launcher/Languages/ja.xaml | 47 +++++-
Flow.Launcher/Languages/ko.xaml | 53 ++++++-
Flow.Launcher/Languages/nb.xaml | 47 +++++-
Flow.Launcher/Languages/nl.xaml | 47 +++++-
Flow.Launcher/Languages/pl.xaml | 47 +++++-
Flow.Launcher/Languages/pt-br.xaml | 47 +++++-
Flow.Launcher/Languages/pt-pt.xaml | 53 ++++++-
Flow.Launcher/Languages/ru.xaml | 47 +++++-
Flow.Launcher/Languages/sk.xaml | 47 +++++-
Flow.Launcher/Languages/sr.xaml | 47 +++++-
Flow.Launcher/Languages/tr.xaml | 47 +++++-
Flow.Launcher/Languages/uk-UA.xaml | 47 +++++-
Flow.Launcher/Languages/vi.xaml | 47 +++++-
Flow.Launcher/Languages/zh-cn.xaml | 49 +++++-
Flow.Launcher/Languages/zh-tw.xaml | 47 +++++-
.../Languages/sk.xaml | 2 +-
.../Languages/ko.xaml | 2 +-
.../Languages/de.xaml | 4 +-
.../Languages/ar.xaml | 2 +
.../Languages/cs.xaml | 2 +
.../Languages/da.xaml | 2 +
.../Languages/de.xaml | 2 +
.../Languages/es-419.xaml | 2 +
.../Languages/es.xaml | 2 +
.../Languages/fr.xaml | 2 +
.../Languages/he.xaml | 2 +
.../Languages/it.xaml | 2 +
.../Languages/ja.xaml | 2 +
.../Languages/ko.xaml | 2 +
.../Languages/nb.xaml | 2 +
.../Languages/nl.xaml | 2 +
.../Languages/pl.xaml | 2 +
.../Languages/pt-br.xaml | 2 +
.../Languages/pt-pt.xaml | 2 +
.../Languages/ru.xaml | 2 +
.../Languages/sk.xaml | 2 +
.../Languages/sr.xaml | 2 +
.../Languages/tr.xaml | 2 +
.../Languages/uk-UA.xaml | 2 +
.../Languages/vi.xaml | 2 +
.../Languages/zh-cn.xaml | 2 +
.../Languages/zh-tw.xaml | 2 +
.../Languages/de.xaml | 4 +-
.../Languages/he.xaml | 2 +-
.../Languages/de.xaml | 2 +-
.../Languages/ar.xaml | 14 +-
.../Languages/cs.xaml | 14 +-
.../Languages/da.xaml | 14 +-
.../Languages/de.xaml | 20 ++-
.../Languages/es-419.xaml | 14 +-
.../Languages/es.xaml | 14 +-
.../Languages/fr.xaml | 14 +-
.../Languages/he.xaml | 14 +-
.../Languages/it.xaml | 14 +-
.../Languages/ja.xaml | 14 +-
.../Languages/ko.xaml | 14 +-
.../Languages/nb.xaml | 14 +-
.../Languages/nl.xaml | 14 +-
.../Languages/pl.xaml | 14 +-
.../Languages/pt-br.xaml | 14 +-
.../Languages/pt-pt.xaml | 18 ++-
.../Languages/ru.xaml | 14 +-
.../Languages/sk.xaml | 14 +-
.../Languages/sr.xaml | 14 +-
.../Languages/tr.xaml | 14 +-
.../Languages/uk-UA.xaml | 14 +-
.../Languages/vi.xaml | 14 +-
.../Languages/zh-cn.xaml | 14 +-
.../Languages/zh-tw.xaml | 14 +-
.../Languages/ar.xaml | 2 +-
.../Languages/cs.xaml | 2 +-
.../Languages/da.xaml | 2 +-
.../Languages/de.xaml | 8 +-
.../Languages/es-419.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/fr.xaml | 2 +-
.../Languages/he.xaml | 2 +-
.../Languages/it.xaml | 2 +-
.../Languages/ja.xaml | 2 +-
.../Languages/ko.xaml | 2 +-
.../Languages/nb.xaml | 2 +-
.../Languages/nl.xaml | 2 +-
.../Languages/pl.xaml | 2 +-
.../Languages/pt-br.xaml | 2 +-
.../Languages/pt-pt.xaml | 2 +-
.../Languages/ru.xaml | 9 +-
.../Languages/sk.xaml | 2 +-
.../Languages/sr.xaml | 2 +-
.../Languages/tr.xaml | 2 +-
.../Languages/uk-UA.xaml | 2 +-
.../Languages/vi.xaml | 2 +-
.../Languages/zh-cn.xaml | 2 +-
.../Languages/zh-tw.xaml | 2 +-
.../Properties/Resources.de-DE.resx | 8 +-
.../Properties/Resources.he-IL.resx | 2 +-
.../Properties/Resources.ko-KR.resx | 2 +-
.../Properties/Resources.pt-PT.resx | 140 +++++++++---------
.../Properties/Resources.sk-SK.resx | 2 +-
107 files changed, 1536 insertions(+), 263 deletions(-)
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index a57179da6c6..b5eafaae9e9 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -7,6 +7,11 @@
انقر فوق لا إذا كان مثبتاً بالفعل، وسوف يطلب منك تحديد المجلد الذي يحتوي على {1} القابل للتنفيذ
الرجاء اختيار الملف التنفيذي لـ {0}
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
تعذر تعيين مسار الملف التنفيذي لـ {0}، يرجى المحاولة من إعدادات Flow (قم بالتمرير إلى الأسفل).
فشل في تهيئة الإضافات
الإضافات: {0} - فشل في التحميل وسيتم تعطيلها، يرجى الاتصال بمطور الإضافة للحصول على المساعدة
@@ -37,7 +42,7 @@
وضع اللعب
تعليق استخدام مفاتيح التشغيل السريع.
إعادة تعيين الموقع
- إعادة تعيين موضع نافذة البحث
+ Type here to search
الإعدادات
@@ -70,8 +75,6 @@
تفريغ الاستعلام الأخير
Preserve Last Action Keyword
Select Last Action Keyword
- ارتفاع ثابت للنافذة
- ارتفاع النافذة غير قابل للتعديل عن طريق السحب.
الحد الأقصى للنتائج المعروضة
يمكنك أيضًا تعديل هذا بسرعة باستخدام CTRL+Plus وCTRL+Minus.
تجاهل مفاتيح التشغيل السريع في وضع ملء الشاشة
@@ -102,6 +105,15 @@
دائمًا معاينة
فتح لوحة المعاينة دائمًا عند تنشيط Flow. اضغط على {0} للتبديل بين المعاينة وعدمها.
تأثير الظل غير مسموح به بينما يتم تمكين تأثير التمويه في السمة الحالية
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
البحث عن إضافة
@@ -118,6 +130,8 @@
كلمة الفعل الحالية
كلمة فعل جديدة
تغيير كلمات الفعل
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
الأولوية الحالية
أولوية جديدة
الأولوية
@@ -131,6 +145,9 @@
إلغاء التثبيت
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
متجر الإضافات
@@ -193,8 +210,20 @@
مخصص
الساعة
التاريخ
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ بلا
+ Acrylic
+ Mica
+ Mica Alt
هذه السمة تدعم الوضعين (فاتح/داكن).
هذه السمة تدعم الخلفية الضبابية الشفافة.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
مفتاح الاختصار
@@ -294,6 +323,9 @@
مجلد السجلات
مسح السجلات
هل أنت متأكد أنك تريد حذف جميع السجلات؟
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
معالج الترحيب
موقع بيانات المستخدم
يتم حفظ إعدادات المستخدم والإضافات المثبتة في مجلد بيانات المستخدم. قد يختلف هذا الموقع اعتمادًا على ما إذا كان في وضع النقل أم لا.
@@ -335,9 +367,16 @@
لا يمكن العثور على الإضافة المحددة
كلمة المفتاح الجديدة لا يمكن أن تكون فارغة
تم تعيين كلمة المفتاح الجديدة هذه إلى إضافة أخرى، يرجى اختيار كلمة أخرى
+ This new Action Keyword is the same as old, please choose a different one
نجاح
اكتمل بنجاح
- أدخل كلمة المفتاح التي ترغب في استخدامها لبدء الإضافة. استخدم * إذا كنت لا ترغب في تحديد أي كلمة، وسيتم تشغيل الإضافة بدون كلمات مفتاحية.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
مفتاح اختصار الاستعلام المخصص
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 92721b70ad0..806e9f2030e 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Herní režim
Potlačit užívání klávesových zkratek.
Obnovit pozici
- Obnovit pozici vyhledávacího okna
+ Type here to search
Nastavení
@@ -70,8 +75,6 @@
Smazat poslední dotaz
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Počet zobrazených výsledků
Toto nastavení můžete také rychle upravit pomocí CTRL + Plus a CTRL + Minus.
Ignorovat klávesové zkratky v režimu celé obrazovky
@@ -102,6 +105,15 @@
Vždy zobrazit náhled
Při aktivaci služby Flow vždy otevřete panel náhledu. Stisknutím klávesy {0} přepnete náhled.
Stínový efekt není povolen, pokud je aktivní efekt rozostření
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Vyhledat plugin
@@ -118,6 +130,8 @@
Aktuální aktivační příkaz
Nový aktivační příkaz
Upravit aktivační příkaz
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Aktuální priorita
Nová priorita
Priorita
@@ -131,6 +145,9 @@
Odinstalovat
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Obchod s pluginy
@@ -193,8 +210,20 @@
Vlastní
Hodiny
Datum
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Klávesová zkratka
@@ -294,6 +323,9 @@
Složka s logy
Vymazat logy
Opravdu chcete odstranit všechny logy?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Průvodce
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
Nepodařilo se najít zadaný plugin
Nový aktivační příkaz nemůže být prázdný
Nový aktivační příkaz byl již přiřazen jinému pluginu, vyberte jiný aktivační příkaz
+ This new Action Keyword is the same as old, please choose a different one
Úspěšné
Úspěšně dokončeno
- Zadejte aktivační příkaz, který je nutný ke spuštění pluginu. Pokud nechcete zadávat aktivační příkaz, použijte * a plugin bude spuštěn bez aktivačního příkazu.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Vlastní klávesová zkratka pro vyhledávání
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index 629173f7492..6055a79e1ea 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
- Reset search window position
+ Type here to search
Indstillinger
@@ -70,8 +75,6 @@
Empty last Query
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Maksimum antal resultater vist
You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
Ignorer genvejstaster i fuldskærmsmode
@@ -102,6 +105,15 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Search Plugin
@@ -118,6 +130,8 @@
Current action keyword
New action keyword
Change Action Keywords
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Current Priority
New Priority
Priority
@@ -131,6 +145,9 @@
Uninstall
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Plugin Store
@@ -193,8 +210,20 @@
Custom
Clock
Date
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Genvejstast
@@ -294,6 +323,9 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
Kan ikke finde det valgte plugin
Nyt nøgleord må ikke være tomt
Nyt nøgleord er tilknyttet et andet plugin, tilknyt venligst et andet nyt nøgeleord
+ This new Action Keyword is the same as old, please choose a different one
Fortsæt
Completed successfully
- Brug * hvis du ikke vil angive et nøgleord
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Tilpasset søgegenvejstast
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 8a7e3498ab9..4fb441d8c1f 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -7,13 +7,18 @@
Klicken Sie auf „Nein“, wenn es bereits installiert ist, und Sie werden aufgefordert, den Ordner auszuwählen, der die ausführbare Datei {1} enthält
Bitte wählen Sie die ausführbare Datei {0} aus
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Der Pfad zur ausführbaren Datei {0} kann nicht festgelegt werden. Bitte versuchen Sie es in den Einstellungen von Flow (scrollen Sie nach unten).
Plug-ins können nicht initialisiert werden
- Plug-ins: {0} - nicht geladen werden und wird deaktiviert, bitte kontaktiere Sie den Ersteller des Plug-ins für Hilfe
+ Plug-ins: {0} - nicht geladen werden und wird deaktiviert, bitte kontaktieren Sie den Ersteller des Plug-ins für Hilfe
Hotkey "{0}" konnte nicht registriert werden. Der Hotkey ist möglicherweise von einem anderen Programm in Verwendung. Wechseln Sie zu einem anderen Hotkey oder beenden Sie das andere Programm.
- Failed to unregister hotkey "{0}". Please try again or see log for details
+ Registrierung des Hotkeys "{0}" konnte nicht aufgehoben werden. Bitte versuchen Sie es erneut oder lesen Sie das Log für Details
Flow Launcher
Konnte nicht gestartet werden {0}
Flow Launcher Plug-in-Dateiformat ungültig
@@ -37,7 +42,7 @@
Spielmodus
Aussetzen der Verwendung von Hotkeys.
Position zurücksetzen
- Position des Suchfensters zurücksetze
+ Type here to search
Einstellungen
@@ -45,9 +50,9 @@
Portabler Modus
Speichern Sie alle Einstellungen und Benutzerdaten in einem Ordner (nützlich bei Verwendung von Wechsellaufwerken oder Cloud-Diensten).
Flow Launcher bei Systemstart starten
- Use logon task instead of startup entry for faster startup experience
- After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler
- Fehler bei Einstellungsstart bei Start
+ Log-on-Aufgabe anstelle des Starteintrags für schnelleres Startup-Erfahrung verwenden
+ Nach der Deinstallation müssen Sie diese Aufgabe (Flow.Launcher Startup) via Task-Scheduler manuell entfernen
+ Fehler bei Einstellungsstart beim Start
Flow Launcher ausblenden, wenn Fokus verloren geht
Versionsbenachrichtigungen nicht zeigen
Position des Suchfensters
@@ -70,8 +75,6 @@
Letzte Abfrage leeren
Letztes Aktions-Schlüsselwort beibehalten
Letztes Aktions-Schlüsselwort auswählen
- Feste Fensterhöhe
- Die Fensterhöhe ist durch Ziehen nicht anpassbar.
Maximal gezeigte Ergebnisse
Sie können dies auch unter Verwendung von STRG+Plus und STRG+Minus schnell anpassen.
Hotkeys im Vollbildmodus ignorieren
@@ -102,6 +105,15 @@
Immer Vorschau
Vorschau-Panel immer öffnen, wenn Flow aktiviert ist. Drücken Sie {0}, um Vorschau umzuschalten.
Schatteneffekt ist nicht erlaubt, während das aktuelle Theme den Unschärfe-Effekt aktiviert hat
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Plug-in suchen
@@ -118,6 +130,8 @@
Aktuelles Action-Schlüsselwort
Neues Aktions-Schlüsselwort
Aktions-Schlüsselwörter ändern
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Aktuelle Priorität
Neue Priorität
Priorität
@@ -129,8 +143,11 @@
Version
Website
Deinstallieren
- Fail to remove plugin settings
- Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Plug-in-Einstellungen können nicht entfernt werden
+ Plug-ins: {0} - Plug-in-Einstellungsdateien können nicht entfernt werden, bitte entfernen Sie diese manuell
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Plug-in-Store
@@ -193,8 +210,20 @@
Benutzerdefiniert
Uhr
Datum
+ Backdrop-Typ
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Keine
+ Acrylic
+ Mica
+ Mica Alt
Dieses Theme unterstützt zwei Modi (hell/dunkel).
Dieses Theme unterstützt Unschärfe und transparenten Hintergrund.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Hotkey
@@ -294,11 +323,14 @@
Ordner »Logs«
Logs löschen
Sind Sie sicher, dass Sie alle Logs löschen wollen?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Assistent
Speicherort für Benutzerdaten
Benutzereinstellungen und installierte Plug-ins werden im Ordner für Benutzerdaten gespeichert. Dieser Speicherort kann variieren, je nachdem, ob sich das Programm im portablen Modus befindet oder nicht.
Ordner öffnen
- Log Level
+ Log-Ebene
Debug
Info
@@ -335,9 +367,16 @@
Das angegebene Plug-in kann nicht gefunden werden
Neues Aktions-Schlüsselwort darf nicht leer sein
Dieses neue Aktions-Schlüsselwort ist bereits einem anderen Plug-in zugewiesen, bitte wählen Sie ein anderes
+ Dieses neue Aktions-Schlüsselwort ist dasselbe wie das alte, bitte wählen Sie ein anderes
Erfolg
Erfolgreich abgeschlossen
- Geben Sie das Aktions-Schlüsselwort ein, das Sie verwenden möchten, um das Plug-in zu starten. Verwenden Sie *, wenn Sie keines angeben möchten, und das Plug-in wird ohne irgendwelche Aktions-Schlüsselwörter ausgelöst.
+ Geben Sie die Aktions-Schlüsselwörter ein, die Sie zum Starten des Plug-ins verwenden möchten, und trennen Sie sie durch Leerzeichen voneinander ab. Verwenden Sie *, wenn Sie keine spezifizieren möchten, und das Plug-in wird ohne jegliche Aktions-Schlüsselwörter ausgelöst.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Benutzerdefinierter Abfrage-Hotkey
@@ -388,9 +427,9 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
Bericht erfolgreich gesendet
Bericht konnte nicht gesendet werden
Flow Launcher hat einen Fehler
- Please open new issue in
- 1. Upload log file: {0}
- 2. Copy below exception message
+ Bitte öffnen Sie einen neuen Fall in
+ 1. Logdatei hochladen: {0}
+ 2. Kopieren Sie die Ausnahmemeldung unterhalb
Bitte warten Sie ...
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 1ab69727b29..23d58eca3a1 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Modo de juego
Suspender el uso de las teclas de acceso directo.
Position Reset
- Reset search window position
+ Type here to search
Ajustes
@@ -70,8 +75,6 @@
Borrar última consulta
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Máximo de resultados mostrados
You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
Ignorar atajos de teclado en modo pantalla completa
@@ -102,6 +105,15 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
El efecto de sombra no está permitido mientras el tema actual tenga el efecto de desenfoque habilitado
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Search Plugin
@@ -118,6 +130,8 @@
Palabra clave actual
Nueva palabra clave
Cambiar palabras clave
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Prioridad Actual
Nueva Prioridad
Prioridad
@@ -131,6 +145,9 @@
Uninstall
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Tienda de Plugins
@@ -193,8 +210,20 @@
Custom
Clock
Date
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Tecla Rápida
@@ -294,6 +323,9 @@
Carpeta de registros
Clear Logs
Are you sure you want to delete all logs?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Asistente
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
No se puede encontrar el plugin especificado
La nueva palabra clave no puede estar vacía
Esta palabra clave ya está asignada a otro plugin, por favor elija una diferente
+ This new Action Keyword is the same as old, please choose a different one
Éxito
Completado con éxito
- Introduzca la palabra clave que desea utilizar para iniciar el plugin. Utilice * si no desea especificar ninguno, y el plugin se activará sin ninguna palabra clave.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Tecla de Acceso Personalizada
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 4cba4c8a7b5..8b3c42fa613 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -7,6 +7,11 @@
Haga clic en no si ya está instalado, y seleccione la carpeta que contiene el ejecutable {1}
Por favor, seleccione el ejecutable {0}
+
+ El ejecutable {0} seleccionado no es válido.
+ {2}{2}
+ Pulsar Sí, si desea seleccionar de nuevo el ejecutable {0}. Pulsar No, si desea descargar {1}
+
No se puede establecer la ruta del ejecutable {0}, por favor inténtelo desde la configuración de Flow (desplácese hacia abajo).
Fallo al iniciar los complementos
Complemento: {0} - no se pudo cargar y se desactivará, póngase en contacto con el creador del complemento para obtener ayuda
@@ -37,7 +42,7 @@
Modo Juego
Suspende el uso de atajos de teclado.
Restablecer posición
- Restablece la posición de la ventana de búsqueda
+ Escribir aquí para buscar
Configuración
@@ -70,8 +75,6 @@
Limpiar la última consulta
Conservar última palabra clave de acción
Seleccionar última palabra clave de acción
- Altura de la ventana fija
- La altura de la ventana no se puede ajustar arrastrando el ratón.
Número máximo de resultados mostrados
También puede ajustarse rápidamente usando Ctrl+Más(+) y Ctrl+Menos(-).
Ignorar atajos de teclado en modo pantalla completa
@@ -102,6 +105,15 @@
Mostrar siempre vista previa
Muestra siempre el panel de vista previa al iniciar Flow. Pulsar {0} para mostrar/ocultar la vista previa.
El efecto de sombra no está permitido si el tema actual tiene activado el efecto de desenfoque
+ Retardo de búsqueda
+ Retrasa un poco la búsqueda al escribir. Esto reduce los saltos en la interfaz y la carga de resultados.
+ Tiempo de retardo de búsqueda predeterminado
+ Tiempo de retardo predeterminado del complemento tras el que aparecerán los resultados de la búsqueda cuando se deje de escribir.
+ Muy largo
+ Largo
+ Normal
+ Corto
+ Muy corto
Buscar complemento
@@ -118,6 +130,8 @@
Palabra clave de acción actual
Nueva palabra clave de acción
Cambia la palabra clave de acción
+ Tiempo de retardo de la búsqueda del complemento
+ Cambiar tiempo de retardo de la búsqueda del complemento
Prioridad actual
Nueva prioridad
Prioridad
@@ -131,6 +145,9 @@
Desinstalar
Fallo al eliminar la configuración del complemento
Complementos: {0} - Fallo al eliminar los archivos de configuración del complemento, por favor elimínelos manualmente
+ Fallo al eliminar la caché del complemento
+ Complementos: {0} - Fallo al eliminar los archivos de caché del complemento, por favor elimínelos manualmente
+ Predeterminado
Tienda complementos
@@ -193,8 +210,20 @@
Personalizada
Reloj
Fecha
+ Tipo de telón de fondo
+ Telón de fondo compatible a partir de Windows 11 build 22000 y superiores
+ Ninguno
+ Acrílico
+ Mica
+ Mica Alt
Este tema soporta dos modos (claro/oscuro).
Este tema soporta fondo transparente desenfocado.
+ Mostrar marcador de posición
+ Mostrar marcador de posición cuando la consulta esté vacía
+ Texto del marcador de posición
+ Cambiar el texto del marcador de posición. La entrada vacía utilizará: {0}
+ Tamaño fijo de la ventana
+ El tamaño de la ventana no se puede ajustar mediante arrastre.
Atajo de teclado
@@ -294,6 +323,9 @@
Carpeta de registros
Eliminar registros
¿Está seguro de que desea eliminar todos los registros?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Asistente
Ubicación de datos del usuario
La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portable o no.
@@ -335,9 +367,16 @@
No se puede encontrar el complemento especificado
La nueva palabra clave de acción no puede estar vacía
Esta nueva palabra clave de acción ya está asignada a otro complemento, por favor elija una diferente
+ Esta nueva palabra clave de acción es la misma que la anterior, por favor elija una diferente
Correcto
Finalizado correctamente
- Introduzca la palabra clave que desea utilizar para iniciar el complemento. Utilice * si no desea especificar ninguna, y el complemento se activará sin ninguna palabra clave.
+ Introduzca las palabras clave de acción que desea utilizar para iniciar el complemento y utilice espacios en blanco para separarlas. Utilice * si no desea especificar ninguna, para que el complemento se inicie sin ninguna palabra clave de acción.
+
+
+ Ajuste del tiempo de retardo de búsqueda
+ Seleccionar el tiempo de retardo de búsqueda que se desea utilizar para el complemento. Seleccionar "{0}" si no se desea especificar nada, y el complemento utilizará el tiempo de retardo de búsqueda predeterminado.
+ Tiempo de retardo de búsqueda actual
+ Nuevo tiempo de retardo de búsqueda
Atajo de teclado de consulta personalizada
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index d0d1d010d0b..e46e0dc9de3 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -7,6 +7,11 @@
Cliquez sur non s'il est déjà installé, et vous serez invité à sélectionner le dossier qui contient l'exécutable {1}
Veuillez sélectionner l'exécutable {0}
+
+ L'exécutable {0} que vous avez sélectionné est invalide.
+ {2}{2}
+ Cliquez sur oui si vous souhaitez sélectionner l'exécutable {0} à nouveau. Cliquez sur non si vous souhaitez télécharger {1}.
+
Impossible de définir {0} comme chemin d'accès vers l'exécutable. Veuillez essayer à partir des paramètres de Flow (défiler vers le bas).
Échec de l'initialisation des plugins
Plugins : {0} - n'ont pas pu être chargés et doivent être désactivés, veuillez contacter le créateur du plugin pour obtenir de l'aide
@@ -37,7 +42,7 @@
Mode jeu
Suspend l'utilisation des raccourcis claviers.
Réinitialiser la position
- Rétablir la position de la fenêtre de recherche
+ Tapez ici pour rechercher
Paramètres
@@ -70,8 +75,6 @@
Ne pas afficher la dernière recherche
Conserver le mot clé de la dernière action
Sélectionnez le mot clé de la dernière action
- Hauteur de fenêtre fixe
- La hauteur de la fenêtre n'est pas réglable par glissement.
Résultats maximums à afficher
Vous pouvez également ajuster ce paramètre en utilisant CTRL+Plus ou CTRL+Moins.
Ignore les raccourcis lorsqu'une application est en plein écran
@@ -102,6 +105,15 @@
Toujours prévisualiser
Toujours ouvrir le panneau d'aperçu lorsque Flow s'active. Appuyez sur {0} pour activer/désactiver l'aperçu.
L'effet d'ombre n'est pas autorisé lorsque le thème actuel à un effet de flou activé
+ Délai de recherche
+ Attendre un certain temps pour effectuer une recherche lors de la saisie. Cela permet de réduire les sauts d'interface et la charge des résultats.
+ Délai de recherche par défaut
+ Délai par défaut du plugin après lequel les résultats de la recherche s'affichent lorsque la saisie est interrompue.
+ Très long
+ Long
+ Normal
+ Court
+ Très court
Rechercher des plugins
@@ -118,6 +130,8 @@
Mot-clé d'action actuel
Nouveau mot-clé d'action
Changer les mots-clés d'action
+ Délai de recherche du plugin
+ Modifier le délai de recherche du plugin
Priorité actuelle
Nouvelle priorité
Priorité
@@ -131,6 +145,9 @@
Désinstaller
Échec de la suppression des paramètres du plugin
Plugins : {0} - Échec de la suppression des fichiers de configuration des plugins, veuillez les supprimer manuellement
+ Échec de la suppression du cache du plugin
+ Plugins : {0} - Échec de la suppression des fichiers cache des plugins, veuillez les supprimer manuellement
+ Défaut
Magasin des Plugins
@@ -193,8 +210,20 @@
Personnalisé
Heure
Date
+ Type d'arrière-plan
+ Arrière-plan pris en charge à partir de Windows 11 version 22000 et plus
+ Aucun
+ Acrylique
+ Mica
+ Mica Alt
Ce thème prend en charge deux modes (clair/sombre).
Ce thème prend en charge l'arrière-plan flou et transparent.
+ Afficher l'espace réservé
+ Afficher un espace réservé lorsque la requête est vide
+ Texte de l'espace réservé
+ Modifier le texte de l'espace réservé. Les entrées vides utiliseront : {0}
+ Taille de la fenêtre fixe
+ La taille de la fenêtre n'est pas réglable par glissement.
Raccourcis
@@ -293,6 +322,9 @@
Répertoire des journaux
Effacer le journal
Êtes-vous sûr de vouloir supprimer tous les journaux ?
+ Vider les caches
+ Êtes-vous sûr de vouloir supprimer tous les caches ?
+ Échec de l'effacement d'une partie des dossiers et des fichiers. Veuillez consulter le fichier journal pour plus d'informations
Assistant
Emplacement des données utilisateur
Les paramètres utilisateur et les plugins installés sont enregistrés dans le dossier des données utilisateur. Cet emplacement peut varier selon que vous soyez en mode portable ou non.
@@ -334,9 +366,16 @@
Impossible de trouver le module spécifi
Le nouveau mot-clé d'action doit être spécifi
Le nouveau mot-clé d'action a été assigné à un autre module, veuillez en choisir un autre
+ Ce nouveau mot-clé d'action est identique à l'ancien, veuillez en choisir un autre
Ajout
Terminé avec succès
- Saisissez * si vous ne souhaitez pas utiliser de mot-clé spécifique
+ Saisissez les mots-clés d'action que vous souhaitez utiliser pour lancer le plugin et séparez-les par des espaces. Utilisez * si vous ne voulez en spécifier aucun, et le plugin sera déclenché sans aucun mot-clé d'action.
+
+
+ Réglage du délai de recherche
+ Sélectionnez le délai de recherche que vous souhaitez utiliser pour le plugin. Sélectionnez "{0}" si vous ne voulez pas en spécifier, et le plugin utilisera le délai de recherche par défaut.
+ Délai de recherche actuel
+ Nouveau délai de recherche
Requêtes personnalisées
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index c912052f10e..38e943cda2a 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -7,6 +7,11 @@
אם זה כבר מותקן, לחץ על 'לא' ותתבקש לבחור את התיקיה המכילה את קובץ ההפעלה {1}
אנא בחר את קובץ ההפעלה {0}
+
+ קובץ ההפעלה {0} שבחרת אינו חוקי.
+ {2}{2}
+ לחץ על כן אם ברצונך, בחר את {0} ההפעלה הקודמת. לחץ על לא אם ברצונך להוריד את {1}
+
לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).
נכשל בהפעלת תוספים
תוספים: {0} - נכשלו בטעינה ויושבתו, אנא צור קשר עם יוצרי התוספים לקבלת עזרה
@@ -37,7 +42,7 @@
מצב משחק
השהה את השימוש במקשי קיצור.
איפוס מיקום
- אפס את מיקום חלון החיפוש
+ הקלד כאן כדי לחפש
הגדרות
@@ -70,8 +75,6 @@
נקה שאילתא אחרונה
שמור מילת מפתח לפעולה האחרונה
בחר מילת מפתח לפעולה האחרונה
- גובה חלון קבוע
- גובה החלון אינו ניתן להתאמה באמצעות גרירה.
כמות תוצאות מרבית
ניתן גם להתאים במהירות באמצעות CTRL+פלוס ו-CTRL+מינוס.
התעלם מקיצורי מקשים במצב מסך מלא
@@ -97,11 +100,20 @@
ללא
נמוך
Regular
- Search with Pinyin
+ חפש באמצעות Pinyin
Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
הצג תמיד תצוגה מקדימה
פתח תמיד את לוח התצוגה המקדימה כאשר Flow מופעל. הקש על {0} כדי להחליף את התצוגה המקדימה.
לא ניתן להחיל אפקט צל כאשר העיצוב הנוכחי מוגדר לאפקט טשטוש
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
חפש תוסף
@@ -118,6 +130,8 @@
מילת מפתח נוכחית לפעולה
מילת מפתח חדשה לפעולה
שנה מילות מפתח לפעולה
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
עדיפות נוכחית
עדיפות חדשה
עדיפות
@@ -131,6 +145,9 @@
הסר התקנה
נכשל בהסרת הגדרות התוסף
תוספים: {0} - נכשל בהסרת קבצי הגדרות התוסף, יש להסירם ידנית
+ נכשל בהסרת מטמון התוסף
+ תוספים: {0} - נכשל בהסרת קובצי מטמון התוסף, אנא הסר אותם ידנית
+ Default
חנות תוספים
@@ -156,7 +173,7 @@
סייר
חפש קבצים, תיקיות ובתוכן הקבצים
חיפוש באינטרנט
- Search the web with different search engine support
+ חפש באינטרנט עם תמיכה במנועי חיפוש שונים
תוכנה
הפעל תוכנות כמנהל או כמשתמש אחר
ProcessKiller
@@ -193,8 +210,20 @@
מותאם אישית
שעון
תאריך
+ סוג רקע
+ התמיכה ב-Backdrop קיימת החל מ-Windows 11 build 22000 ומעלה
+ ללא
+ אקריליק
+ מיקה
+ Mica Alt
ערכת נושא זאת תומך בשני מצבים (בהיר/כהה).
ערכת נושא זו תומכת בטשטוש רקע שקוף.
+ הצג מציין מיקום
+ הצג מציין מיקום כאשר השאילתה ריקה
+ טקסט מציין מיקום
+ שנה את טקסט מציין המיקום. אם הקלט ריק, ייעשה שימוש ב: {0}
+ גודל חלון קבוע
+ לא ניתן להתאים את גודל החלון באמצעות גרירה.
מקש קיצור
@@ -289,18 +318,21 @@
הערות שחרור
טיפים לשימוש
- DevTools
+ כלי פיתוח
תיקיית ההגדרות
תיקיית יומני רישום
נקה יומני רישום
האם אתה בטוח שברצונך למחוק את כל היומנים?
+ נקה נתוני מטמון
+ האם אתה בטוח שברצונך למחוק את כל הנתונים שבמטמון?
+ נכשל ניקוי חלק מהתיקיות והקבצים. עיין בלוג לקבלת מידע נוסף
אשף
מיקום נתוני משתמש
הגדרות המשתמש והתוספים המותקנים נשמרים בתיקיית נתוני המשתמש. מיקום זה עשוי להשתנות אם התוכנה במצב נייד.
פתח תיקיה
Log Level
- Debug
- Info
+ ניפוי שגיאות
+ מידע
בחר מנהל קבצים
@@ -335,9 +367,16 @@
לא ניתן למצוא את התוסף שצוין
מילת הפעולה החדשה לא יכולה להיות ריקה
מילת הפעולה החדשה כבר מוקצה לתוסף אחר, אנא בחר אחת שונה
+ מילת הפעולה החדשה זהה לישנה, נא לבחור מילת פעולה שונה
הצליח
הושלם בהצלחה
- הזן את מילת הפעולה שברצונך להשתמש בה להפעלת התוסף. השתמש ב-* אם אינך רוצה לציין מילה כלשהי, והתוסף יופעל ללא צורך במילת פעולה.
+ הזן את מילות הפעולה שבהן תרצה להשתמש כדי להפעיל את התוסף, והשתמש ברווחים כדי להפריד ביניהן. השתמש ב-* אם אינך רוצה להגדיר כלל, והתוסף יופעל ללא מילות פעולה.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
מקש קיצור לשאילתה מותאמת אישית
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index e4d4d3e2cbb..fd34bf36625 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Modalità gioco
Sospendere l'uso dei tasti di scelta rapida.
Ripristina Posizione
- Ripristina posizione finestra di ricerca
+ Type here to search
Impostazioni
@@ -70,8 +75,6 @@
Cancella ultima ricerca
Preserve Last Action Keyword
Select Last Action Keyword
- Altezza Finestra Fissa
- L'altezza della finestra non si può regolare trascinando.
Numero massimo di risultati mostrati
È anche possibile regolarlo rapidamente utilizzando CTRL+Più e CTRL+Meno.
Ignora i tasti di scelta rapida in applicazione a schermo pieno
@@ -102,6 +105,15 @@
Mostra Sempre Anteprima
Apri sempre il pannello di anteprima quando Flow si attiva. Premi {0} per attivare l'anteprima.
L'effetto ombra non è consentito mentre il tema corrente ha un effetto di sfocatura abilitato
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Plugin di ricerca
@@ -118,6 +130,8 @@
Parola chiave di azione corrente
Nuova parola chiave d'azione
Cambia Keywords Azione
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Priorità Attuale
Nuova Priorità
Priorità
@@ -131,6 +145,9 @@
Disinstalla
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Negozio dei Plugin
@@ -193,8 +210,20 @@
Personalizzato
Orologio
Data
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Vuoto
+ Acrylic
+ Mica
+ Mica Alt
Questo tema supporta due (chiaro/scuro) varianti.
Questo tema supporta lo sfondo trasparente blurrato.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Tasti scelta rapida
@@ -294,6 +323,9 @@
Cartella dei Log
Cancella i log
Sei sicuro di voler cancellare tutti i log?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
Posizione Dati Utente
Le impostazioni dell'utente e i plugin installati sono salvati nella cartella dati utente. Questa posizione può variare se è in modalità portable o no.
@@ -335,9 +367,16 @@
Impossibile trovare il plugin specificato
La nuova parola chiave d'azione non può essere vuota
La nuova parola chiave d'azione è stata assegnata ad un altro plugin, per favore sceglierne una differente
+ This new Action Keyword is the same as old, please choose a different one
Successo
Completato con successo
- Usa * se non vuoi specificare una parola chiave d'azione
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Tasti scelta rapida per ricerche personalizzate
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index 28c3346679a..e6f2223cd22 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
ゲームモード
ホットキーの使用を一時停止します。
位置のリセット
- 検索ウィンドウの位置をリセットします。
+ Type here to search
設定
@@ -70,8 +75,6 @@
前回のクエリを消去
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
結果の最大表示件数
CTRL+PlusとCTRL+Minusを使用すれば、簡単に調整することもできます。
ウィンドウがフルスクリーン時にホットキーを無効にする
@@ -102,6 +105,15 @@
常にプレビューする
Flow が有効になったとき、常にプレビューパネルを開きます。 {0} を押してプレビューの表示/非表示を切り替えます。
現在のテーマでぼかしの効果が有効になっている場合、影の効果を有効にすることはできません
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Search Plugin
@@ -118,6 +130,8 @@
Current action keyword
New action keyword
Change Action Keywords
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Current Priority
New Priority
重要度
@@ -131,6 +145,9 @@
アンインストール
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
プラグインストア
@@ -193,8 +210,20 @@
カスタム
時刻
日付
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
ホットキー
@@ -294,6 +323,9 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
プラグインが見つかりません
新しいアクションキーボードを空にすることはできません
新しいアクションキーボードは他のプラグインに割り当てられています。他のアクションキーボードを指定してください
+ This new Action Keyword is the same as old, please choose a different one
成功しました
Completed successfully
- アクションキーボードを指定しない場合、* を使用してください
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index d9da26bcb21..3aee3f5e4aa 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
게임 모드
단축키 사용을 일시중단합니다.
창 위치 초기화
- 검색창 위치 초기화
+ 검색어 입력
설정
@@ -45,8 +50,8 @@
포터블 모드
모든 설정이 폴더안에 들어갑니다. USB 드라이브나 클라우드로 사용 가능합니다.
시스템 시작 시 Flow Launcher 실행
- Use logon task instead of startup entry for faster startup experience
- After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler
+ 더 빠른 시작을 위해 시작 프로그램 항목 대신 로그온 Task 사용
+ Flow Launcher를 제거한 후에는 작업 스케줄러에서 이 작업(Flow.Launcher Startup)을 수동으로 삭제해야 합니다
Error setting launch on startup
포커스 잃으면 Flow Launcher 숨김
새 버전 알림 끄기
@@ -70,8 +75,6 @@
직전 쿼리 지우기
Preserve Last Action Keyword
Select Last Action Keyword
- 창 높이 고정
- 드래그로 창 높이를 조정하지 않습니다.
표시할 결과 수
Ctrl + '+'키와 Ctrl + '-'키로도 빠르게 조정할 수 있습니다
전체화면 모드에서는 단축키 무시
@@ -89,7 +92,7 @@
자동 업데이트
선택
시작 시 Flow Launcher 숨김
- Flow Launcher search window is hidden in the tray after starting up.
+ Flowr Launcher가 트레이에 숨겨진 상태로 시작합니다.
트레이 아이콘 숨기기
트레이에서 아이콘을 숨길 경우, 검색창 우클릭으로 설정창을 열 수 있습니다.
쿼리 검색 정밀도
@@ -102,6 +105,15 @@
항상 미리보기
Flow 사용시 항상 미리보기 패널을 열어둡니다. {0} 키를 눌러 프리뷰창을 켜고 끌 수 있습니다.
반투명 흐림 효과를 사용하는 경우, 그림자 효과를 쓸 수 없습니다.
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
플러그인 검색
@@ -118,6 +130,8 @@
현재 액션 키워드
새 액션 키워드
액션 키워드 변경
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
현재 중요도:
새 중요도:
중요도
@@ -131,6 +145,9 @@
제거
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
플러그인 스토어
@@ -193,8 +210,20 @@
사용자 정의
시계
날짜
+ 배경 효과 타입
+ Backdrop supported starting from Windows 11 build 22000 and above
+ 없음
+ 아크릴
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ 안내 텍스트 표시
+ 입력 내용이 없을때 입력창 위치를 알 수 있는 텍스트를 표시합니다
+ 안내 텍스트
+ 안내 텍스트를 변경하세요. 아무것도 입력하지 않으면 다음을 사용합니다: "{0}"
+ Fixed Window Size
+ The window size is not adjustable by dragging.
단축키
@@ -294,6 +323,9 @@
로그 폴더
로그 삭제
정말 모든 로그를 삭제하시겠습니까?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
마법사
사용자 데이터 위치
사용자 설정과 설치된 플러그인은 사용자 데이터 폴더에 저장됩니다. 이 위치는 휴대용 모드 활성화 여부에 따라 달라질 수 있습니다.
@@ -335,9 +367,16 @@
플러그인을 찾을 수 없습니다.
새 액션 키워드를 입력하세요.
새 액션 키워드가 할당된 플러그인이 이미 있습니다. 다른 액션 키워드를 입력하세요.
+ This new Action Keyword is the same as old, please choose a different one
성공
성공적으로 완료했습니다.
- 플러그인을 시작하는데 필요한 액션 키워드를 입력하세요. 액션 키워드를 지정하지 않으려면 *를 사용하세요. 이 경우 키워드를 입력하지 않아도 동작합니다.
+ 플러그인을 실행할 때 사용할 액션 키워드를 입력하세요. 여러 개를 입력할 경우 공백으로 구분하세요. 아무 키워드도 지정하지 않으려면 * 를 입력하세요. 이 경우 액션 키워드 없이도 플러그인이 실행됩니다.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
사용자지정 쿼리 단축키
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index a37a204e101..b78bcb7d718 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -7,6 +7,11 @@
Klikk nei hvis det allerede er installert, og du vil bli bedt om å velge mappen som inneholder {1} kjørbar fil
Velg den kjørbare filen for {0}
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Kan ikke angi {0} kjørbar bane, prøv fra Flows innstillinger (bla ned til bunnen).
Mislykkes i å initialisere programtillegg
Programtillegg: {0} - mislykkes å lastes inn og vil bli deaktivert, vennligst kontakt utvikleren av programtillegget for hjelp
@@ -37,7 +42,7 @@
Spillmodus
Stopp bruken av hurtigtaster.
Tilbakestilling av posisjon
- Tilbakestill posisjonen til søkevinduet
+ Type here to search
Innstillinger
@@ -70,8 +75,6 @@
Tøm siste spørring
Preserve Last Action Keyword
Select Last Action Keyword
- Fast vindushøyde
- Vindushøyden kan ikke justeres ved å dra.
Maksimalt antall resultater vist
Du kan også raskt justere dette ved å bruke CTRL+Plus og CTRL+Minus.
Ignorer hurtigtaster i fullskjermmodus
@@ -102,6 +105,15 @@
Alltid forhåndsvisning
Åpne alltid forhåndsvisningspanel når Flow aktiveres. Trykk på {0} for å velge forhåndsvisning.
Skyggeeffekt er ikke tillatt mens gjeldende tema har uskarphet-effekt aktivert
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Søk etter programtillegg
@@ -118,6 +130,8 @@
Nåværende handlingsnøkkelord
Nytt handlingsnøkkelord
Endre handlingsnøkkelord
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Gjeldende prioritet
Ny prioritet
Prioritet
@@ -131,6 +145,9 @@
Avinstaller
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Programtillegg butikk
@@ -193,8 +210,20 @@
Egendefinert
Klokke
Dato
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Ingen
+ Acrylic
+ Mica
+ Mica Alt
Dette temaet støtter to (lys/mørk) moduser.
Dette temaet støtter uskarp gjennomsiktig bakgrunn.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Hurtigtast
@@ -294,6 +323,9 @@
Loggmappe
Tøm logger
Er du sikker på at du vil slette alle loggene?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Veiviser
Plassering av brukerdata
Brukerinnstillinger og installerte programtillegg lagres i brukerens datamappe. Denne plasseringen kan variere avhengig av om den er i portabel modus eller ikke.
@@ -335,9 +367,16 @@
Kan ikke finne spesifisert programtillegg
Nytt handlingsnøkkelord kan ikke være tom
Det nye nøkkelordet for handling er allerede tilordnet et annet programtillegg, velg et annet
+ This new Action Keyword is the same as old, please choose a different one
Vellykket
Fullført vellykket
- Skriv inn handlingsnøkkelord du vil bruke for å starte programtillegget. Bruk * hvis du ikke ønsker å spesifisere noen, og utvidelsen vil bli utløst uten noen handlingsord.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Hurtigtast for egendefinert spørring
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index 64adccd9420..ce340614218 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Spelmodus
Stop het gebruik van Sneltoetsen.
Positie resetten
- Positie zoekvenster resetten
+ Type here to search
Instellingen
@@ -70,8 +75,6 @@
Laatste zoekopdracht verwijderen
Preserve Last Action Keyword
Select Last Action Keyword
- Vaste venster hoogte
- De vensterhoogte is niet aanpasbaar door te slepen.
Laat maximale resultaten zien
Je kunt dit ook snel aanpassen met CTRL+Plus en CTRL+Minus.
Negeer sneltoetsen in vol scherm modus
@@ -102,6 +105,15 @@
Altijd voorbeeld
Open altijd het voorbeeld paneel wanneer Flow activeert. Druk op {0} om voorbeeld te schakelen.
Schaduw effect is niet toegestaan omdat het huidige thema een vervagingseffect heeft
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Plug-ins zoeken
@@ -118,6 +130,8 @@
Huidige actie sneltoets
Nieuw actie sneltoets
Wijzig actie-sneltoets
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Huidige Prioriteit
Nieuwe Prioriteit
Prioriteit
@@ -131,6 +145,9 @@
Verwijderen
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Plugin Winkel
@@ -193,8 +210,20 @@
Aangepast
Klok
Datum
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
Dit thema ondersteunt twee (licht/donker) modi.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Sneltoets
@@ -294,6 +323,9 @@
Log Map
Logbestanden wissen
Weet u zeker dat u alle logbestanden wilt verwijderen?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
Gegevenslocatie van gebruiker
Gebruikersinstellingen en geïnstalleerde plug-ins worden opgeslagen in de gebruikersgegevensmap. Deze locatie kan variëren afhankelijk van of het in draagbare modus is of niet.
@@ -335,9 +367,16 @@
Kan plugin niet vinden
Nieuwe actie sneltoets moet ingevuld worden
Nieuwe actie sneltoets is toegewezen aan een andere plugin, wijs een nieuwe actie sneltoets aan
+ This new Action Keyword is the same as old, please choose a different one
Succesvol
Succesvol afgerond
- Gebruik * wanneer je geen nieuwe actie sneltoets wilt specificeren
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Custom Query Sneltoets
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 06204395cf3..12af37c3ed9 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -7,6 +7,11 @@
Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy poproszony o wybranie folderu zawierającego plik wykonywalny {1}
Wybierz plik wykonywalny {0}
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Nie można ustawić ścieżki do pliku wykonywalnego {0}. Spróbuj ponownie w ustawieniach Flow (przewiń na sam dół).
Nie udało się zainicjować wtyczek
Wtyczki: {0} – nie udało się ich wczytać i zostaną wyłączone. Skontaktuj się z twórcą wtyczki, aby uzyskać pomoc
@@ -37,7 +42,7 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Tryb grania
Wstrzymaj używanie skrótów.
Resetowanie pozycji
- Zresetuj pozycję okna wyszukiwania
+ Type here to search
Ustawienia
@@ -70,8 +75,6 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Puste ostatnie zapytanie
Zachowaj ostatnie słowo kluczowe akcji
Wybierz ostatnie słowo kluczowe akcji
- Stała wysokość okna
- Wysokość okna nie jest regulowana poprzez przeciąganie.
Maksymalna liczba wyników
Możesz to również szybko dostosować używając CTRL+Plus i CTRL+Minus.
Ignoruj skróty klawiszowe w trybie pełnoekranowym
@@ -102,6 +105,15 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Zawsze podgląd
Zawsze otwieraj panel podglądu, gdy aktywowany jest Flow. Naciśnij {0}, aby przełączyć podgląd.
Efekt cienia jest niedozwolony, gdy bieżący motyw ma włączony efekt rozmycia
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Szukaj wtyczek
@@ -118,6 +130,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Bieżące słowo kluczowe akcji
Nowe słowo kluczowe akcji
Zmień słowa kluczowe akcji
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Obecny Priorytet
Nowy Priorytet
Priorytet
@@ -131,6 +145,9 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Odinstalowywanie
Nie udało się usunąć ustawień wtyczki
Wtyczki: {0} – nie udało się usunąć plików ustawień wtyczek, usuń je ręcznie
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Sklep z wtyczkami
@@ -193,8 +210,20 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Niestandardowa
Zegar
Data
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Brak
+ Acrylic
+ Mica
+ Mica Alt
Ten motyw obsługuje dwa tryby (jasny/ciemny).
Ten motyw obsługuje rozmyte przezroczyste tło.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Skrót klawiszowy
@@ -294,6 +323,9 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Folder dziennika
Wyczyść logi
Czy na pewno chcesz usunąć wszystkie logi?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Kreator
Lokalizacja danych użytkownika
Ustawienia użytkownika i zainstalowane wtyczki są zapisywane w folderze danych użytkownika. Ta lokalizacja może się różnić w zależności od tego, czy aplikacja jest w trybie przenośnym, czy nie.
@@ -335,9 +367,16 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Nie można odnaleźć podanej wtyczki
Nowy wyzwalacz nie może być pusty
Ten wyzwalacz został już przypisany do innej wtyczki, musisz podać inny wyzwalacz.
+ This new Action Keyword is the same as old, please choose a different one
Sukces
Zakończono pomyślnie
- Użyj * jeżeli nie chcesz podawać wyzwalacza
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Skrót klawiszowy niestandardowych zapyta
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index 62293b1a1ba..d0040d7995d 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Modo Gamer
Suspender o uso de Teclas de Atalho.
Redefinição de Posição
- Redefinir posição da janela de busca
+ Type here to search
Configurações
@@ -70,8 +75,6 @@
Limpar última consulta
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Máximo de resultados mostrados
Você também pode ajustar isso rapidamente usando CTRL+Mais e CTRL+Menos.
Ignorar atalhos em tela cheia
@@ -102,6 +105,15 @@
Sempre Pré-visualizar
Sempre abrir o painel de pré-visualização quando o Flow é ativado. Pressione {0} para ativar ou desativar a pré-visualização.
O efeito de sombra não é permitido enquanto o tema atual tem o efeito de desfoque ativado
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Buscar Plugin
@@ -118,6 +130,8 @@
Palavra-chave de ação atual
Nova palavra-chave de ação
Alterar Palavras-chave de Ação
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Prioridade atual
Nova Prioridade
Prioridade
@@ -131,6 +145,9 @@
Desinstalar
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Loja de Plugins
@@ -193,8 +210,20 @@
Personalizado
Relógio
Data
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Atalho
@@ -294,6 +323,9 @@
Pasta de Registro
Limpar Registros
Tem certeza que quer excluir todos os registros?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Assistente
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
Não foi possível encontrar o plugin especificado
A nova palavra-chave da ação não pode ser vazia
A nova palavra-chave da ação já foi atribuída a outro plugin, por favor tente outra
+ This new Action Keyword is the same as old, please choose a different one
Sucesso
Concluído com sucesso
- Use * se não quiser especificar uma palavra-chave de ação
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Atalho de Consulta Personalizada
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index bad37f688cb..9dc520cbd7e 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -7,6 +7,11 @@
Clique "Não" se já tiver instalado e, de seguida, ser-lhe-á solicitada a pasta que contém o executável {1}.
Por favor, selecione o executável {0}
+
+ O executável {0} é inválido.
+ {2}{2}
+ Clique Sim se quiser escolher o novo executável {0}. Clique Não se quiser descarregar {1}.
+
Não foi possível definir o caminho do executável {0}. Experimente definir o caminho nas definições (desloque até ao fundo).
Falha ao iniciar os plugins
Plugin: {0} - não foi possível iniciar e será desativado. Contacte o criador do plugin para obter ajuda.
@@ -37,7 +42,7 @@
Modo de jogo
Suspender utilização das teclas de atalho
Repor posição
- Repor posição da janela de pesquisa
+ Escreva aqui para pesquisar
Definições
@@ -70,8 +75,6 @@
Limpar última consulta
Manter palavra-chave da última ação
Selecionar palavra-chave da última ação
- Altura fixa de janela
- Não é possível ajustar o tamanho da janela por arrasto.
Número máximo de resultados
Também pode ajustar rapidamente através do atalho Ctrl+ e Ctrl-.
Ignorar teclas de atalho se em ecrã completo
@@ -102,6 +105,15 @@
Pré-visualizar sempre
Abrir painel de pré-visualização ao ativar Flow Launcher. Prima {0} para comutar a pré-visualização.
O efeito sombra não é permitido com este tema porque o efeito desfocar está ativo
+ Atraso da pesquisa
+ Tempo a esperar após a digitação. Esta definição melhora o carregamento dos resultados.
+ Tempo de espera padrão
+ O valor padrão a esperar, antes de iniciar a pesquisa após terminar a digitação.
+ Muito longo
+ Longo
+ Normal
+ Curto
+ Muito curto
Pesquisar plugins
@@ -118,6 +130,8 @@
Palavra-chave atual
Nova palavra-chave
Alterar palavras-chave
+ Tempo de espera do plugin
+ Alterar tempo de espera do plugin
Prioridade atual
Nova prioridade
Prioridade
@@ -131,6 +145,9 @@
Desinstalar
Falha ao remover as definições do plugin
Plugin: {0} - Falha ao remover o ficheiro de definições do plugin. Experimente remover manualmente.
+ Falha ao limpar a cache do plugin
+ Plugin: {0} - Falha ao remover os ficheiros em cache do plugin. Experimente remover manualmente.
+ Padrão
Loja de plugins
@@ -193,8 +210,20 @@
Personalizada
Relógio
Data
+ Tipo de fundo
+ Esta opção apenas está disponível em sistemas após Windows 11 Build 22000
+ Nenhuma
+ Acrílico
+ Mica
+ Mica alternativo
Este tema tem suporte a dois modos (claro/escuro).
Este tema tem suporte a fundo transparente desfocado.
+ Mostrar marcador de posição
+ Mostrar marcador de posição se a consulta estiver vazia
+ Texto do marcador
+ O texto do marcador de posição. Se vazio, será utilizado: {0}
+ Janela com tamanho fixo
+ Não pode ajustar o tamanho da janela por arrasto.
Tecla de atalho
@@ -293,13 +322,16 @@
Pasta de registos
Limpar registos
Tem a certeza de que deseja remover todos os registos?
+ Limpar cache
+ Tem a certeza de que pretende limpar todas as caches?
+ Não foi possível limpar todas as pastas e ficheiros. Consulte o ficheiro de registo para mais informações.
Assistente
Localização dos dados do utilizador
As definições e os plugins instalados são guardados na pasta de dados do utilizador. A localização pode variar, tendo em conta se a aplicação está instalada ou no modo portátil
Abrir pasta
- Log Level
- Debug
- Info
+ Nível de registo
+ Depuração
+ Informação
Selecione o gestor de ficheiros
@@ -334,9 +366,16 @@
Plugin não encontrado
A nova palavra-chave não pode estar vazia
Esta palavra-chave já está associada a um plugin. Por favor escolha outra.
+ A palavra-chave escolhida é igual à anterior. Por favor escolha outra.
Sucesso
Terminado com sucesso
- Introduza a palavra-chave a utilizar para iniciar o plugin. Utilize * se não quiser utilizar esta funcionalidade e o plugin não será ativado com palavras-chave.
+ Introduza as palavras-chave que pretende utilizar para iniciar o plugin e um espaço vazio caso queira mais do que uma. Utilize * se não quiser especificar uma palavra-chave e o plugin será ativado sem palavras-chave.
+
+
+ Definição do tempo de espera
+ Selecione o tempo de espera que pretende utilizar com este plugin. Selecione "{0}" se não o quiser especificar e, desta forma, o plugin irá utilizar o tempo de espera padrão.
+ Tempo de espera atual
+ Novo tempo de espera
Tecla de atalho personalizada
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index a56a770da18..c38855474ba 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Игровой режим
Приостановить использование горячих клавиш.
Сброс положения
- Сброс положения окна поиска
+ Type here to search
Настройки
@@ -70,8 +75,6 @@
Очистить последний запрос
Preserve Last Action Keyword
Select Last Action Keyword
- Фиксированная высота окна
- The window height is not adjustable by dragging.
Максимальное количество результатов
Вы также можете быстро настроить это с помощью CTRL+плюс и CTRL+минус.
Игнорировать горячие клавиши в полноэкранном режиме
@@ -102,6 +105,15 @@
Всегда предпросмотр
Всегда открывать панель предварительного просмотра при запуске Flow. Нажмите {0}, чтобы переключить предварительный просмотр.
Эффект тени не допускается, если в текущей теме включён эффект размытия
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Поиск плагина
@@ -118,6 +130,8 @@
Ключевое слово текущего действия
Ключевое слово нового действия
Изменить ключевое слово действия
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Текущий приоритет
Новый приоритет
Приоритет
@@ -131,6 +145,9 @@
Удалить
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Магазин плагинов
@@ -193,8 +210,20 @@
Своя
Часы
Дата
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Горячая клавиша
@@ -294,6 +323,9 @@
Папка журнала
Очистить журнал
Вы уверены, что хотите удалить все журналы?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Мастер
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
Не удалось найти заданный плагин
Новая горячая клавиша не может быть пустой
Новая горячая клавиша уже используется другим плагином. Пожалуйста, задайте новую
+ This new Action Keyword is the same as old, please choose a different one
Успешно
Выполнено успешно
- Введите горячую клавишу, которое вы хотите использовать для запуска плагина. Используйте *, если вы не хотите ничего указывать, и плагин будет запускаться без каких-либо горячих клавиш.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Задаваемые горячие клавиши для запросов
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index 332528b2b61..0f07387c631 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -7,6 +7,11 @@
Ak už ho máte nainštalovaný, kliknite na nie, a budete vyzvaný na zadanie cesty k priečinku spustiteľného súboru {1}
Vyberte spustiteľný súbor {0}
+
+ Vybrali ste nesprávny spustiteľný súbor {0}.
+ {2}{2}
+ Ak chcete znovu vybrať spustiteľný súbor {0}, kliknite na Áno. Kliknutím na Nie sa stiahne {1}.
+
Nie je možné nastaviť cestu ku spustiteľnému súboru {0}, skúste to v nastaveniach Flowu (prejdite nadol).
Nepodarilo sa inicializovať pluginy
Pluginy: {0} – nepodarilo sa načítať a mal by byť zakázaný, na pomoc kontaktujte autora pluginu
@@ -37,7 +42,7 @@
Herný režim
Pozastaviť používanie klávesových skratiek.
Resetovať pozíciu
- Resetovať pozíciu vyhľadávacieho okna
+ Zadajte text na vyhľadávanie
Nastavenia
@@ -70,8 +75,6 @@
Vymazať
Ponechať posledný akčný príkaz
Označiť posledný akčný príkaz
- Pevná výška okna
- Výška okna sa nedá nastaviť ťahaním.
Maximum výsledkov
Túto hodnotu môžete rýchlo upraviť aj pomocou klávesových skratiek CTRL + znamienko plus (+) a CTRL + znamienko mínus (-).
Ignorovať klávesové skratky v režime na celú obrazovku
@@ -102,6 +105,15 @@
Vždy zobraziť náhľad
Pri aktivácii Flowu vždy otvoriť panel s náhľadom. Stlačením klávesu {0} prepnete náhľad.
Efekt tieňa nie je povolený, kým má aktuálny motív povolený efekt rozostrenia
+ Oneskorenie vyhľadávania
+ Pri písaní sa na chvíľu oneskorí vyhľadávanie. Tým sa zníži skákanie rozhrania a načítanie výsledkov.
+ Predvolené oneskorenie vyhľadávania
+ Predvolené oneskorenie pluginu, po ktorom sa zobrazia výsledky vyhľadávania po zastavení písania.
+ Veľmi dlhé
+ Dlhé
+ Normálne
+ Krátke
+ Veľmi krátke
Vyhľadať plugin
@@ -118,6 +130,8 @@
Aktuálny aktivačný príkaz
Nový aktivačný príkaz
Upraviť aktivačný príkaz
+ Oneskorenie vyhľadávania pomocou pluginu
+ Zmení oneskorenie vyhľadávania pomocou pluginu
Aktuálna priorita
Nová priorita
Priorita
@@ -131,6 +145,9 @@
Odinštalovať
Nepodarilo sa odstrániť nastavenia pluginu
Pluginy: {0} – Nepodarilo sa odstrániť súbory s nastaveniami pluginu, odstráňte ich manuálne
+ Nepodarilo sa odstrániť vyrovnávaciu pamäť pluginu
+ Pluginy: {0} – Nepodarilo sa odstrániť vyrovnávaciu pamäť pluginu, odstráňte ju manuálne
+ Predvolené
Repozitár pluginov
@@ -193,8 +210,20 @@
Vlastné
Hodiny
Dátum
+ Typ pozadia
+ Backdrop je podporovaný od Windows 11 zostava 22000 a novších
+ Žiadna
+ Acrylic
+ Mica
+ Mica Alt
Tento motív podporuje 2 režimy (svetlý/tmavý).
Tento motív podporuje rozostrenie priehľadného pozadia.
+ Zobraziť zástupný text
+ Zobrazí zástupný text v prázdnom vyhľadávacom poli
+ Zástupný text
+ Zobrazí zástupný text. V prázdnom poli sa zobrazí: {0}
+ Pevná veľkosť okna
+ Veľkosť okna sa nedá nastaviť ťahaním.
Klávesové skratky
@@ -294,6 +323,9 @@
Priečinok s logmi
Vymazať logy
Naozaj chcete odstrániť všetky logy?
+ Vymazať vyrovnávaciu pamäť
+ Naozaj chcete vymazať všetky vyrovnávacie pamäte?
+ Nepodarilo sa odstrániť niektoré priečinky a súbory. Pre viac informácií si pozrite súbor logu
Sprievodca
Cesta k používateľskému priečinku
Nastavenia používateľa a nainštalované pluginy sa ukladajú do používateľského priečinka. Toto umiestnenie sa môže líšiť v závislosti od toho, či je v prenosnom režime alebo nie.
@@ -335,9 +367,16 @@
Nepodarilo sa nájsť zadaný plugin
Nový aktivačný príkaz nemôže byť prázdny
Nový aktivačný príkaz už bol priradený inému pluginu, prosím, zvoľte iný aktivačný príkaz
+ Tento nový aktivačný príkaz je rovnaký ako starý, vyberte iný
Úspešné
Úspešne dokončené
- Zadajte aktivačný príkaz, ktorý je potrebný na spustenie pluginu. Ak nechcete zadať aktivačný príkaz, použite * a plugin bude spustený bez aktivačného príkazu.
+ Zadajte aktivačné príkazy, ktoré chcete používať na spustenie pluginu a oddeľte ich medzerou. Ak nechcete zadať aktivačný príkaz, použite * a plugin bude spustený bez aktivačného príkazu.
+
+
+ Nastavenie oneskoreného vyhľadávania
+ Vyberte oneskorenie vyhľadávania, ktoré chcete použiť pre plugin. Ak vyberiete "{0}", plugin použije predvolené oneskorenie vyhľadávania.
+ Aktuálne oneskorenie vyhľadávania
+ Nové oneskorenie vyhľadávania
Klávesová skratka vlastného vyhľadávania
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index b244c46602b..1d1eb912047 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
- Reset search window position
+ Type here to search
Podešavanja
@@ -70,8 +75,6 @@
Isprazni poslednji Upit
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
Maksimum prikazanih rezultata
You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
Ignoriši prečice u fullscreen režimu
@@ -102,6 +105,15 @@
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Search Plugin
@@ -118,6 +130,8 @@
Current action keyword
New action keyword
Change Action Keywords
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Current Priority
New Priority
Priority
@@ -131,6 +145,9 @@
Uninstall
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Plugin Store
@@ -193,8 +210,20 @@
Custom
Clock
Date
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Prečica
@@ -294,6 +323,9 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
Navedeni plugin nije moguće pronaći
Prečica za novu radnju ne može da bude prazna
Prečica za novu radnju je dodeljena drugom plugin-u, molim Vas dodelite drugu prečicu
+ This new Action Keyword is the same as old, please choose a different one
Uspešno
Completed successfully
- Koristite * ako ne želite da navedete prečicu za radnju
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
prečica za ručno dodat upit
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index 5d550ebedea..b9b5d351edd 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Oyun Modu
Kısayol tuşlarının kullanımını durdurun.
Pencere Konumunu Sıfırla
- Arama penceresinin konumunu sıfırla
+ Type here to search
Ayarlar
@@ -70,8 +75,6 @@
Sorgu Kutusunu Temizle
Preserve Last Action Keyword
Select Last Action Keyword
- Sabit Pencere Yükseliği
- Pencere yüksekliği sürükleme ile ayarlanamaz.
Maksimum Sonuç Sayısı
Bunu CTRL + ve CTRL - kısayollarıyla da ayarlayabilirsiniz.
Tam Ekran Modunda Kısayol Tuşunu Gözardı Et
@@ -102,6 +105,15 @@
Önizleme
Önizleme panelini her zaman aç. Önizlemeyi bu ayardan bağımsız {0} kısayolu ile açıp kapatabilirsiniz.
Mevcut temada bulanıklık efekti etkinken gölgelendirme efektine izin verilmez
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Eklenti Ara
@@ -118,6 +130,8 @@
Geçerli anahtar kelime
Yeni anahtar kelime
Anahtar kelimeyi değiştir
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Mevcut öncelik
Yeni Öncelik
Öncelik
@@ -131,6 +145,9 @@
Kaldır
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Eklenti Mağazası
@@ -193,8 +210,20 @@
Özel
Saat
Tarih
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Hiçbiri
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Kısayol Tuşu
@@ -294,6 +323,9 @@
Günlük Klasörü
Günlükleri Temizle
Tüm günlük kayıtlarını silmek istediğinize emin misiniz?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Kurulum Sihirbazı
Kullanıcı Verisi Dizini
Kullanıcı ayarları ve yüklü eklentiler bu klasörde saklanır. Klasörün konumu taşınabilir moda bağlı olarak değişebilir.
@@ -335,9 +367,16 @@
Belirtilen eklenti bulunamadı
Yeni anahtar kelime boş olamaz
Yeni anahtar kelime başka bir eklentiye atanmış durumda. Lütfen başka bir anahtar kelime seçin.
+ This new Action Keyword is the same as old, please choose a different one
Başarılı
Başarıyla tamamlandı
- Herhangi bir anahtar kelime belirlemek istemiyorsanız * kullanın
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Özel Sorgu Kısayolları
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index 95a746a51cb..427511c6630 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -7,6 +7,11 @@
Клацніть Ні, якщо воно вже встановлене, і вам буде запропоновано вибрати теку, яка містить виконуваник {1}
Будласка оберіть виконуваник {0}
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Не вдається встановити шлях до виконуваника {0}, будласка спробуйте в налаштуваннях Flow (прокрутіть вниз до кінця).
Невдача ініціалізації плагінів
Плагіни: {0} - не вдалося підвантажити і буде вимкнено, зверніться за допомогою до автора плагіна
@@ -37,7 +42,7 @@
Режим гри
Призупинити використання гарячих клавіш.
Скидання позиції
- Скинути положення вікна пошуку
+ Type here to search
Налаштування
@@ -70,8 +75,6 @@
Очистити останній запит
Preserve Last Action Keyword
Select Last Action Keyword
- Фіксована висота вікна
- Висота вікна не регулюється перетягуванням.
Максимальна кількість результатів
Ви також можете швидко налаштувати цей параметр за допомогою клавіш CTRL+Плюс чи CTRL+Мінус.
Ігнорувати гарячі клавіші в повноекранному режимі
@@ -102,6 +105,15 @@
Завжди переглядати
Завжди відкривати панель попереднього перегляду при активації Flow. Натисніть {0}, щоб переключити попередній перегляд.
Ефект тіні не дозволено, коли поточна тема має ефект розмиття
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Плагін для пошуку
@@ -118,6 +130,8 @@
Поточна гаряча клавіша
Нова гаряча клавіша
Змінити гарячі клавіши
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Поточний пріоритет
Новий пріоритет
Пріоритет
@@ -131,6 +145,9 @@
Видалити
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Магазин плагінів
@@ -193,8 +210,20 @@
Користувацька
Годинник
Дата
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Нема
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
Ця тема підтримує розмитий прозорий фон.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Гаряча клавіша
@@ -294,6 +323,9 @@
Тека журналу
Очистити журнали
Ви впевнені, що хочете видалити всі журнали?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Чаклун
Розташування даних користувача
Налаштування користувача та встановлені плагіни зберігаються у теці даних користувача. Це місце може змінюватися залежно від того, чи перебуває програма в портативному режимі, чи ні.
@@ -335,9 +367,16 @@
Не вдалося знайти вказаний плагін
Нова гаряча клавіша не може бути порожньою
Нова гаряча клавіша вже використовується іншим плагіном. Будь ласка, вкажіть нову
+ This new Action Keyword is the same as old, please choose a different one
Успішно
Успішно завершено
- Введіть гарячу клавішу, яку ви хочете використовувати для запуску плагіна. Використовуйте * у разі, якщо ви не хочете ставити конкретну гарячу клавішу.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Задані гарячі клавіші для запитів
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index 17e421e1681..6223efc0006 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -7,6 +7,11 @@
Hãy chọn không nếu nó đã được cài đặt, và bạn sẽ được hỏi chọn thư mục chứa chương trình thực thi {1}
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
Chế độ trò chơi
Tạm dừng sử dụng phím nóng.
Đặt lại vị trí
- Đặt lại vị trí của cửa sổ tìm kiếm
+ Type here to search
Cài đặt
@@ -70,8 +75,6 @@
Trống truy vấn cuối cùng
Preserve Last Action Keyword
Select Last Action Keyword
- Giữ nguyên chiều cao cửa sổ
- Chiều cao cửa sổ không thể thay đổi bằng cách kéo.
Số kết quả tối đa
Có thể thiết lập nhanh chóng bằng CTRL+Plus và CTRL+Minus.
Bỏ qua phím nóng khi cửa sổ ở chế độ toàn màn hình
@@ -102,6 +105,15 @@
Luôn xem trước
Luôn mở bảng xem trước khi Flow kích hoạt. Nhấn {0} để chuyển đổi chế độ xem trước.
Hiệu ứng đổ bóng không được phép nếu chủ đề hiện tại bật hiệu ứng làm mờ
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Plugin tìm kiếm
@@ -118,6 +130,8 @@
Từ hành động hiện tại
Từ hành động mới
Thay đổi từ hành động
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
Ưu tiên hiện tại
Ưu tiên mới
Ưu tiên
@@ -131,6 +145,9 @@
Gỡ cài đặt
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
Tải tiện ích mở rộng
@@ -193,8 +210,20 @@
Tùy chỉnh
Giờ
Ngày
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ Không
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
Phím tắt
@@ -296,6 +325,9 @@
Thư mục nhật ký
Xóa tệp nhật ký
Bạn có chắc chắn muốn xóa tất cả nhật ký không?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
Wizard
Vị trí dữ liệu người dùng
Thiết đặt người dùng và plugin đã cài đặt sẽ được lưu trong thư mục dữ liệu người dùng. Vị trí này có thể thay đổi tùy thuộc vào việc nó có ở chế độ di động hay không.
@@ -337,9 +369,16 @@
Không thể tìm thấy plugin được chỉ định
Từ khóa hành động mới không được để trống
Từ khóa hành động mới này đã được gán cho một plugin khác, vui lòng chọn một plugin khác
+ This new Action Keyword is the same as old, please choose a different one
Thành công
Đã hoàn tất thành công
- Sử dụng * nếu bạn muốn xác định từ khóa hành động.
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
Phím nóng truy vấn tùy chỉnh
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index d9966d757ed..3d302da5ba1 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -7,6 +7,11 @@
如果已安装,请单击“否”,系统将提示您选择包含 {1} 可执行文件的文件夹
请选择 {0} 可执行文件
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
无法设置 {0} 可执行路径,请尝试从 Flow 的设置中设置(向下滚动到底部)。
无法初始化插件
插件:{0} - 无法加载并将被禁用,请联系插件创建者寻求帮助
@@ -37,7 +42,7 @@
游戏模式
暂停使用热键。
重置位置
- 重置搜索窗口位置
+ Type here to search
设置
@@ -70,8 +75,6 @@
清空上次搜索关键字
Preserve Last Action Keyword
Select Last Action Keyword
- 固定窗口高度
- 窗口高度不能通过拖动来调整。
最大结果显示个数
您也可以通过使用 CTRL+ "+" 和 CTRL+ "-" 来快速调整它。
全屏模式下忽略热键
@@ -102,6 +105,15 @@
始终打开预览
Flow 启动时总是打开预览面板。按 {0} 以切换预览。
当前主题已启用模糊效果,不允许启用阴影效果
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
搜索插件
@@ -118,6 +130,8 @@
当前触发关键字
新触发关键字
更改触发关键字
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
当前优先级
新优先级
优先级
@@ -131,6 +145,9 @@
卸载
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
插件商店
@@ -193,8 +210,20 @@
自定义
时钟
日期
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ 无
+ Acrylic
+ Mica
+ Mica Alt
该主题支持两种(浅色/深色)模式。
该主题支持模糊透明背景。
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
热键
@@ -294,6 +323,9 @@
日志目录
清除日志
你确定要删除所有的日志吗?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
向导
用户数据位置
用户设置和已安装的插件保存在用户数据文件夹中。此位置可能因是否处于便携模式而异。
@@ -335,9 +367,16 @@
找不到指定的插件
新触发关键字不能为空
此触发关键字已经被指派给其他插件了,请换一个关键字
+ This new Action Keyword is the same as old, please choose a different one
成功
成功完成
- 如果你不想设置触发关键字,可以使用*代替
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
自定义查询热键
@@ -371,7 +410,7 @@
更新
是
否
- 背景
+ 后台
版本
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index 01b667e728c..cecad8e0dcb 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -7,6 +7,11 @@
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
Please select the {0} executable
+
+ Your selected {0} executable is invalid.
+ {2}{2}
+ Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+
Unable to set {0} executable path, please try from Flow's settings (scroll down to the bottom).
Fail to Init Plugins
Plugins: {0} - fail to load and would be disabled, please contact plugin creator for help
@@ -37,7 +42,7 @@
遊戲模式
暫停使用快捷鍵。
重設位置
- 重設搜尋視窗位置
+ Type here to search
設定
@@ -70,8 +75,6 @@
清空上次搜尋關鍵字
Preserve Last Action Keyword
Select Last Action Keyword
- Fixed Window Height
- The window height is not adjustable by dragging.
最大結果顯示個數
You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.
全螢幕模式下忽略快捷鍵
@@ -102,6 +105,15 @@
一律預覽
當 Flow 啟動時,一律開啟預覽面板。按下 {0} 可切換預覽。
Shadow effect is not allowed while current theme has blur effect enabled
+ Search Delay
+ Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Default Search Delay Time
+ Plugin default delay time after which search results appear when typing is stopped.
+ Very long
+ Long
+ Normal
+ Short
+ Very short
Search Plugin
@@ -118,6 +130,8 @@
目前觸發關鍵字
新觸發關鍵字
更改觸發關鍵字
+ Plugin seach delay time
+ Change Plugin Seach Delay Time
目前優先
新增優先
優先
@@ -131,6 +145,9 @@
解除安裝
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
+ Fail to remove plugin cache
+ Plugins: {0} - Fail to remove plugin cache files, please remove them manually
+ Default
插件商店
@@ -193,8 +210,20 @@
Custom
時鐘
日期
+ Backdrop Type
+ Backdrop supported starting from Windows 11 build 22000 and above
+ None
+ Acrylic
+ Mica
+ Mica Alt
This theme supports two(light/dark) modes.
This theme supports Blur Transparent Background.
+ Show placeholder
+ Display placeholder when query is empty
+ Placeholder text
+ Change placeholder text. Input empty will use: {0}
+ Fixed Window Size
+ The window size is not adjustable by dragging.
快捷鍵
@@ -294,6 +323,9 @@
日誌資料夾
清除日誌
請確認要刪除所有日誌嗎?
+ Clear Caches
+ Are you sure you want to delete all caches?
+ Failed to clear part of folders and files. Please see log file for more information
嚮導
User Data Location
User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not.
@@ -335,9 +367,16 @@
找不到指定的插件
新觸發關鍵字不能為空白
新觸發關鍵字已經被指派給另一個插件,請設定其他關鍵字。
+ This new Action Keyword is the same as old, please choose a different one
成功
成功完成
- 如果不想設定觸發關鍵字,可以使用*代替
+ Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+
+
+ Search Delay Time Setting
+ Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
+ Current search delay time
+ New search delay time
自定義快捷鍵查詢
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/sk.xaml
index 4cdd4c934d5..d8d3a586f53 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/sk.xaml
@@ -2,7 +2,7 @@
Kalkulačka
- Spracúva matematické operácie.(Skúste 5*3-2 vo flowlauncheri)
+ Spracúva matematické operácie. (Skúste 5*3-2 vo Flow Launcheri)
Nie je číslo (NaN)
Nesprávny alebo neúplný výraz (Nezabudli ste na zátvorky?)
Kopírovať výsledok do schránky
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
index 41a4abfcf81..cc78c9a9a47 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
@@ -4,6 +4,6 @@
Activate {0} plugin action keyword
플러그인 인디케이터
- 플러그인의 액션 키워드 제안을 제공합니다
+ 사용중인 플러그인들의 전체 액션 키워드 목록을 보여줍니다
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/de.xaml
index df162af9254..47ea31cceee 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/de.xaml
@@ -13,8 +13,8 @@
Plugin wird installiert
{0} herunterladen und installieren
Plug-in-Deinstallation
- Keep plugin settings
- Do you want to keep the settings of the plugin for the next usage?
+ Plug-in-Einstellungen beibehalten
+ Möchten Sie die Einstellungen des Plug-ins für die nächste Nutzung beibehalten?
Plug-in {0} erfolgreich installiert. Flow wird neu gestartet, bitte warten Sie ...
Die Metadaten-Datei plugin.json in der entpackten Zip-Datei kann nicht gefunden werden.
Fehler: Ein Plug-in, welches die gleiche oder eine höhere Version mit {0} hat, ist bereits vorhanden.
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
index 4104bd7570e..04619239de1 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
@@ -8,4 +8,6 @@
قتل عمليات {0}
قتل جميع الأمثلة
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
index 4dc11fcec20..d621b63c4d5 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
@@ -8,4 +8,6 @@
ukončit {0} procesů
ukončit všechny instance
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
index 8697818dc89..766d170a49b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
@@ -8,4 +8,6 @@
{0} Prozesse beenden
Alle Instanzen beenden
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
index 2dd0745c326..9b4a20a69ab 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
@@ -8,4 +8,6 @@
terminar {0} procesos
termina todas las instancias
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
index 27fda1db7f9..ab788075e73 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
@@ -8,4 +8,6 @@
finalizar {0} procesos
finalizar todas las instancias
+ Colocar procesos con ventanas visibles en la parte superior
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
index ec880406a93..7064de1fe1b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
@@ -8,4 +8,6 @@
Tuer {0} processus
Tuer toutes les instances
+ Placer les processus dont les fenêtres sont visibles en haut de la page
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
index 018435eca0f..8567b541255 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
@@ -8,4 +8,6 @@
סגור {0} תהליכים
סגור את כל המופעים
+ הצב תהליכים עם חלונות גלויים בחלק העליון
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
index 1ea52e741e1..1333fe573be 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
@@ -8,4 +8,6 @@
termina {0} processi
termina tutte le istanze
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
index a19c958b494..c3d1f6d083f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
@@ -8,4 +8,6 @@
{0} 프로세스 종료
모든 인스턴스 종료
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
index f0612188775..1210818bfc7 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
@@ -8,4 +8,6 @@
terminer {0} processes
terminer alle forekomstene
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
index c4cc8546346..cfcd71c3775 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Zet processen met zichtbare vensters bovenaan
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
index a111f8776a4..650f146575d 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
@@ -8,4 +8,6 @@
zamknij {0} procesów
zamknij wszystkie instancje
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
index b5c75f2d984..944a883c933 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
@@ -8,4 +8,6 @@
terminar {0} processos
terminar todas as instâncias
+ Colocar processos com janelas visíveis por cima
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
index 26963bddb18..0e2bef05283 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
@@ -8,4 +8,6 @@
удалить {0} процессов
удалить все экземпляры
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
index bfa4792e48c..2b06d3bbe13 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
@@ -8,4 +8,6 @@
ukončiť {0} procesov
ukončiť všetky inštancie
+ Zobraziť procesy s viditeľným oknom navrchu
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
index e23f43875b6..02dab46ba7b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
@@ -8,4 +8,6 @@
вбити {0} процесів
вбити всі екземпляри
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
index 0bf065ee165..89fd67635fa 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
@@ -8,4 +8,6 @@
Buộc tắt các tiến trình {0}
Tắt tất cả phên bản
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
index 160ca5f9614..15e717c79c3 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
@@ -8,4 +8,6 @@
杀死 {0} 进程
杀死所有实例
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
index c4cc8546346..8563f49a0e2 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
@@ -8,4 +8,6 @@
kill {0} processes
kill all instances
+ Put processes with visible windows on the top
+
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
index 662765760c9..14e228b2ad4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
@@ -34,8 +34,8 @@
Blendet Programme mit gängigen Uninstaller-Namen aus, wie unins000.exe
In Programmbeschreibung suchen
Flow wird in Programmbeschreibung suchen
- Hide duplicated apps
- Hide duplicated Win32 programs that are already in the UWP list
+ Duplizierte Apps ausblenden
+ Duplizierte Win32-Programme ausblenden, die bereits in der UWP-Liste sind
Suffixe
Maximale Tiefe
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
index 0e8b2f1d599..af272fb4635 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
@@ -84,7 +84,7 @@
סייר מותאם אישית
ארגומנטים
- You can customize the explorer used for opening the container folder by inputing the Environmental Variable of the explorer you want to use. It will be useful to use CMD to test whether the Environmental Variable is available.
+ באפשרותך להתאים אישית את הסייר שבו נעשה שימוש לפתיחת תיקיית המכולה על ידי הזנת משתנה הסביבה של הסייר שברצונך להשתמש בו. כדאי לבדוק באמצעות CMD אם משתנה הסביבה זמין.
הזן את הארגומנטים שברצונך להוסיף לסייר המותאם אישית שלך. %s עבור ספריית האב, %f עבור הנתיב המלא (זמין רק עבור win32). בדוק באתר הסייר לפרטים נוספים.
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
index 77a3fed47f0..dcfc82e0a6e 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/de.xaml
@@ -6,7 +6,7 @@
Drücken Sie eine beliebige Taste, um dieses Fenster zu schließen ...
Eingabeaufforderung nach Befehlsausführung nicht schließen
Immer als Administrator ausführen
- Use Windows Terminal
+ Windows-Terminal verwenden
Als anderer Benutzer ausführen
Shell
Ermöglicht das Ausführen von Systembefehlen aus Flow Launcher
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
index 529be9f45e3..ccc50678e5a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ar.xaml
@@ -2,8 +2,9 @@
- أمر
+ اسم البرنامج
وصف
+ أمر
إيقاف التشغيل
إعادة التشغيل
@@ -27,6 +28,8 @@
تبديل وضع اللعبة
Set the Flow Launcher Theme
+ تعدي
+
إيقاف تشغيل الكمبيوتر
إعادة تشغيل الكمبيوتر
@@ -59,6 +62,15 @@
هل أنت متأكد أنك تريد إعادة تشغيل الكمبيوتر مع خيارات التمهيد المتقدمة؟
هل أنت متأكد أنك تريد تسجيل الخروج؟
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ إعادة تعيين
+ Confirm
+ إلغاء
+ Please enter a non-empty command keyword
+
أوامر النظام
يوفر أوامر متعلقة بالنظام، مثل إيقاف التشغيل، القفل، الإعدادات، وما إلى ذلك.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
index 1a42ce51bd0..de35c959232 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/cs.xaml
@@ -2,8 +2,9 @@
- Příkaz
+ Jméno
Popis
+ Příkaz
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Editovat
+
Vypnout počítač
Restartovat počítač
@@ -59,6 +62,15 @@
Opravdu chcete restartovat počítač s rozšířenými možnostmi spouštění?
Opravdu se chcete odhlásit?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Potvrdit
+ Zrušit
+ Please enter a non-empty command keyword
+
Systémové příkazy
Poskytuje příkazy související se systémem, jako je vypnutí, uzamčení počítače atd.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
index 172adfd2f9f..91230e7e3ee 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/da.xaml
@@ -2,8 +2,9 @@
- Command
+ Name
Description
+ Command
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Rediger
+
Shutdown Computer
Restart Computer
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Annuller
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
index cdd0e03488d..794e949ad71 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
@@ -2,8 +2,9 @@
- Befehl
+ Name
Beschreibung
+ Befehl
Herunterfahren
Neu starten
@@ -25,7 +26,9 @@
Flow Launcher-Tipps
Flow Launcher UserData-Ordner
Spielmodus umschalten
- Set the Flow Launcher Theme
+ Flow Launcher-Theme festlegen
+
+ Bearbeiten
Computer herunterfahren
@@ -48,7 +51,7 @@
Besuchen Sie die Dokumentation von Flow Launcher für mehr Hilfe und Tipps zur Verwendung
Den Ort öffnen, an dem die Einstellungen von Flow Launcher gespeichert sind
Spielmodus umschalten
- Quickly change the Flow Launcher theme
+ Das Flow-Launcher-Theme schnell ändern
Erfolg
@@ -56,9 +59,18 @@
Alle anwendbaren Plug-in-Daten neu geladen
Sind Sie sicher, dass Sie den Computer herunterfahren wollen?
Sind Sie sicher, dass Sie den Computer neu starten wollen?
- Soll der Computer wirklich mit erweiterten Startoptionen neu gestartet werden?
+ Sind Sie sicher, dass Sie den Computer mit erweiterten Boot-Optionen neu starten wollen?
Sind Sie sicher, dass Sie sich ausloggen wollen?
+ Befehls-Schlüsselwort-Einstellung
+ Benutzerdefiniertes Befehls-Schlüsselwort
+ Geben Sie ein Schlüsselwort ein, um nach dem Befehl zu suchen: {0}. Dieses Schlüsselwort wird verwendet, um Ihre Anfrage abzugleichen.
+ Befehls-Schlüsselwort
+ Zurücksetzen
+ Bestätigen
+ Abbrechen
+ Bitte geben Sie ein nicht-leeres Befehls-Schlüsselwort ein
+
Systembefehle
Bietet systembezogene Befehle, z. B. Herunterfahren, Sperren, Einstellungen etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
index 99eec60fa7d..ac4040dcad0 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es-419.xaml
@@ -2,8 +2,9 @@
- Command
+ Name
Description
+ Command
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Editar
+
Shutdown Computer
Restart Computer
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Cancelar
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
index 2139738f771..5f3688ab811 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/es.xaml
@@ -2,8 +2,9 @@
- Comando
+ Nombre
Descripción
+ Comando
Apagar
Reiniciar
@@ -27,6 +28,8 @@
Cambiar a Modo Juego
Establecer el tema de Flow Launcher
+ Editar
+
Apaga el equipo
Reinicia el equipo
@@ -59,6 +62,15 @@
¿Está seguro de que desea reiniciar el equipo con opciones de arranque avanzadas?
¿Está seguro de que desea cerrar la sesión?
+ Configuración de la palabra clave de comando
+ Palabra clave de comando personalizada
+ Introducir una palabra clave para buscar el comando: {0}. Esta palabra clave se utiliza para que coincida con la búsqueda.
+ Palabra clave de comando
+ Restablecer
+ Confirmar
+ Cancelar
+ Por favor, introducir una palabra clave de comando no vacía
+
Comandos del sistema
Proporciona comandos relacionados con el sistema. Por ejemplo, apagar, bloquear, configurar, etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
index 727a9a6adc1..5419bd8e2a9 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/fr.xaml
@@ -2,8 +2,9 @@
- Commande
+ Nom
Description
+ Commande
Arrêter
Redémarrer
@@ -27,6 +28,8 @@
Basculer le mode de jeu
Définir le thème Flow Launcher
+ Modifier
+
Éteindre l'ordinateur
Redémarrer l'ordinateur
@@ -59,6 +62,15 @@
Êtes-vous sûr de vouloir redémarrer l'ordinateur avec les options de démarrage avancées ?
Êtes-vous sûr de vouloir vous déconnecter ?
+ Réglage du mot-clé de commande
+ Mot-clé de commande personnalisé
+ Entrez un mot-clé pour rechercher la commande : {0}. Ce mot-clé est utilisé pour répondre à votre requête.
+ Mot-clé de commande
+ Réinitialiser
+ Confirmer
+ Annuler
+ Veuillez saisir un mot-clé de commande non vide
+
Commandes système
Fournit des commandes liées au système. Par exemple, arrêt, verrouillage, paramètres, etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
index acc3f3b59e4..86688a130f8 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
@@ -2,8 +2,9 @@
- פקודה
+ שם
תיאור
+ פקודה
כיבוי
הפעלה מחדש
@@ -27,6 +28,8 @@
מצב משחק
Set the Flow Launcher Theme
+ ערו
+
כבה את המחשב
הפעל מחדש את המחשב
@@ -59,6 +62,15 @@
האם אתה בטוח שברצונך להפעיל מחדש את המחשב עם אפשרויות אתחול מתקדמות?
האם אתה בטוח שברצונך להתנתק?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ אפס
+ אישו
+ ביטול
+ Please enter a non-empty command keyword
+
פקודות מערכת
מספק פקודות הקשורות למערכת, כגון כיבוי, נעילה, הגדרות ועוד.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
index b464cab2890..be31e4e5210 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/it.xaml
@@ -2,8 +2,9 @@
- Comando
+ Nome
Descrizione
+ Comando
Spegni
Riavvia
@@ -27,6 +28,8 @@
Attiva/Disattiva Modalità Di Gioco
Set the Flow Launcher Theme
+ Modifica
+
Spegni il computer
Riavvia il Computer
@@ -59,6 +62,15 @@
Sei sicuro di voler riavviare il computer con le Opzioni di Avvio Avanzate?
Sei sicuro di volerti disconettere?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Resetta
+ Conferma
+ Annulla
+ Please enter a non-empty command keyword
+
Comandi di Sistema
Fornisce comandi relativi al sistema, ad esempio spegnimento, blocco, impostazioni ecc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
index cff426d4e02..bc7dff59f4a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
@@ -2,8 +2,9 @@
- コマンド
+ Name
説明
+ コマンド
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ 編
+
コンピュータをシャットダウンする
コンピュータを再起動する
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+
+ Please enter a non-empty command keyword
+
システムコマンド
システム関連のコマンドを提供します。例:シャットダウン、ロック、設定など
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
index d9b568e14f6..f2049038faa 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
@@ -2,8 +2,9 @@
- 명령어
+ Name
설명
+ 명령어
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ 편집
+
시스템 종료
시스템 재시작
@@ -59,6 +62,15 @@
고급 부팅 옵션으로 시스템을 다시 시작하시겠습니까?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ 확인
+ 취소
+ Please enter a non-empty command keyword
+
시스템 명령어
시스템 종료, 컴퓨터 잠금, 설정 등과 같은 시스템 관련 명령어를 제공합니다
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
index a531189fee1..072fd623d44 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nb.xaml
@@ -2,8 +2,9 @@
- Kommando
+ Navn
Beskrivelse
+ Kommando
Slå av
Start på nytt
@@ -27,6 +28,8 @@
Vis/Skjul spillmodus
Set the Flow Launcher Theme
+ Rediger
+
Slår av datamaskin
Start datamaskinen på nytt
@@ -59,6 +62,15 @@
Er du sikker på at du vil starte datamaskinen på nytt med avanserte oppstartsalternativer?
Er du sikker på at du vil logge av?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Tilbakestill
+ Bekreft
+ Avbryt
+ Please enter a non-empty command keyword
+
Systemkommandoer
Gir systemrelaterte kommandoer, f.eks. slå av, lås, innstillinger osv.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
index e0e4d46a83c..9d1d540763e 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/nl.xaml
@@ -2,8 +2,9 @@
- Opdracht
+ Name
Beschrijving
+ Opdracht
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Bewerken
+
Computer afsluiten
Computer opnieuw opstarten
@@ -59,6 +62,15 @@
Weet u zeker dat u de computer wilt herstarten met geavanceerde opstartopties?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Herstellen
+ Confirm
+ Annuleer
+ Please enter a non-empty command keyword
+
Systeemopdrachten
Voorziet in systeem gerelateerde opdrachten. bijv.: afsluiten, vergrendelen, instellingen, enz.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
index bbb3bec8820..c09a447d29c 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pl.xaml
@@ -2,8 +2,9 @@
- Komenda
+ Nazwa
Opis
+ Komenda
Wyłącz komputer
Restart
@@ -27,6 +28,8 @@
Przełącz tryb gry
Set the Flow Launcher Theme
+ Edytuj
+
Wyłącz komputer
Uruchom ponownie komputer
@@ -59,6 +62,15 @@
Czy na pewno chcesz ponownie uruchomić komputer z Zaawansowanymi opcjami rozruchu?
Czy na pewno chcesz się wylogować?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Zresetuj
+ Potwierdź
+ Anuluj
+ Please enter a non-empty command keyword
+
Komendy systemowe
Wykonywanie komend systemowych, np. wyłącz, zablokuj komputer, otwórz ustawienia itp.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
index b356f6bc791..a19ab39d630 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-br.xaml
@@ -2,8 +2,9 @@
- Comando
+ Nome
Descrição
+ Comando
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Editar
+
Desligar o Computador
Reiniciar o Computador
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Cancelar
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
index aa7217c01b7..9e0e3906650 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/pt-pt.xaml
@@ -2,8 +2,9 @@
- Comando
+ Nome
Descrição
+ Comando
Desligar
Reiniciar
@@ -25,7 +26,9 @@
Dicas Flow Launcher
Pasta de dados do utilizador Flow Launcher
Comutar modo de jogo
- Set the Flow Launcher Theme
+ Definir tema Flow Launcher
+
+ Editar
Desligar computador
@@ -48,7 +51,7 @@
Aceda à documentação para mais informações e dicas de utilização
Abrir localização onde as definições do Flow Launcher estão guardadas
Comutar modo de jogo
- Quickly change the Flow Launcher theme
+ Alterar rapidamente o tema da aplicação
Sucesso
@@ -59,6 +62,15 @@
Tem certeza de que deseja reiniciar o computador com as opções avançadas de arranque?
Tem certeza de que deseja terminar a sessão?
+ Definição de palavra-chave
+ Palavra-chave personalizada
+ Indique a palavra-chave para pesquisar o comando: {0}. A aplavra-chave será usada para correspondência com a consulta.
+ Palavra-chave
+ Repor
+ Confirmar
+ Cancelar
+ Não pode indicar uma palavra-chave vazia
+
Comandos do sistema
Disponibiliza os comandos relacionados com o sistema tais como: desligar, bloquear, reiniciar...
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
index 4547274f891..796cda69d62 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ru.xaml
@@ -2,8 +2,9 @@
- Command
+ Name
Description
+ Command
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Редактировать
+
Shutdown Computer
Restart Computer
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Отменить
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
index 0f88942889f..087ff9f0593 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sk.xaml
@@ -2,8 +2,9 @@
- Príkaz
+ Názov
Popis
+ Príkaz
Vypnúť
Reštartovať
@@ -27,6 +28,8 @@
Prepnúť herný režim
Nastaviť motív pre Flow Laucher
+ Upraviť
+
Vypnúť počítač
Reštartovať počítač
@@ -59,6 +62,15 @@
Naozaj chcete počítač reštartovať s pokročilými možnosťami spúšťania?
Naozaj sa chcete odhlásiť?
+ Nastavenia kľúčového slova príkazu
+ Vlastné kľúčové slovo príkazu
+ Na vyhľadanie príkazu zadajte kľúčové slovo: {0}. Toto kľúčové slovo sa použije na vyhľadnie príkazu.
+ Kľúčové slovo príkazu
+ Resetovať
+ Potvrdiť
+ Zrušiť
+ Prosím, zadajte neprázdne kľúčové slovo príkazu
+
Systémové príkazy
Poskytuje príkazy súvisiace so systémom ako je vypnutie, uzamknutie počítača atď.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
index d04a783d099..f5a2f1b306e 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/sr.xaml
@@ -2,8 +2,9 @@
- Command
+ Name
Description
+ Command
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Izmeni
+
Shutdown Computer
Restart Computer
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ Confirm
+ Otkaži
+ Please enter a non-empty command keyword
+
System Commands
Provides System related commands. e.g. shutdown, lock, settings etc.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
index 93973913f9e..18f7f63f5bb 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/tr.xaml
@@ -2,8 +2,9 @@
- Komut
+ Name
Açıklama
+ Komut
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Düzenle
+
Bilgisayarı Kapat
Yeniden Başlat
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Sıfırla
+ Onayla
+ İptal
+ Please enter a non-empty command keyword
+
Sistem Komutları
Sistem ile ilgili komutlara erişim sağlar. ör. shutdown, lock, settings vb.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
index 57c83e1a5f9..19d69511b10 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/uk-UA.xaml
@@ -2,8 +2,9 @@
- Команда
+ Назва
Опис
+ Команда
Вимкнути
Перезавантажити
@@ -27,6 +28,8 @@
Перемкнути режим гри
Set the Flow Launcher Theme
+ Редагувати
+
Вимкнути комп'ютер
Перезавантажити комп'ютер
@@ -59,6 +62,15 @@
Ви впевнені, що хочете перезавантажити комп'ютер за допомогою додаткових параметрів завантаження?
Ви впевнені, що хочете вийти з системи?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Скинути
+ Підтвердити
+ Скасувати
+ Please enter a non-empty command keyword
+
Системні команди
Надає команди, пов'язані з системою, наприклад, вимкнення, блокування, налаштування тощо.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/vi.xaml
index 8d0bc43c02e..dae12c501eb 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/vi.xaml
@@ -2,8 +2,9 @@
- Lệnh
+ Tên
Mô Tả
+ Lệnh
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ Sửa
+
shutdown máy tính
Khởi động lại máy tính
@@ -59,6 +62,15 @@
Bạn có chắc chắn muốn khởi động lại máy tính bằng Advanced Boot Options không?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Đặt lại
+ Xác nhận
+ Hủy
+ Please enter a non-empty command keyword
+
Lệnh hệ thống
Cung cấp các lệnh liên quan đến Hệ thống. ví dụ. tắt máy, khóa, cài đặt, v.v.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
index e08f312b195..74512913034 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-cn.xaml
@@ -2,8 +2,9 @@
- 命令
+ 名称
描述
+ 命令
关机
重启
@@ -27,6 +28,8 @@
切换游戏模式
Set the Flow Launcher Theme
+ 编辑
+
关闭电脑
重启这台电脑
@@ -59,6 +62,15 @@
您确定要以高级启动选项重启吗?
您确定要注销吗?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ 重置
+ 确认
+ 取消
+ Please enter a non-empty command keyword
+
系统命令
提供操作系统相关的命令,如关机、锁定、设置等。
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
index d43496466d9..573aefcbd62 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/zh-tw.xaml
@@ -2,8 +2,9 @@
- 命令
+ 名稱
描述
+ 命令
Shutdown
Restart
@@ -27,6 +28,8 @@
Toggle Game Mode
Set the Flow Launcher Theme
+ 編輯
+
電腦關機
電腦重新啟動
@@ -59,6 +62,15 @@
Are you sure you want to restart the computer with Advanced Boot Options?
Are you sure you want to log off?
+ Command Keyword Setting
+ Custom Command Keyword
+ Enter a keyword to search for command: {0}. This keyword is used to match your query.
+ Command Keyword
+ Reset
+ 確認
+ 取消
+ Please enter a non-empty command keyword
+
系統命令
系統相關的命令。例如,關機,鎖定,設定等
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
index 6e92178db97..cefb5d1d1a8 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ar.xaml
@@ -17,7 +17,7 @@
كلمة مفتاحية للعمل
الرابط
بحث
- استخدام الإكمال التلقائي لاستعلام البحث:
+ Use Search Query Autocomplete
بيانات الإكمال التلقائي من:
يرجى اختيار بحث على الويب
هل أنت متأكد أنك تريد حذف {0}؟
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
index 849f27f0522..ca98581c39b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/cs.xaml
@@ -17,7 +17,7 @@
Aktivační příkaz
URL
Hledat
- Používejte automatické dokončování vyhledávaných výrazů:
+ Use Search Query Autocomplete
Automatické doplnění údajů z:
Vyberte webové vyhledávání
Opravdu chcete odstranit {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
index 2a7d4aa328b..b1113acb79a 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/da.xaml
@@ -17,7 +17,7 @@
Action Keyword
URL
Search
- Use Search Query Autocomplete:
+ Use Search Query Autocomplete
Autocomplete Data from:
Please select a web search
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
index 0c72b11bf99..2a7dca59652 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/de.xaml
@@ -17,8 +17,8 @@
Aktions-Schlüsselwort
URL
Suche
- Autovervollständigung von Suchanfragen verwenden:
- Daten automatisch vervollständigen aus:
+ Autovervollständigung von Suchanfragen verwenden
+ Autovervollständigung der Daten aus:
Bitte wählen Sie eine Websuche aus
Sind Sie sicher, dass Sie {0} löschen wollen?
Wenn Sie Flow eine Suche nach einer bestimmten Website hinzufügen möchten, geben Sie zunächst eine Dummy-Textzeichenfolge in die Suchleiste dieser Website ein und starten Sie die Suche. Kopieren Sie jetzt den Inhalt der Adressleiste des Browsers und fügen Sie ihn in das URL-Feld unten ein. Ersetzen Sie Ihre Testzeichenfolge durch {q}. Zum Beispiel, wenn Sie auf Netflix nach casino suchen, steht in der Adressleiste
@@ -30,8 +30,8 @@
https://www.netflix.com/search?q={q}
- Copy URL
- Copy search URL to clipboard
+ URL kopieren
+ Such-URL in Zwischenablage kopieren
Titel
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
index 517ac0918e2..3ce22bb7809 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es-419.xaml
@@ -17,7 +17,7 @@
Palabra clave
URL
Buscar
- Autocompletar la búsqueda:
+ Use Search Query Autocomplete
Autocompletar datos de:
Por favor, seleccione una búsqueda
¿Seguro que desea eliminar {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
index e6e4a94d2cb..7f14b59c6b3 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/es.xaml
@@ -17,7 +17,7 @@
Palabra clave de acción
URL
Busca en
- Usar autocompletado en consultas de búsqueda:
+ Usar autocompletado en consultas de búsqueda
Autocompletar datos desde:
Por favor, seleccione una búsqueda web
¿Está seguro de que desea eliminar {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
index c6b1b145cdf..f04cfb48afb 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/fr.xaml
@@ -17,7 +17,7 @@
Mot-clé d'action
URL
Rechercher sur
- Utiliser la saisie automatique de la requête de recherche :
+ Utiliser la fonction d'auto-complétion des requêtes de recherche
Saisir automatiquement les données à partir de :
Veuillez sélectionner une recherche web
Êtes-vous sûr de vouloir supprimer {0} ?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
index 630287983a7..78ee7ca7db1 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/he.xaml
@@ -17,7 +17,7 @@
מילת מפתח לפעולה
כתובת URL
חיפו
- השתמש בהשלמה אוטומטית לשאילתות חיפוש:
+ השתמש בהשלמה אוטומטית לשאילתת חיפוש
השלמה אוטומטית מתוך:
בחר שירות חיפוש אינטרנטי
האם אתה בטוח שברצונך למחוק את {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
index 26c1e845945..db2a4dfeb56 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/it.xaml
@@ -17,7 +17,7 @@
Parola Chiave
URL
Cerca
- Usa Autocompletamento Ricerca:
+ Use Search Query Autocomplete
Autocompleta i dati da:
Seleziona una ricerca web
Sei sicuro di voler eliminare {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
index 85ce0e28232..9ae62885333 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
@@ -17,7 +17,7 @@
キーワード
URL
検索
- 検索サジェスチョンを有効にする
+ Use Search Query Autocomplete
Autocomplete Data from:
web検索を選択してください
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
index 5ab5fffa3d9..3ac9f6a6c72 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
@@ -17,7 +17,7 @@
액션 키워드
URL
검색
- 검색 쿼리 자동완성 사용:
+ Use Search Query Autocomplete
자동완성 데이터 출처:
웹 검색을 선택하세요
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
index 4bba382a9b6..9f793c43fd2 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nb.xaml
@@ -17,7 +17,7 @@
Nøkkelord for handling
Nettadresse
Søk
- Bruk autofullføring av søkespørring:
+ Use Search Query Autocomplete
Autofullfør data fra:
Vennligst velg et websøk
Er du sikker på at du ønsker å slette {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
index a48d9948715..a18710324d6 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/nl.xaml
@@ -17,7 +17,7 @@
Action Keyword
URL
Search
- Use Search Query Autocomplete:
+ Use Search Query Autocomplete
Autocomplete Data from:
Please select a web search
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
index 499351343b0..d693a3f28d2 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pl.xaml
@@ -17,7 +17,7 @@
Wyzwalacz
Adres URL
Szukaj
- Pokazuj podpowiedzi wyszukiwania
+ Use Search Query Autocomplete
Autouzupełnianie danych z:
Musisz wybrać coś z listy
Czy jesteś pewien że chcesz usunąć {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
index d4135c79529..6f0d7fcc961 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-br.xaml
@@ -17,7 +17,7 @@
Action Keyword
URL
Search
- Use Search Query Autocomplete:
+ Use Search Query Autocomplete
Autocomplete Data from:
Please select a web search
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
index 16969dac70d..1a2476a2c5f 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/pt-pt.xaml
@@ -17,7 +17,7 @@
Palavra-chave de ação
URL
Pesquisar
- Utilizar conclusão automática da consulta:
+ Utilizar conclusão automática para as consultas
Preencher dados a partir de:
Selecione uma pesquisa web
Tem a certeza de que deseja eliminar {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
index c591822906b..1fd9aca96a9 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ru.xaml
@@ -1,4 +1,4 @@
-
+
Search Source Setting
@@ -17,7 +17,7 @@
Action Keyword
URL
Search
- Use Search Query Autocomplete:
+ Use Search Query Autocomplete
Autocomplete Data from:
Please select a web search
Are you sure you want to delete {0}?
@@ -28,8 +28,9 @@
Then replace casino with {q}.
Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
- Скопировать URL-адрес
- Скопировать URL поиска в буфер обмена
+
+ Copy URL
+ Copy search URL to clipboard
Title
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
index 44b765c58cb..1afcdb3600d 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sk.xaml
@@ -17,7 +17,7 @@
Aktivačný príkaz
Adresa URL
Hľadať
- Použiť automatické dokončovanie výrazov vyhľadávania:
+ Použiť automatické dokončovanie výrazov vyhľadávania
Automatické dokončovanie údajov z:
Vyberte webové vyhľadávanie
Naozaj chcete odstrániť {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
index 5f180365581..06707b4af17 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/sr.xaml
@@ -17,7 +17,7 @@
Action Keyword
URL
Search
- Use Search Query Autocomplete:
+ Use Search Query Autocomplete
Autocomplete Data from:
Please select a web search
Are you sure you want to delete {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
index 1506b753bae..aaad035a071 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/tr.xaml
@@ -17,7 +17,7 @@
Anahtar Kelime
URL
Ara:
- Arama önerilerini etkinleştir
+ Use Search Query Autocomplete
Autocomplete Data from:
Lütfen bir web araması seçin
{0} bağlantısını silmek istediğinize emin misiniz?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
index beb085d28ba..5536a7e680e 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/uk-UA.xaml
@@ -17,7 +17,7 @@
Ключове слово дії
URL
Пошук
- Використовувати автозаповнення пошукового запиту:
+ Use Search Query Autocomplete
Автозаповнення даних з:
Будь ласка, виберіть пошуковий запит в Інтернеті
Ви впевнені, що хочете видалити {0}?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
index e3105283fad..731275c5ef3 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/vi.xaml
@@ -17,7 +17,7 @@
Từ khóa hành động
Địa chỉ URL
Tìm kiếm
- Sử dụng Tự động hoàn thành truy vấn tìm kiếm:
+ Use Search Query Autocomplete
Tự động hoàn thành dữ liệu từ:
Vui lòng chọn tìm kiếm trên web
Bạn có chắc chắn muốn xóa {0} không?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
index d3df223cc71..375a741d0dd 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-cn.xaml
@@ -17,7 +17,7 @@
触发关键字
打开链接
搜索
- 启用搜索建议
+ Use Search Query Autocomplete
自动补全数据:
请选择一项
您确定要删除 {0} 吗?
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
index eb58a4ec0ab..727b2f4a99a 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/zh-tw.xaml
@@ -17,7 +17,7 @@
觸發關鍵字
網址
搜尋
- 啟用搜尋建議
+ Use Search Query Autocomplete
從以下位置自動填入資料:
請選擇一項
你確認要刪除{0}嗎
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
index dcc74d52031..5f8d9a6dfbc 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.de-DE.resx
@@ -275,7 +275,7 @@
Hardware und Sound
- Startseite
+ Homepage
Mixed Reality
@@ -2161,7 +2161,7 @@
Erweiterte Druckereinrichtung
- Change default printer
+ Standard-Drucker ändern
Edit environment variables for your account
@@ -2416,7 +2416,7 @@
Erweiterte Sharing-Einstellungen verwalten
- Change battery settings
+ Akku-Einstellungen ändern
Diesen Computer umbenennen
@@ -2479,7 +2479,7 @@
Find and fix bluescreen problems
- Hear a tone when keys are pressed
+ Einen Ton hören, wenn Tasten gedrückt werden
Browsing-Historie löschen
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
index 55ac42dd347..faa8c2dcc86 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
@@ -432,7 +432,7 @@
Area Personalization
- Client service for NetWare
+ שירות לקוח עבור NetWare
Area Control Panel (legacy settings)
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ko-KR.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ko-KR.resx
index c7c1854b7a9..ab69a2a314d 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ko-KR.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.ko-KR.resx
@@ -1203,7 +1203,7 @@
Area Gaming
- Windows 설정을 검색하는 플러그 인
+ Windows 설정을 검색하는 플러그인
Windows Settings
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
index e7f8e1683e4..39062bbb860 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.pt-PT.resx
@@ -1797,13 +1797,13 @@
Mostrar ficheiros e pastas ocultas
- Change Windows To Go start-up options
+ Mudar as configurações de início do Windows Portátil
- See which processes start up automatically when you start Windows
+ Veja quais processos se iniciam automaticamente quando o Windows inicia
- Tell if an RSS feed is available on a website
+ Informar se um feed RSS está disponível em um site
Adicionar relógios para diferentes fusos horários
@@ -1815,7 +1815,7 @@
Personalizar botões do rato
- Set tablet buttons to perform certain tasks
+ Definir botões do tablet para executar certas tarefas
Ver tipos de letra instalados
@@ -1869,13 +1869,13 @@
Ver digitalizadores e câmaras
- Microsoft IME Register Word (Japanese)
+ Registro do Word Microsoft IME (japonês)
Restaurar ficheiros com o Histórico de ficheiros
- Turn On-Screen keyboard on or off
+ Ativar ou desativar o teclado na tela
Bloquear ou permitir cookies de terceiros
@@ -1887,7 +1887,7 @@
Criar uma unidade de recuperação
- Microsoft New Phonetic Settings
+ Configurações do Microsoft New Phonetic
Gerer relatório de saúde do sistema
@@ -1899,16 +1899,16 @@
Cópia de segurança e restauro (Windows 7)
- Preview, delete, show or hide fonts
+ Pré-visualizar, excluir, mostrar ou ocultar fontes
- Microsoft Quick Settings
+ Configurações Rápidas da Microsoft
Ver histórico de fiabilidade
- Access RemoteApp and desktops
+ Acessar o RemoteApp e desktops
Configurar fontes de dados ODBC
@@ -1926,7 +1926,7 @@
Opções SimpleFast do Microsoft Pinyin
- Change what closing the lid does
+ Mudar o que fechar a tampa faz
Desativar animações desnecessárias
@@ -1947,7 +1947,7 @@
Ver ações recomendadas para manter o sistema a funcionar nas melhores condições
- Alterar a frequência de piscar do cursor
+ Alterar frequência de intermitência do cursor
Adicionar ou remover programas
@@ -1959,13 +1959,13 @@
Configurar propriedades avançadas do perfil de utilizador
- Start or stop using AutoPlay for all media and devices
+ Inicie ou pare de usar o AutoPlay para todas as mídias e dispositivos
Alterar definições de manutenção automática
- Specify single- or double-click to open
+ Especificar se um clique ou dois são necessários para abrir
Utilizadores que podem utilizar o ambiente de trabalho remoto
@@ -1995,13 +1995,13 @@
Analisar estado do teclado
- Control the computer without the mouse or keyboard
+ Controle o computador sem o mouse ou teclado
Alterar ou remover um programa
- Change multi-touch gesture settings
+ Alterar configurações de gestos multi-toque
Configurar origens ODBC (64 bits)
@@ -2013,13 +2013,13 @@
Alterar página inicial
- Group similar windows on the taskbar
+ Agrupar janelas semelhantes na barra de tarefas
- Change Windows SideShow settings
+ Alterar configurações do Windows SideShow
- Use audio description for video
+ Usar descrição de áudio para vídeos
Alterar nome do grupo de trabalho
@@ -2028,13 +2028,13 @@
Encontrar e corrigir problemas de impressão
- Change when the computer sleeps
+ Mudar quando o computador dorme
Configurar uma rede privada (VPN)
- Accommodate learning abilities
+ Acomodar habilidades de aprendizagem
Configurar uma ligação telefónica
@@ -2046,7 +2046,7 @@
Como alterar a palavra-passe do Windows
- Tornar mais fácil ver o ponteiro do rato
+ Tornar mais fácil de ver o ponteiro do mouse
Configurar o iniciador iSCSI
@@ -2067,7 +2067,7 @@
Substituir sons por pistas visuais
- Change temporary Internet file settings
+ Alterar configurações de arquivo de Internet temporárias
Estabelecer ligação à Internet
@@ -2085,16 +2085,16 @@
Guardar cópias de segurança dos ficheiros no Histórico de Ficheiros
- View current accessibility settings
+ Ver configurações de acessibilidade atuais
- Change tablet pen settings
+ Alterar configurações da caneta
Alterar modo de funcionamento do rato
- Show how much RAM is on this computer
+ Mostrar quanta memória RAM este computador tem
Editar plano de energia
@@ -2115,7 +2115,7 @@
Ampliar partes do ecrão com o Magnificador
- Change the file type associated with a file extension
+ Alterar o tipo de arquivo associado a uma extensão de arquivo
Ver registo de eventos
@@ -2133,17 +2133,17 @@
Alterar definições de poupança de energia
- Optimise for blindness
+ Otimizar para cegueira
- Turn Windows features on or off
+ Ative ou desative os recursos do Windows
- Show which operating system your computer is running
+ Mostra qual sistema operacional o seu computador está executando
Ver serviços locais
@@ -2152,7 +2152,7 @@
Gerir pastas de trabalho
- Encrypt your offline files
+ Criptografe seus arquivos offline
Treinar o computador para reconhecer a sua voz
@@ -2173,43 +2173,43 @@
Alterar definições ddo clique do rato
- Change advanced colour management settings for displays, scanners and printers
+ Alterar configurações avançadas de gerenciamento de cores para telas, scanners e impressoras
- Let Windows suggest Ease of Access settings
+ Permitir que o Windows sugira Facilidade de Acesso
- Clear disk space by deleting unnecessary files
+ Limpar espaço em disco excluindo arquivos desnecessários
Ver dispositivos e impressoras
- Private Character Editor
+ Editor de Caracteres Privados
- Record steps to reproduce a problem
+ Registrar as etapas para reproduzir um problema
- Adjust the appearance and performance of Windows
+ Ajustar a aparência e o desempenho do Windows
- Settings for Microsoft IME (Japanese)
+ Configurações para o Microsoft IME (japonês)
- Invite someone to connect to your PC and help you, or offer to help someone else
+ Convide alguém para se conectar ao seu PC e ajudá-lo, ou ofereça para ajudar outra pessoa
- Run programs made for previous versions of Windows
+ Execute programas feitos para versões anteriores do Windows
- Choose the order of how your screen rotates
+ Escolha a ordem de como a tela gira
- Change how Windows searches
+ Alterar como o Windows pesquisa
- Set flicks to perform certain tasks
+ Defina gestos para realizar certas ações
Alterar tipo de conta
@@ -2221,64 +2221,64 @@
Alterar Configurações de Controlo da Conta do Utilizador
- Turn on easy access keys
+ Ativar teclas de acesso fácil
- Identify and repair network problems
+ Identificar e reparar problemas de rede
- Find and fix networking and connection problems
+ Encontrar e corrigir problemas de rede e conexão
- Play CDs or other media automatically
+ Reproduzir CDs ou outras mídias automaticamente
- View basic information about your computer
+ Ver informações básicas sobre seu computador
- Choose how you open links
+ Escolha como abrir os links
- Allow Remote Assistance invitations to be sent from this computer
+ Permitir que convites de assistência remota sejam enviados a partir deste computador
Gestor de tarefas
- Turn flicks on or off
+ Ativar ou desativar gestos
Adicionar um idioma
- View network status and tasks
+ Ver status de rede e tarefas
- Turn Magnifier on or off
+ Ativar ou desativar a lupa
- See the name of this computer
+ Ver o nome deste computador
Ver ligações de rede
- Perform recommended maintenance tasks automatically
+ Executar tarefas recomendadas de manutenção automaticamente
- Manage disk space used by your offline files
+ Gerir espaço de disco utilizado pelos ficheiros locais
- Turn High Contrast on or off
+ Ativar ou desativar modo de alto contraste
- Change the way time is displayed
+ Alterar modo de exibição da hora
- Change how web pages are displayed in tabs
+ Alterar modo de exibição das páginas web nos separadores
- Change the way dates and lists are displayed
+ Alterar modo de exibição das datas e das listas
Gerir dispositivos de áudio
@@ -2293,37 +2293,37 @@
Apagar cookies ou ficheiros temporários
- Specify which hand you write with
+ Especificar a mão com a qual escreve
- Change touch input settings
+ Alterar definições do painel de toque
- How to change the size of virtual memory
+ Como alterar tamanho da memória virtual
- Hear text read aloud with Narrator
+ Utilizar Narrador para ouvir os textos
- Set up USB game controllers
+ Configurar controladores de jogos USB
- Show which domain your computer is on
+ Mostrar o domínio ao qual o computador pertence
- View all problem reports
+ Ver todos os relatórios de erro
- 16-Bit Application Support
+ Suporte a aplicações 16-bit
- Set up dialling rules
+ Configurar regras de marcação
Ativar ou desativar cookies da sessão
- Give administrative rights to a domain user
+ Conceder direitos de administrador a um domínio
Choose when to turn off display
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.sk-SK.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.sk-SK.resx
index f47b9ada3df..5b4dea6a977 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.sk-SK.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.sk-SK.resx
@@ -118,7 +118,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- O aplikácii
+ O systéme
Area System
From 24d43ed84bc29edd373ea1a513f4ef740828cce5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:46:02 +0800
Subject: [PATCH 0911/1335] Use api functions in Program plugin
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index a50868b69dd..f03040d68b1 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,7 +6,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
@@ -14,7 +13,6 @@
using Flow.Launcher.Plugin.SharedCommands;
using Microsoft.Extensions.Caching.Memory;
using Path = System.IO.Path;
-using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher.Plugin.Program
{
@@ -32,6 +30,8 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
internal static PluginInitContext Context { get; private set; }
+ private static readonly string ClassName = nameof(Main);
+
private static readonly List emptyResults = new();
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
@@ -109,7 +109,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
}
catch (OperationCanceledException)
{
- Log.Debug("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
+ Context.API.LogDebug(ClassName, "Query operation cancelled");
return emptyResults;
}
finally
@@ -188,7 +188,7 @@ public async Task InitAsync(PluginInitContext context)
var _win32sCount = 0;
var _uwpsCount = 0;
- await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", async () =>
+ await Context.API.StopwatchLogInfoAsync(ClassName, "Preload programs cost", async () =>
{
var pluginCacheDirectory = Context.CurrentPluginMetadata.PluginCacheDirectoryPath;
FilesFolders.ValidateDirectory(pluginCacheDirectory);
@@ -253,8 +253,8 @@ static void MoveFile(string sourcePath, string destinationPath)
_uwpsCount = _uwps.Count;
_uwpsLock.Release();
});
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32sCount}>");
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwpsCount}>");
+ Context.API.LogInfo(ClassName, $"Number of preload win32 programs <{_win32sCount}>");
+ Context.API.LogInfo(ClassName, $"Number of preload uwps <{_uwpsCount}>");
var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
@@ -295,7 +295,7 @@ public static async Task IndexWin32ProgramsAsync()
}
catch (Exception e)
{
- Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Win32 programs", e);
+ Context.API.LogException(ClassName, "Failed to index Win32 programs", e);
}
finally
{
@@ -320,7 +320,7 @@ public static async Task IndexUwpProgramsAsync()
}
catch (Exception e)
{
- Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Uwp programs", e);
+ Context.API.LogException(ClassName, "Failed to index Uwp programs", e);
}
finally
{
@@ -332,12 +332,12 @@ public static async Task IndexProgramsAsync()
{
var win32Task = Task.Run(async () =>
{
- await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32ProgramsAsync);
+ await Context.API.StopwatchLogInfoAsync(ClassName, "Win32Program index cost", IndexWin32ProgramsAsync);
});
var uwpTask = Task.Run(async () =>
{
- await Stopwatch.NormalAsync("|Flow.Launcher.Plugin.Program.Main|UWPProgram index cost", IndexUwpProgramsAsync);
+ await Context.API.StopwatchLogInfoAsync(ClassName, "UWPProgram index cost", IndexUwpProgramsAsync);
});
await Task.WhenAll(win32Task, uwpTask).ConfigureAwait(false);
From 1af9d061f741735b015b880c754bfc5ef9226bb7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 8 Apr 2025 21:53:00 +0800
Subject: [PATCH 0912/1335] Use api functions in other places
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 6 ++++--
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 10 +++++++---
Flow.Launcher/App.xaml.cs | 7 ++++---
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 0ee268f5c56..4c85fb061e3 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -23,6 +23,8 @@ namespace Flow.Launcher.Core.Plugin
///
public static class PluginManager
{
+ private static readonly string ClassName = nameof(PluginManager);
+
private static IEnumerable _contextMenuPlugins;
public static List AllPlugins { get; private set; }
@@ -194,7 +196,7 @@ public static async Task InitializePluginsAsync()
{
try
{
- var milliseconds = await Stopwatch.DebugAsync($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>",
+ var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Init method time cost for <{pair.Metadata.Name}>",
() => pair.Plugin.InitAsync(new PluginInitContext(pair.Metadata, API)));
pair.Metadata.InitTime += milliseconds;
@@ -266,7 +268,7 @@ public static async Task> QueryForPluginAsync(PluginPair pair, Quer
try
{
- var milliseconds = await Stopwatch.DebugAsync($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}",
+ var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Cost for {metadata.Name}",
async () => results = await pair.Plugin.QueryAsync(query, token).ConfigureAwait(false));
token.ThrowIfCancellationRequested();
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 495a4c1ab5f..1010d9f083b 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -11,12 +11,17 @@
#pragma warning restore IDE0005
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher.Core.Plugin
{
public static class PluginsLoader
{
+ private static readonly string ClassName = nameof(PluginsLoader);
+
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
public static List Plugins(List metadatas, PluginsSettings settings)
{
var dotnetPlugins = DotNetPlugins(metadatas);
@@ -59,8 +64,7 @@ private static IEnumerable DotNetPlugins(List source
foreach (var metadata in metadatas)
{
- var milliseconds = Stopwatch.Debug(
- $"|PluginsLoader.DotNetPlugins|Constructor init cost for {metadata.Name}", () =>
+ var milliseconds = API.StopwatchLogDebug(ClassName, $"Constructor init cost for {metadata.Name}", () =>
{
Assembly assembly = null;
IAsyncPlugin plugin = null;
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 81938612c34..90fefe0a642 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -21,7 +21,6 @@
using Flow.Launcher.ViewModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher
{
@@ -35,6 +34,8 @@ public partial class App : IDisposable, ISingleInstanceApp
#region Private Fields
+ private static readonly string ClassName = nameof(App);
+
private static bool _disposed;
private MainWindow _mainWindow;
private readonly MainViewModel _mainVM;
@@ -136,7 +137,7 @@ public static void Main()
private async void OnStartup(object sender, StartupEventArgs e)
{
- await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
+ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
{
// Because new message box api uses MessageBoxEx window,
// if it is created and closed before main window is created, it will cause the application to exit.
@@ -313,7 +314,7 @@ protected virtual void Dispose(bool disposing)
_disposed = true;
}
- Stopwatch.Normal("|App.Dispose|Dispose cost", () =>
+ API.StopwatchLogInfo(ClassName, "Dispose cost", () =>
{
Log.Info("|App.Dispose|Begin Flow Launcher dispose ----------------------------------------------------");
From 47743e6362469684e432b790649b419b96d0d543 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 09:31:02 +0800
Subject: [PATCH 0913/1335] Set max result lower limit to 1
---
.../ViewModels/SettingsViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index d2b85e6877d..4073009249b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -524,7 +524,7 @@ public string ExcludedFileTypes
}
}
- public int MaxResultLowerLimit => 100;
+ public int MaxResultLowerLimit => 1;
public int MaxResultUpperLimit => 100000;
public int MaxResult
From 49dc657becdac6f23f66c3ee4060165ff5b9838e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:12:32 +0800
Subject: [PATCH 0914/1335] Fix build issue
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 5dec8b953e3..3eb74dd7442 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.BrowserBookmark.Commands;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.BrowserBookmark.Views;
@@ -10,6 +9,7 @@
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Threading;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.BrowserBookmark;
@@ -35,7 +35,7 @@ public void Init(PluginInitContext context)
_context.CurrentPluginMetadata.PluginCacheDirectoryPath,
"FaviconCache");
- Helper.ValidateDirectory(_faviconCacheDir);
+ FilesFolders.ValidateDirectory(_faviconCacheDir);
LoadBookmarksIfEnabled();
}
From 9c07989edf4f42766922317b639e710ec33d6e35 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:14:07 +0800
Subject: [PATCH 0915/1335] Improve code quality
---
.../ChromiumBookmarkLoader.cs | 4 +-
.../ContextMenu.cs | 21 +++-----
.../DirectoryInfo/DirectoryInfoSearch.cs | 7 ++-
.../Search/WindowsIndex/WindowsIndex.cs | 8 +--
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 13 ++---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 49 ++++++++++---------
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 7 +--
7 files changed, 51 insertions(+), 58 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 28287647259..27bcbd9a935 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -2,7 +2,6 @@
using System.IO;
using System.Text.Json;
using System;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
@@ -116,8 +115,7 @@ private static void EnumerateFolderBookmark(JsonElement folderElement, ICollecti
}
else
{
- Log.Error(
- $"ChromiumBookmarkLoader: EnumerateFolderBookmark: type property not found for {subElement.GetString()}");
+ Main._context.API.LogError(ClassName, $"type property not found for {subElement.GetString()}");
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index 3f3b7cb5846..f6de65e90dd 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -2,13 +2,12 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Threading.Tasks;
using System.Windows;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using System.Linq;
using Flow.Launcher.Plugin.Explorer.Helper;
using Flow.Launcher.Plugin.Explorer.ViewModels;
@@ -470,22 +469,16 @@ private Result CreateOpenWithMenu(SearchResult record)
private void LogException(string message, Exception e)
{
- Log.Exception($"|Flow.Launcher.Plugin.Folder.ContextMenu|{message}", e);
+ Context.API.LogException(nameof(Main), message, e);
}
- private bool CanRunAsDifferentUser(string path)
+ private static bool CanRunAsDifferentUser(string path)
{
- switch (Path.GetExtension(path))
+ return Path.GetExtension(path) switch
{
- case ".exe":
- case ".bat":
- case ".msi":
- return true;
-
- default:
- return false;
-
- }
+ ".exe" or ".bat" or ".msi" => true,
+ _ => false,
+ };
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
index 9fd495f4910..1a0d3bd15d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
@@ -1,10 +1,9 @@
-using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin.SharedCommands;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
+using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
{
@@ -76,7 +75,7 @@ private static IEnumerable DirectorySearch(EnumerationOptions enum
}
catch (Exception e)
{
- Log.Exception(nameof(DirectoryInfoSearch), "Error occurred while searching path", e);
+ Main.Context.API.LogException(nameof(DirectoryInfoSearch), "Error occurred while searching path", e);
throw;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
index 66230937cd3..2aeb421e003 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/WindowsIndex.cs
@@ -1,6 +1,4 @@
-using Flow.Launcher.Infrastructure.Logger;
-using Microsoft.Search.Interop;
-using System;
+using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
@@ -9,11 +7,13 @@
using System.Text.RegularExpressions;
using System.Threading;
using Flow.Launcher.Plugin.Explorer.Exceptions;
+using Microsoft.Search.Interop;
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
internal static class WindowsIndex
{
+ private static readonly string ClassName = nameof(WindowsIndex);
// Reserved keywords in oleDB
private static Regex _reservedPatternMatcher = new(@"^[`\@\@\#\#\*\^,\&\&\/\\\$\%_;\[\]]+$", RegexOptions.Compiled);
@@ -33,7 +33,7 @@ private static async IAsyncEnumerable ExecuteWindowsIndexSearchAsy
}
catch (OleDbException e)
{
- Log.Exception($"|WindowsIndex.ExecuteWindowsIndexSearchAsync|Failed to execute windows index search query: {indexQueryString}", e);
+ Main.Context.API.LogException(ClassName, $"Failed to execute windows index search query: {indexQueryString}", e);
yield break;
}
await using var dataReader = dataReaderAttempt;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index a50868b69dd..acfa0655ee6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -6,7 +6,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
@@ -20,6 +19,8 @@ namespace Flow.Launcher.Plugin.Program
{
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, IAsyncReloadable, IDisposable
{
+ private static readonly string ClassName = nameof(Main);
+
private const string Win32CacheName = "Win32";
private const string UwpCacheName = "UWP";
@@ -109,7 +110,7 @@ public async Task> QueryAsync(Query query, CancellationToken token)
}
catch (OperationCanceledException)
{
- Log.Debug("|Flow.Launcher.Plugin.Program.Main|Query operation cancelled");
+ Context.API.LogDebug(ClassName, "Query operation cancelled");
return emptyResults;
}
finally
@@ -253,8 +254,8 @@ static void MoveFile(string sourcePath, string destinationPath)
_uwpsCount = _uwps.Count;
_uwpsLock.Release();
});
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32sCount}>");
- Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwpsCount}>");
+ Context.API.LogInfo(ClassName, "Number of preload win32 programs <{_win32sCount}>");
+ Context.API.LogInfo(ClassName, "Number of preload uwps <{_uwpsCount}>");
var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
@@ -295,7 +296,7 @@ public static async Task IndexWin32ProgramsAsync()
}
catch (Exception e)
{
- Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Win32 programs", e);
+ Context.API.LogException(ClassName, "Failed to index Win32 programs", e);
}
finally
{
@@ -320,7 +321,7 @@ public static async Task IndexUwpProgramsAsync()
}
catch (Exception e)
{
- Log.Exception("|Flow.Launcher.Plugin.Program.Main|Failed to index Uwp programs", e);
+ Context.API.LogException(ClassName, "Failed to index Uwp programs", e);
}
finally
{
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 53479b81fc3..97ff6130413 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -8,7 +8,6 @@
using WindowsInput;
using WindowsInput.Native;
using Flow.Launcher.Infrastructure.Hotkey;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using Control = System.Windows.Controls.Control;
using Keys = System.Windows.Forms.Keys;
@@ -17,8 +16,11 @@ namespace Flow.Launcher.Plugin.Shell
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu
{
+ private static readonly string ClassName = nameof(Main);
+
+ internal PluginInitContext Context { get; private set; }
+
private const string Image = "Images/shell.png";
- private PluginInitContext context;
private bool _winRStroked;
private readonly KeyboardSimulator _keyboardSimulator = new KeyboardSimulator(new InputSimulator());
@@ -88,7 +90,7 @@ public List Query(Query query)
}
catch (Exception e)
{
- Log.Exception($"|Flow.Launcher.Plugin.Shell.Main.Query|Exception when query for <{query}>", e);
+ Context.API.LogException(ClassName, $"Exception when query for <{query}>", e);
}
return results;
}
@@ -102,14 +104,14 @@ private List GetHistoryCmds(string cmd, Result result)
{
if (m.Key == cmd)
{
- result.SubTitle = string.Format(context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value);
+ result.SubTitle = string.Format(Context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value);
return null;
}
var ret = new Result
{
Title = m.Key,
- SubTitle = string.Format(context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value),
+ SubTitle = string.Format(Context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value),
IcoPath = Image,
Action = c =>
{
@@ -139,7 +141,7 @@ private Result GetCurrentCmd(string cmd)
{
Title = cmd,
Score = 5000,
- SubTitle = context.API.GetTranslation("flowlauncher_plugin_cmd_execute_through_shell"),
+ SubTitle = Context.API.GetTranslation("flowlauncher_plugin_cmd_execute_through_shell"),
IcoPath = Image,
Action = c =>
{
@@ -164,7 +166,7 @@ private List ResultsFromHistory()
.Select(m => new Result
{
Title = m.Key,
- SubTitle = string.Format(context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value),
+ SubTitle = string.Format(Context.API.GetTranslation("flowlauncher_plugin_cmd_cmd_has_been_executed_times"), m.Value),
IcoPath = Image,
Action = c =>
{
@@ -211,7 +213,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
info.FileName = "cmd.exe";
}
- info.ArgumentList.Add($"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}");
+ info.ArgumentList.Add($"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}");
break;
}
@@ -234,7 +236,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
else
{
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
+ info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
}
break;
}
@@ -255,7 +257,7 @@ private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdmin
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
- info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
+ info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
break;
}
@@ -309,13 +311,13 @@ private void Execute(Func startProcess, ProcessStartI
{
var name = "Plugin: Shell";
var message = $"Command not found: {e.Message}";
- context.API.ShowMsg(name, message);
+ Context.API.ShowMsg(name, message);
}
catch (Win32Exception e)
{
var name = "Plugin: Shell";
var message = $"Error running the command: {e.Message}";
- context.API.ShowMsg(name, message);
+ Context.API.ShowMsg(name, message);
}
}
@@ -350,14 +352,14 @@ private bool ExistInPath(string filename)
public void Init(PluginInitContext context)
{
- this.context = context;
+ Context = context;
_settings = context.API.LoadSettingJsonStorage();
context.API.RegisterGlobalKeyboardCallback(API_GlobalKeyboardEvent);
}
bool API_GlobalKeyboardEvent(int keyevent, int vkcode, SpecialKeyState state)
{
- if (!context.CurrentPluginMetadata.Disabled && _settings.ReplaceWinR)
+ if (!Context.CurrentPluginMetadata.Disabled && _settings.ReplaceWinR)
{
if (keyevent == (int)KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed)
{
@@ -380,10 +382,9 @@ private void OnWinRPressed()
// show the main window and set focus to the query box
_ = Task.Run(() =>
{
- context.API.ShowMainWindow();
- context.API.ChangeQuery($"{context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
+ Context.API.ShowMainWindow();
+ Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
});
-
}
public Control CreateSettingPanel()
@@ -393,12 +394,12 @@ public Control CreateSettingPanel()
public string GetTranslatedPluginTitle()
{
- return context.API.GetTranslation("flowlauncher_plugin_cmd_plugin_name");
+ return Context.API.GetTranslation("flowlauncher_plugin_cmd_plugin_name");
}
public string GetTranslatedPluginDescription()
{
- return context.API.GetTranslation("flowlauncher_plugin_cmd_plugin_description");
+ return Context.API.GetTranslation("flowlauncher_plugin_cmd_plugin_description");
}
public List LoadContextMenus(Result selectedResult)
@@ -407,8 +408,8 @@ public List LoadContextMenus(Result selectedResult)
{
new()
{
- Title = context.API.GetTranslation("flowlauncher_plugin_cmd_run_as_different_user"),
- AsyncAction = async c =>
+ Title = Context.API.GetTranslation("flowlauncher_plugin_cmd_run_as_different_user"),
+ Action = c =>
{
Execute(ShellCommand.RunAsDifferentUser, PrepareProcessStartInfo(selectedResult.Title));
return true;
@@ -418,7 +419,7 @@ public List LoadContextMenus(Result selectedResult)
},
new()
{
- Title = context.API.GetTranslation("flowlauncher_plugin_cmd_run_as_administrator"),
+ Title = Context.API.GetTranslation("flowlauncher_plugin_cmd_run_as_administrator"),
Action = c =>
{
Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, true));
@@ -429,10 +430,10 @@ public List LoadContextMenus(Result selectedResult)
},
new()
{
- Title = context.API.GetTranslation("flowlauncher_plugin_cmd_copy"),
+ Title = Context.API.GetTranslation("flowlauncher_plugin_cmd_copy"),
Action = c =>
{
- context.API.CopyToClipboard(selectedResult.Title);
+ Context.API.CopyToClipboard(selectedResult.Title);
return true;
},
IcoPath = "Images/copy.png",
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 94a9d0348ff..043eb7a190a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -6,7 +6,6 @@
using System.Runtime.InteropServices;
using System.Windows;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Windows.Win32;
using Windows.Win32.Foundation;
@@ -19,6 +18,8 @@ namespace Flow.Launcher.Plugin.Sys
{
public class Main : IPlugin, ISettingProvider, IPluginI18n
{
+ private static readonly string ClassName = nameof(Main);
+
private readonly Dictionary KeywordTitleMappings = new()
{
{"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
@@ -106,7 +107,7 @@ private string GetTitle(string key)
{
if (!KeywordTitleMappings.TryGetValue(key, out var translationKey))
{
- Log.Error("Flow.Launcher.Plugin.Sys.Main", $"Title not found for: {key}");
+ _context.API.LogError(ClassName, $"Title not found for: {key}");
return "Title Not Found";
}
@@ -117,7 +118,7 @@ private string GetDescription(string key)
{
if (!KeywordDescriptionMappings.TryGetValue(key, out var translationKey))
{
- Log.Error("Flow.Launcher.Plugin.Sys.Main", $"Description not found for: {key}");
+ _context.API.LogError(ClassName, $"Description not found for: {key}");
return "Description Not Found";
}
From 4e1d4ab7afcddeaa39f0b1aeca0639e401a5e933 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:18:44 +0800
Subject: [PATCH 0916/1335] Remove unused project reference
---
.../Flow.Launcher.Plugin.WebSearch.csproj | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj
index c2d0a46a094..73726ab37ab 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj
@@ -51,7 +51,6 @@
-
From 1aeaaf2fc24d32d67d994f84b2e84b555fb8c367 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:30:50 +0800
Subject: [PATCH 0917/1335] Add keyevent in Plugin project & Improve Shell
plugin code quality
---
Flow.Launcher.Infrastructure/NativeMethods.txt | 5 -----
.../Hotkey => Flow.Launcher.Plugin}/KeyEvent.cs | 7 ++++++-
Flow.Launcher.Plugin/NativeMethods.txt | 7 ++++++-
.../Flow.Launcher.Plugin.Shell.csproj | 1 -
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 7 +++----
5 files changed, 15 insertions(+), 12 deletions(-)
rename {Flow.Launcher.Infrastructure/Hotkey => Flow.Launcher.Plugin}/KeyEvent.cs (61%)
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index 363ecb9d002..18b20602213 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -11,11 +11,6 @@ GetModuleHandle
GetKeyState
VIRTUAL_KEY
-WM_KEYDOWN
-WM_KEYUP
-WM_SYSKEYDOWN
-WM_SYSKEYUP
-
EnumWindows
DwmSetWindowAttribute
diff --git a/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs b/Flow.Launcher.Plugin/KeyEvent.cs
similarity index 61%
rename from Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs
rename to Flow.Launcher.Plugin/KeyEvent.cs
index 95bb258377b..321f17cc18e 100644
--- a/Flow.Launcher.Infrastructure/Hotkey/KeyEvent.cs
+++ b/Flow.Launcher.Plugin/KeyEvent.cs
@@ -1,7 +1,12 @@
using Windows.Win32;
-namespace Flow.Launcher.Infrastructure.Hotkey
+namespace Flow.Launcher.Plugin
{
+ ///
+ /// Enumeration of key events for
+ ///
+ /// and
+ ///
public enum KeyEvent
{
///
diff --git a/Flow.Launcher.Plugin/NativeMethods.txt b/Flow.Launcher.Plugin/NativeMethods.txt
index e3e2b705eb0..0596691cc7f 100644
--- a/Flow.Launcher.Plugin/NativeMethods.txt
+++ b/Flow.Launcher.Plugin/NativeMethods.txt
@@ -1,3 +1,8 @@
EnumThreadWindows
GetWindowText
-GetWindowTextLength
\ No newline at end of file
+GetWindowTextLength
+
+WM_KEYDOWN
+WM_KEYUP
+WM_SYSKEYDOWN
+WM_SYSKEYUP
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj b/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj
index 8f443214bba..c7ea7cdd550 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj
@@ -37,7 +37,6 @@
-
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 97ff6130413..b149884d7d4 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -7,7 +7,6 @@
using System.Threading.Tasks;
using WindowsInput;
using WindowsInput.Native;
-using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Plugin.SharedCommands;
using Control = System.Windows.Controls.Control;
using Keys = System.Windows.Forms.Keys;
@@ -22,7 +21,7 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu
private const string Image = "Images/shell.png";
private bool _winRStroked;
- private readonly KeyboardSimulator _keyboardSimulator = new KeyboardSimulator(new InputSimulator());
+ private readonly KeyboardSimulator _keyboardSimulator = new(new InputSimulator());
private Settings _settings;
@@ -55,7 +54,7 @@ public List Query(Query query)
{
basedir = Path.GetDirectoryName(excmd);
var dirName = Path.GetDirectoryName(cmd);
- dir = (dirName.EndsWith("/") || dirName.EndsWith(@"\")) ? dirName : cmd.Substring(0, dirName.Length + 1);
+ dir = (dirName.EndsWith("/") || dirName.EndsWith(@"\")) ? dirName : cmd[..(dirName.Length + 1)];
}
if (basedir != null)
@@ -321,7 +320,7 @@ private void Execute(Func startProcess, ProcessStartI
}
}
- private bool ExistInPath(string filename)
+ private static bool ExistInPath(string filename)
{
if (File.Exists(filename))
{
From c035b65517befa0b3df89560f51a6447781b1937 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:31:53 +0800
Subject: [PATCH 0918/1335] Fix code documents issue
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 273676bfbd6..ff0f1ba4a26 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -372,6 +372,7 @@ public interface IPublicAPI
///
public bool SetCurrentTheme(ThemeData theme);
+ ///
/// Save all Flow's plugins caches
///
void SavePluginCaches();
@@ -404,6 +405,7 @@ public interface IPublicAPI
///
Task SaveCacheBinaryStorageAsync(string cacheName, string cacheDirectory) where T : new();
+ ///
/// Load image from path. Support local, remote and data:image url.
/// If image path is missing, it will return a missing icon.
///
@@ -418,6 +420,7 @@ public interface IPublicAPI
///
ValueTask LoadImageAsync(string path, bool loadFullImage = false, bool cacheImage = true);
+ ///
/// Update the plugin manifest
///
///
From e07beb22613a7d7c1d4cf7670d52d99546137e89 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:33:22 +0800
Subject: [PATCH 0919/1335] Add dispose
---
Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index b149884d7d4..0d395c0537a 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -13,7 +13,7 @@
namespace Flow.Launcher.Plugin.Shell
{
- public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu
+ public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, IDisposable
{
private static readonly string ClassName = nameof(Main);
@@ -442,5 +442,10 @@ public List LoadContextMenus(Result selectedResult)
return results;
}
+
+ public void Dispose()
+ {
+ Context.API.RemoveGlobalKeyboardCallback(API_GlobalKeyboardEvent);
+ }
}
}
From 46712f287ffdd188687850875acf884ad54b4a9e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:37:42 +0800
Subject: [PATCH 0920/1335] Improve api documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 42 ++++++++++++++++---
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index ff0f1ba4a26..6f17f57f57d 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -142,15 +142,47 @@ public interface IPublicAPI
List GetAllPlugins();
///
- /// Register a callback for Global Keyboard Event
- ///
- ///
+ /// Registers a callback function for global keyboard events.
+ ///
+ ///
+ /// The callback function to invoke when a global keyboard event occurs.
+ ///
+ /// Parameters:
+ ///
+ /// int: The type of (key down, key up, etc.)
+ /// int: The virtual key code of the pressed/released key
+ /// : The state of modifier keys (Ctrl, Alt, Shift, etc.)
+ ///
+ ///
+ ///
+ /// Returns: true to allow normal system processing of the key event,
+ /// or false to intercept and prevent default handling.
+ ///
+ ///
+ ///
+ /// This callback will be invoked for all keyboard events system-wide.
+ /// Use with caution as intercepting system keys may affect normal system operation.
+ ///
public void RegisterGlobalKeyboardCallback(Func callback);
-
+
///
/// Remove a callback for Global Keyboard Event
///
- ///
+ ///
+ /// The callback function to invoke when a global keyboard event occurs.
+ ///
+ /// Parameters:
+ ///
+ /// int: The type of (key down, key up, etc.)
+ /// int: The virtual key code of the pressed/released key
+ /// : The state of modifier keys (Ctrl, Alt, Shift, etc.)
+ ///
+ ///
+ ///
+ /// Returns: true to allow normal system processing of the key event,
+ /// or false to intercept and prevent default handling.
+ ///
+ ///
public void RemoveGlobalKeyboardCallback(Func callback);
///
From f71e7461c6cf83cababdd18d6c4f8f766aa20aa5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:38:52 +0800
Subject: [PATCH 0921/1335] Remove unused project reference
---
Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index 266c2417008..dbc36ad424b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -39,7 +39,6 @@
-
From 826bc42536432f8b5afe07bee6f34a7db7b7c7f2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:44:26 +0800
Subject: [PATCH 0922/1335] Improve code quality
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +-
.../Programs/UWPPackage.cs | 19 +++++-----
.../Programs/Win32.cs | 37 +++++++++----------
3 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index acfa0655ee6..99fa44257fd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -275,7 +275,7 @@ static void MoveFile(string sourcePath, string destinationPath)
static void WatchProgramUpdate()
{
Win32.WatchProgramUpdate(_settings);
- _ = UWPPackage.WatchPackageChange();
+ _ = UWPPackage.WatchPackageChangeAsync();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
index bf100ed7ee3..cb33250e15e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWPPackage.cs
@@ -8,7 +8,6 @@
using System.Windows.Media.Imaging;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.Program.Logger;
using Flow.Launcher.Plugin.SharedModels;
using System.Threading.Channels;
@@ -290,9 +289,9 @@ private static IEnumerable CurrentUserPackages()
}
}
- private static Channel PackageChangeChannel = Channel.CreateBounded(1);
+ private static readonly Channel PackageChangeChannel = Channel.CreateBounded(1);
- public static async Task WatchPackageChange()
+ public static async Task WatchPackageChangeAsync()
{
if (Environment.OSVersion.Version.Major >= 10)
{
@@ -403,13 +402,13 @@ public Result Result(string query, IPublicAPI api)
if (!Main._settings.EnableDescription || string.IsNullOrWhiteSpace(Description) || Name.Equals(Description))
{
title = Name;
- matchResult = StringMatcher.FuzzySearch(query, Name);
+ matchResult = Main.Context.API.FuzzySearch(query, Name);
}
else
{
title = $"{Name}: {Description}";
- var nameMatch = StringMatcher.FuzzySearch(query, Name);
- var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
+ var nameMatch = Main.Context.API.FuzzySearch(query, Name);
+ var descriptionMatch = Main.Context.API.FuzzySearch(query, Description);
if (descriptionMatch.Score > nameMatch.Score)
{
for (int i = 0; i < descriptionMatch.MatchData.Count; i++)
@@ -477,7 +476,7 @@ public List ContextMenus(IPublicAPI api)
{
var contextMenus = new List
{
- new Result
+ new()
{
Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"),
Action = _ =>
@@ -496,9 +495,9 @@ public List ContextMenus(IPublicAPI api)
contextMenus.Add(new Result
{
Title = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator"),
- Action = _ =>
+ Action = c =>
{
- Task.Run(() => Launch(true)).ConfigureAwait(false);
+ _ = Task.Run(() => Launch(true)).ConfigureAwait(false);
return true;
},
IcoPath = "Images/cmd.png",
@@ -539,7 +538,7 @@ internal string LogoPathFromUri(string uri, (int, int) desiredSize)
{
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
$"|{UserModelId} 's logo uri is null or empty: {Location}",
- new ArgumentException("uri"));
+ new ArgumentException(null, nameof(uri)));
return string.Empty;
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
index 06be2a628cf..a87b002d414 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
@@ -6,7 +6,6 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.Program.Logger;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.SharedModels;
@@ -73,7 +72,7 @@ public string UniqueIdentifier
private const string ExeExtension = "exe";
private string _uid = string.Empty;
- private static readonly Win32 Default = new Win32()
+ private static readonly Win32 Default = new()
{
Name = string.Empty,
Description = string.Empty,
@@ -92,7 +91,7 @@ private static MatchResult Match(string query, IReadOnlyCollection candi
if (candidates.Count == 0)
return null;
- var match = candidates.Select(candidate => StringMatcher.FuzzySearch(query, candidate))
+ var match = candidates.Select(candidate => Main.Context.API.FuzzySearch(query, candidate))
.MaxBy(match => match.Score);
return match?.IsSearchPrecisionScoreMet() ?? false ? match : null;
@@ -112,14 +111,14 @@ public Result Result(string query, IPublicAPI api)
resultName.Equals(Description))
{
title = resultName;
- matchResult = StringMatcher.FuzzySearch(query, resultName);
+ matchResult = Main.Context.API.FuzzySearch(query, resultName);
}
else
{
// Search in both
title = $"{resultName}: {Description}";
- var nameMatch = StringMatcher.FuzzySearch(query, resultName);
- var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
+ var nameMatch = Main.Context.API.FuzzySearch(query, resultName);
+ var descriptionMatch = Main.Context.API.FuzzySearch(query, Description);
if (descriptionMatch.Score > nameMatch.Score)
{
for (int i = 0; i < descriptionMatch.MatchData.Count; i++)
@@ -219,27 +218,27 @@ public List ContextMenus(IPublicAPI api)
{
var contextMenus = new List
{
- new Result
+ new()
{
Title = api.GetTranslation("flowlauncher_plugin_program_run_as_different_user"),
- Action = _ =>
+ Action = c =>
{
var info = new ProcessStartInfo
{
FileName = FullPath, WorkingDirectory = ParentDirectory, UseShellExecute = true
};
- Task.Run(() => Main.StartProcess(ShellCommand.RunAsDifferentUser, info));
+ _ = Task.Run(() => Main.StartProcess(ShellCommand.RunAsDifferentUser, info));
return true;
},
IcoPath = "Images/user.png",
Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\xe7ee"),
},
- new Result
+ new()
{
Title = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator"),
- Action = _ =>
+ Action = c =>
{
var info = new ProcessStartInfo
{
@@ -249,14 +248,14 @@ public List ContextMenus(IPublicAPI api)
UseShellExecute = true
};
- Task.Run(() => Main.StartProcess(Process.Start, info));
+ _ = Task.Run(() => Main.StartProcess(Process.Start, info));
return true;
},
IcoPath = "Images/cmd.png",
Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\xe7ef"),
},
- new Result
+ new()
{
Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"),
Action = _ =>
@@ -296,7 +295,7 @@ public override string ToString()
return Name;
}
- private static List Watchers = new List();
+ private static readonly List Watchers = new();
private static Win32 Win32Program(string path)
{
@@ -402,7 +401,7 @@ private static Win32 UrlProgram(string path, string[] protocols)
var data = parser.ReadFile(path);
var urlSection = data["InternetShortcut"];
var url = urlSection?["URL"];
- if (String.IsNullOrEmpty(url))
+ if (string.IsNullOrEmpty(url))
{
return program;
}
@@ -418,12 +417,12 @@ private static Win32 UrlProgram(string path, string[] protocols)
}
var iconPath = urlSection?["IconFile"];
- if (!String.IsNullOrEmpty(iconPath))
+ if (!string.IsNullOrEmpty(iconPath))
{
program.IcoPath = iconPath;
}
}
- catch (Exception e)
+ catch (Exception)
{
// Many files do not have the required fields, so no logging is done.
}
@@ -474,7 +473,7 @@ private static string Extension(string path)
var extension = Path.GetExtension(path)?.ToLowerInvariant();
if (!string.IsNullOrEmpty(extension))
{
- return extension.Substring(1); // remove dot
+ return extension[1..]; // remove dot
}
else
{
@@ -785,7 +784,7 @@ public static void WatchProgramUpdate(Settings settings)
_ = Task.Run(MonitorDirectoryChangeAsync);
}
- private static Channel indexQueue = Channel.CreateBounded(1);
+ private static readonly Channel indexQueue = Channel.CreateBounded(1);
public static async Task MonitorDirectoryChangeAsync()
{
From d4c9626cbf5f62fda084db5f6949b636b8da9265 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:54:20 +0800
Subject: [PATCH 0923/1335] Improve code quality & Remove unused project
reference
---
...low.Launcher.Plugin.PluginIndicator.csproj | 2 -
.../Main.cs | 41 ++++++++++++++-----
2 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj
index 21d964c1126..1e662de9ef9 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj
@@ -41,8 +41,6 @@
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
index aea0d77a1f6..05e8d960fb0 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
@@ -1,20 +1,20 @@
using System.Collections.Generic;
using System.Linq;
-using Flow.Launcher.Core.Plugin;
namespace Flow.Launcher.Plugin.PluginIndicator
{
public class Main : IPlugin, IPluginI18n
{
- private PluginInitContext context;
+ internal PluginInitContext Context { get; private set; }
public List Query(Query query)
{
+ var nonGlobalPlugins = GetNonGlobalPlugins();
var results =
- from keyword in PluginManager.NonGlobalPlugins.Keys
- let plugin = PluginManager.NonGlobalPlugins[keyword].Metadata
- let keywordSearchResult = context.API.FuzzySearch(query.Search, keyword)
- let searchResult = keywordSearchResult.IsSearchPrecisionScoreMet() ? keywordSearchResult : context.API.FuzzySearch(query.Search, plugin.Name)
+ from keyword in nonGlobalPlugins.Keys
+ let plugin = nonGlobalPlugins[keyword].Metadata
+ let keywordSearchResult = Context.API.FuzzySearch(query.Search, keyword)
+ let searchResult = keywordSearchResult.IsSearchPrecisionScoreMet() ? keywordSearchResult : Context.API.FuzzySearch(query.Search, plugin.Name)
let score = searchResult.Score
where (searchResult.IsSearchPrecisionScoreMet()
|| string.IsNullOrEmpty(query.Search)) // To list all available action keywords
@@ -22,32 +22,51 @@ from keyword in PluginManager.NonGlobalPlugins.Keys
select new Result
{
Title = keyword,
- SubTitle = string.Format(context.API.GetTranslation("flowlauncher_plugin_pluginindicator_result_subtitle"), plugin.Name),
+ SubTitle = string.Format(Context.API.GetTranslation("flowlauncher_plugin_pluginindicator_result_subtitle"), plugin.Name),
Score = score,
IcoPath = plugin.IcoPath,
AutoCompleteText = $"{keyword}{Plugin.Query.TermSeparator}",
Action = c =>
{
- context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeparator}");
+ Context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeparator}");
return false;
}
};
return results.ToList();
}
+ private Dictionary GetNonGlobalPlugins()
+ {
+ var nonGlobalPlugins = new Dictionary();
+ foreach (var plugin in Context.API.GetAllPlugins())
+ {
+ foreach (var actionKeyword in plugin.Metadata.ActionKeywords)
+ {
+ // Skip global keywords
+ if (actionKeyword == Plugin.Query.GlobalPluginWildcardSign) continue;
+
+ // Skip dulpicated keywords
+ if (nonGlobalPlugins.ContainsKey(actionKeyword)) continue;
+
+ nonGlobalPlugins.Add(actionKeyword, plugin);
+ }
+ }
+ return nonGlobalPlugins;
+ }
+
public void Init(PluginInitContext context)
{
- this.context = context;
+ Context = context;
}
public string GetTranslatedPluginTitle()
{
- return context.API.GetTranslation("flowlauncher_plugin_pluginindicator_plugin_name");
+ return Context.API.GetTranslation("flowlauncher_plugin_pluginindicator_plugin_name");
}
public string GetTranslatedPluginDescription()
{
- return context.API.GetTranslation("flowlauncher_plugin_pluginindicator_plugin_description");
+ return Context.API.GetTranslation("flowlauncher_plugin_pluginindicator_plugin_description");
}
}
}
From 17cf74e313cba0f5a0de4b6b3cc5e51bc1f22fc2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 12:57:28 +0800
Subject: [PATCH 0924/1335] Add obsolete warning
---
Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs b/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs
index 350c892cf32..f9504e6d926 100644
--- a/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs
+++ b/Flow.Launcher.Infrastructure/UI/EnumBindingSource.cs
@@ -3,6 +3,7 @@
namespace Flow.Launcher.Infrastructure.UI
{
+ [Obsolete("EnumBindingSourceExtension is obsolete. Use with Flow.Launcher.Localization NuGet package instead.")]
public class EnumBindingSourceExtension : MarkupExtension
{
private Type _enumType;
From c41d02127206047641b5e258366dfb1f4d2ee4ab Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:01:29 +0800
Subject: [PATCH 0925/1335] Add obsolete warning
---
Flow.Launcher.Core/Resource/LocalizationConverter.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Core/Resource/LocalizationConverter.cs b/Flow.Launcher.Core/Resource/LocalizationConverter.cs
index 81600e023e1..fdda33926d5 100644
--- a/Flow.Launcher.Core/Resource/LocalizationConverter.cs
+++ b/Flow.Launcher.Core/Resource/LocalizationConverter.cs
@@ -6,6 +6,7 @@
namespace Flow.Launcher.Core.Resource
{
+ [Obsolete("LocalizationConverter is obsolete. Use with Flow.Launcher.Localization NuGet package instead.")]
public class LocalizationConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
From da8a69038a3a9091c67340f5d98bea229f78844b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:05:43 +0800
Subject: [PATCH 0926/1335] Improve code quality
---
.../Resource/LocalizedDescriptionAttribute.cs | 10 ++++++---
.../Resource/TranslationConverter.cs | 14 ++++++++----
.../SettingsPanePluginStoreViewModel.cs | 4 ++--
.../SettingsPanePluginsViewModel.cs | 4 ++--
.../Search/ResultManager.cs | 22 +++++++++----------
5 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs b/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs
index 52a23233441..3e1a19a7686 100644
--- a/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs
+++ b/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs
@@ -1,15 +1,19 @@
using System.ComponentModel;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
{
public class LocalizedDescriptionAttribute : DescriptionAttribute
{
- private readonly Internationalization _translator;
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
private readonly string _resourceKey;
public LocalizedDescriptionAttribute(string resourceKey)
{
- _translator = InternationalizationManager.Instance;
_resourceKey = resourceKey;
}
@@ -17,7 +21,7 @@ public override string Description
{
get
{
- string description = _translator.GetTranslation(_resourceKey);
+ string description = API.GetTranslation(_resourceKey);
return string.IsNullOrWhiteSpace(description) ?
string.Format("[[{0}]]", _resourceKey) : description;
}
diff --git a/Flow.Launcher.Core/Resource/TranslationConverter.cs b/Flow.Launcher.Core/Resource/TranslationConverter.cs
index ebab99e5b81..eb0032758b4 100644
--- a/Flow.Launcher.Core/Resource/TranslationConverter.cs
+++ b/Flow.Launcher.Core/Resource/TranslationConverter.cs
@@ -1,19 +1,25 @@
using System;
using System.Globalization;
using System.Windows.Data;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
{
public class TranslationConverter : IValueConverter
{
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var key = value.ToString();
- if (String.IsNullOrEmpty(key))
- return key;
- return InternationalizationManager.Instance.GetTranslation(key);
+ if (string.IsNullOrEmpty(key)) return key;
+ return API.GetTranslation(key);
}
- public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture) => throw new System.InvalidOperationException();
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
+ throw new InvalidOperationException();
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 84d8a2ff926..fd2c8e09fa1 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -32,7 +32,7 @@ private async Task RefreshExternalPluginsAsync()
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
{
return string.IsNullOrEmpty(FilterText) ||
- StringMatcher.FuzzySearch(FilterText, plugin.Name).IsSearchPrecisionScoreMet() ||
- StringMatcher.FuzzySearch(FilterText, plugin.Description).IsSearchPrecisionScoreMet();
+ App.API.FuzzySearch(FilterText, plugin.Name).IsSearchPrecisionScoreMet() ||
+ App.API.FuzzySearch(FilterText, plugin.Description).IsSearchPrecisionScoreMet();
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 4958bb7b748..b89e970e99b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -106,8 +106,8 @@ public SettingsPanePluginsViewModel(Settings settings)
public List FilteredPluginViewModels => PluginViewModels
.Where(v =>
string.IsNullOrEmpty(FilterText) ||
- StringMatcher.FuzzySearch(FilterText, v.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet() ||
- StringMatcher.FuzzySearch(FilterText, v.PluginPair.Metadata.Description).IsSearchPrecisionScoreMet()
+ App.API.FuzzySearch(FilterText, v.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet() ||
+ App.API.FuzzySearch(FilterText, v.PluginPair.Metadata.Description).IsSearchPrecisionScoreMet()
)
.ToList();
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 1add8476577..5c4accdc05f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -1,16 +1,14 @@
-using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Plugin.SharedCommands;
-using System;
+using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using Flow.Launcher.Plugin.Explorer.Search.Everything;
-using System.Windows.Input;
-using Path = System.IO.Path;
using System.Windows.Controls;
+using System.Windows.Input;
+using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Views;
+using Flow.Launcher.Plugin.SharedCommands;
using Peter;
+using Path = System.IO.Path;
namespace Flow.Launcher.Plugin.Explorer.Search
{
@@ -66,7 +64,7 @@ public static Result CreateResult(Query query, SearchResult result)
CreateFolderResult(Path.GetFileName(result.FullPath), result.FullPath, result.FullPath, query, result.Score, result.WindowsIndexed),
ResultType.File =>
CreateFileResult(result.FullPath, query, result.Score, result.WindowsIndexed),
- _ => throw new ArgumentOutOfRangeException()
+ _ => throw new ArgumentOutOfRangeException(null)
};
}
@@ -99,7 +97,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
IcoPath = path,
SubTitle = subtitle,
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
- TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
+ TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
CopyText = path,
Preview = new Result.PreviewInfo
{
@@ -164,7 +162,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
return false;
},
Score = score,
- TitleToolTip = InternationalizationManager.Instance.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
+ TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
SubTitleToolTip = path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
@@ -286,7 +284,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
FilePath = filePath,
},
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
- TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
+ TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
PreviewPanel = new Lazy(() => new PreviewPanel(Settings, filePath)),
@@ -319,7 +317,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
return true;
},
- TitleToolTip = InternationalizationManager.Instance.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
+ TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
SubTitleToolTip = filePath,
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
From f5de5d70dbede5d276e311489b06fcec01656c42 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:08:28 +0800
Subject: [PATCH 0927/1335] Fix log message issue
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 99fa44257fd..54e59d1beb8 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -254,9 +254,8 @@ static void MoveFile(string sourcePath, string destinationPath)
_uwpsCount = _uwps.Count;
_uwpsLock.Release();
});
- Context.API.LogInfo(ClassName, "Number of preload win32 programs <{_win32sCount}>");
- Context.API.LogInfo(ClassName, "Number of preload uwps <{_uwpsCount}>");
-
+ Context.API.LogInfo(ClassName, $"Number of preload win32 programs <{_win32sCount}>");
+ Context.API.LogInfo(ClassName, $"Number of preload uwps <{_uwpsCount}>");
var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
if (cacheEmpty || _settings.LastIndexTime.AddHours(30) < DateTime.Now)
From 71b9e4a81121be6d445716786bbf2efe186d85c5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:09:37 +0800
Subject: [PATCH 0928/1335] Fix log info class name issue
---
Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index f6de65e90dd..f479078242e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -393,7 +393,7 @@ private Result CreateAddToIndexSearchExclusionListResult(SearchResult record)
{
Title = Context.API.GetTranslation("plugin_explorer_excludefromindexsearch"),
SubTitle = Context.API.GetTranslation("plugin_explorer_path") + " " + record.FullPath,
- Action = _ =>
+ Action = c_ =>
{
if (!Settings.IndexSearchExcludedSubdirectoryPaths.Any(x => string.Equals(x.Path, record.FullPath, StringComparison.OrdinalIgnoreCase)))
Settings.IndexSearchExcludedSubdirectoryPaths.Add(new AccessLink
@@ -401,7 +401,7 @@ private Result CreateAddToIndexSearchExclusionListResult(SearchResult record)
Path = record.FullPath
});
- Task.Run(() =>
+ _ = Task.Run(() =>
{
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_excludedfromindexsearch_msg"),
Context.API.GetTranslation("plugin_explorer_path") +
@@ -469,7 +469,7 @@ private Result CreateOpenWithMenu(SearchResult record)
private void LogException(string message, Exception e)
{
- Context.API.LogException(nameof(Main), message, e);
+ Context.API.LogException(nameof(ContextMenu), message, e);
}
private static bool CanRunAsDifferentUser(string path)
From 048a40d085915e59e7d05d3faf17132ec39aadac Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:11:55 +0800
Subject: [PATCH 0929/1335] Code quality
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 3eb74dd7442..3bee49bf20a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -32,7 +32,7 @@ public void Init(PluginInitContext context)
_settings = context.API.LoadSettingJsonStorage();
_faviconCacheDir = Path.Combine(
- _context.CurrentPluginMetadata.PluginCacheDirectoryPath,
+ context.CurrentPluginMetadata.PluginCacheDirectoryPath,
"FaviconCache");
FilesFolders.ValidateDirectory(_faviconCacheDir);
From 7061ac54485e3bd95177dbe737e8b2c4fc521903 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 13:12:05 +0800
Subject: [PATCH 0930/1335] Fix register bookmark file comment
---
.../ChromiumBookmarkLoader.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 27bcbd9a935..7631aad9116 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -37,7 +37,7 @@ protected List LoadBookmarks(string browserDataPath, string name)
{
if (File.Exists(bookmarkPath))
{
- //Main.RegisterBookmarkFile(bookmarkPath);
+ Main.RegisterBookmarkFile(bookmarkPath);
}
}
catch (Exception ex)
From f854cd3f7623f12b10eddba2beb69599e9672f5f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 15:22:41 +0800
Subject: [PATCH 0931/1335] Code quality
---
Flow.Launcher.Infrastructure/Image/ImageCache.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs
index ddbab4ef0b1..b8c12868bfb 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
-using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using BitFaster.Caching.Lfu;
@@ -55,7 +53,6 @@ public bool TryGetValue(string key, bool isFullImage, out ImageSource image)
return image != null;
}
-
image = null;
return false;
}
From 82f67884ef4619d2f05a931d02e47b40b95479c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 16:15:37 +0800
Subject: [PATCH 0932/1335] Support svg image file loading
---
.../Flow.Launcher.Infrastructure.csproj | 1 +
.../Image/ImageLoader.cs | 66 +++++++++++++++++--
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 4 +-
.../FirefoxBookmarkLoader.cs | 20 +-----
4 files changed, 66 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index b91da711480..f02b2297f64 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -67,6 +67,7 @@
+
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 41a33104b66..6fd5c627766 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -9,6 +9,8 @@
using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
+using SharpVectors.Converters;
+using SharpVectors.Renderers.Wpf;
namespace Flow.Launcher.Infrastructure.Image
{
@@ -25,8 +27,10 @@ public static class ImageLoader
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
public const int SmallIconSize = 64;
public const int FullIconSize = 256;
+ public const int FullImageSize = 320;
private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
+ private static readonly string SvgExtension = ".svg";
public static async Task InitializeAsync()
{
@@ -245,6 +249,19 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
}
}
+ else if (extension == SvgExtension)
+ {
+ try
+ {
+ image = LoadFullSvgImage(path, loadFullImage);
+ type = ImageType.FullImageFile;
+ }
+ catch (System.Exception)
+ {
+ image = Image;
+ type = ImageType.Error;
+ }
+ }
else
{
type = ImageType.File;
@@ -318,7 +335,7 @@ public static async ValueTask LoadAsync(string path, bool loadFullI
return img;
}
- private static BitmapImage LoadFullImage(string path)
+ private static ImageSource LoadFullImage(string path)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
@@ -327,24 +344,24 @@ private static BitmapImage LoadFullImage(string path)
image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
image.EndInit();
- if (image.PixelWidth > 320)
+ if (image.PixelWidth > FullImageSize)
{
BitmapImage resizedWidth = new BitmapImage();
resizedWidth.BeginInit();
resizedWidth.CacheOption = BitmapCacheOption.OnLoad;
resizedWidth.UriSource = new Uri(path);
resizedWidth.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
- resizedWidth.DecodePixelWidth = 320;
+ resizedWidth.DecodePixelWidth = FullImageSize;
resizedWidth.EndInit();
- if (resizedWidth.PixelHeight > 320)
+ if (resizedWidth.PixelHeight > FullImageSize)
{
BitmapImage resizedHeight = new BitmapImage();
resizedHeight.BeginInit();
resizedHeight.CacheOption = BitmapCacheOption.OnLoad;
resizedHeight.UriSource = new Uri(path);
resizedHeight.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
- resizedHeight.DecodePixelHeight = 320;
+ resizedHeight.DecodePixelHeight = FullImageSize;
resizedHeight.EndInit();
return resizedHeight;
}
@@ -354,5 +371,44 @@ private static BitmapImage LoadFullImage(string path)
return image;
}
+
+ private static ImageSource LoadFullSvgImage(string path, bool loadFullImage = false)
+ {
+ // Set up drawing settings
+ var desiredHeight = loadFullImage ? FullImageSize : SmallIconSize;
+ var drawingSettings = new WpfDrawingSettings
+ {
+ IncludeRuntime = true,
+ // Set IgnoreRootViewbox to false to respect the SVG's viewBox
+ IgnoreRootViewbox = false
+ };
+
+ // Load and render the SVG
+ var converter = new FileSvgReader(drawingSettings);
+ var drawing = converter.Read(path);
+
+ // Calculate scale to achieve desired height
+ var drawingBounds = drawing.Bounds;
+ var scale = desiredHeight / drawingBounds.Height;
+ var scaledWidth = drawingBounds.Width * scale;
+ var scaledHeight = drawingBounds.Height * scale;
+
+ // Convert the Drawing to a Bitmap
+ var drawingVisual = new DrawingVisual();
+ using DrawingContext drawingContext = drawingVisual.RenderOpen();
+ drawingContext.PushTransform(new ScaleTransform(scale, scale));
+ drawingContext.DrawDrawing(drawing);
+
+ // Create a RenderTargetBitmap to hold the rendered image
+ var bitmap = new RenderTargetBitmap(
+ (int)Math.Ceiling(scaledWidth),
+ (int)Math.Ceiling(scaledHeight),
+ 96, // DpiX
+ 96, // DpiY
+ PixelFormats.Pbgra32);
+ bitmap.Render(drawingVisual);
+
+ return bitmap;
+ }
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 6f17f57f57d..f37496fd19e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -438,7 +438,9 @@ public interface IPublicAPI
Task SaveCacheBinaryStorageAsync(string cacheName, string cacheDirectory) where T : new();
///
- /// Load image from path. Support local, remote and data:image url.
+ /// Load image from path.
+ /// Support local, remote and data:image url.
+ /// Support png, jpg, jpeg, gif, bmp, tiff, ico, svg image files.
/// If image path is missing, it will return a missing icon.
///
/// The path of the image.
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index d2f9733293f..113476703ef 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -159,16 +159,7 @@ ORDER BY i.width DESC -- Select largest icon available
if (!File.Exists(faviconPath))
{
- // SVG 파일인지 확인
- if (IsSvgData(imageData))
- {
- bookmark.FaviconPath = defaultIconPath;
- continue;
- }
- else
- {
- SaveBitmapData(imageData, faviconPath);
- }
+ SaveBitmapData(imageData, faviconPath);
}
bookmark.FaviconPath = faviconPath;
@@ -199,15 +190,6 @@ ORDER BY i.width DESC -- Select largest icon available
}
}
- private static bool IsSvgData(byte[] data)
- {
- if (data.Length < 5)
- return false;
- string start = System.Text.Encoding.ASCII.GetString(data, 0, Math.Min(100, data.Length));
- return start.Contains("
Date: Wed, 9 Apr 2025 16:24:09 +0800
Subject: [PATCH 0933/1335] Change function name
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 6fd5c627766..ba46a7cff46 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -253,7 +253,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
{
try
{
- image = LoadFullSvgImage(path, loadFullImage);
+ image = LoadSvgImage(path, loadFullImage);
type = ImageType.FullImageFile;
}
catch (System.Exception)
@@ -372,7 +372,7 @@ private static ImageSource LoadFullImage(string path)
return image;
}
- private static ImageSource LoadFullSvgImage(string path, bool loadFullImage = false)
+ private static ImageSource LoadSvgImage(string path, bool loadFullImage = false)
{
// Set up drawing settings
var desiredHeight = loadFullImage ? FullImageSize : SmallIconSize;
From 5e7573b654d135cb92ca92c576d8f54295763374 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 16:28:53 +0800
Subject: [PATCH 0934/1335] Add log messages
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index ba46a7cff46..e0959ccc27f 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -233,10 +233,11 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
image = LoadFullImage(path);
type = ImageType.FullImageFile;
}
- catch (NotSupportedException)
+ catch (NotSupportedException ex)
{
image = Image;
type = ImageType.Error;
+ Log.Exception($"Failed to load image file from path {path}: {ex.Message}", ex);
}
}
else
@@ -256,10 +257,11 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
image = LoadSvgImage(path, loadFullImage);
type = ImageType.FullImageFile;
}
- catch (System.Exception)
+ catch (System.Exception ex)
{
image = Image;
type = ImageType.Error;
+ Log.Exception($"Failed to load SVG image from path {path}: {ex.Message}", ex);
}
}
else
From cce4e89c221e32291b2c88547a5f8f52e585c84c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 16:30:35 +0800
Subject: [PATCH 0935/1335] Add safeguards to SVG loading implementation
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index e0959ccc27f..0433036b7c2 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -391,6 +391,10 @@ private static ImageSource LoadSvgImage(string path, bool loadFullImage = false)
// Calculate scale to achieve desired height
var drawingBounds = drawing.Bounds;
+ if (drawingBounds.Height <= 0)
+ {
+ throw new InvalidOperationException($"Invalid SVG dimensions: Height must be greater than zero in {path}");
+ }
var scale = desiredHeight / drawingBounds.Height;
var scaledWidth = drawingBounds.Width * scale;
var scaledHeight = drawingBounds.Height * scale;
From 4f246460c353cec83a7b8fbfde31c26eba159219 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 16:46:13 +0800
Subject: [PATCH 0936/1335] Fix build issue
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 4 ++--
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 --
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index be360995666..cd5a4cf7154 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -243,7 +243,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
{
image = Image;
type = ImageType.Error;
- Log.Exception($"Failed to load image file from path {path}: {ex.Message}", ex);
+ API.LogException(ClassName, $"Failed to load image file from path {path}: {ex.Message}", ex);
}
}
else
@@ -267,7 +267,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
{
image = Image;
type = ImageType.Error;
- Log.Exception($"Failed to load SVG image from path {path}: {ex.Message}", ex);
+ API.LogException(ClassName, $"Failed to load SVG image from path {path}: {ex.Message}", ex);
}
}
else
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index dca07d08516..16b6bcab203 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -32,8 +32,6 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
internal static PluginInitContext Context { get; private set; }
- private static readonly string ClassName = nameof(Main);
-
private static readonly List emptyResults = new();
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
From 5c55d29e1f8788a7f5cc62231fda7b9774e66342 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 9 Apr 2025 17:54:37 +0900
Subject: [PATCH 0937/1335] =?UTF-8?q?Handle=20it=20so=20that=20it=20doesn?=
=?UTF-8?q?=E2=80=99t=20show=20if=20the=20registry=20is=20missing.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Views/SettingsPaneGeneral.xaml | 33 +++++++++++--------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 1d4dfd8ae84..d225b01a4a2 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -3,12 +3,12 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
+ xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ext="clr-namespace:Flow.Launcher.Resources.MarkupExtensions"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:settingsViewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels"
xmlns:ui="http://schemas.modernwpf.com/2019"
- xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
Title="General"
d:DataContext="{d:DesignInstance settingsViewModels:SettingsPaneGeneralViewModel}"
@@ -32,7 +32,7 @@
Style="{StaticResource PageTitle}"
Text="{DynamicResource general}"
TextAlignment="left" />
-
+
-
-
+
+
+
+
+ Icon=""
+ Sub="{DynamicResource KoreanImeRegistryTooltip}">
-
+ Icon=""
+ Sub="{DynamicResource KoreanImeOpenLinkTooltip}">
+
From ba0205f47100c54b91276bc3e25c45add0981f75 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 17:05:29 +0800
Subject: [PATCH 0938/1335] Force save favicon icons & Fix svg save issue
---
.../ChromiumBookmarkLoader.cs | 8 +++----
.../FirefoxBookmarkLoader.cs | 21 +++++++++++++++----
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 7631aad9116..7e29cb350dd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -177,11 +177,9 @@ ORDER BY b.width DESC
if (imageData is not { Length: > 0 })
continue;
- var faviconPath = Path.Combine(_faviconCacheDir, $"{domain}_{iconId}.png");
- if (!File.Exists(faviconPath))
- {
- SaveBitmapData(imageData, faviconPath);
- }
+ var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
+ SaveBitmapData(imageData, faviconPath);
+
bookmark.FaviconPath = faviconPath;
}
catch (Exception ex)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index 113476703ef..b356d08b885 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -155,12 +155,16 @@ ORDER BY i.width DESC -- Select largest icon available
if (imageData is not { Length: > 0 })
continue;
- var faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.png");
-
- if (!File.Exists(faviconPath))
+ string faviconPath;
+ if (IsSvgData(imageData))
+ {
+ faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.svg");
+ }
+ else
{
- SaveBitmapData(imageData, faviconPath);
+ faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.png");
}
+ SaveBitmapData(imageData, faviconPath);
bookmark.FaviconPath = faviconPath;
}
@@ -201,6 +205,15 @@ private static void SaveBitmapData(byte[] imageData, string outputPath)
Main._context.API.LogException(ClassName, $"Failed to save image: {outputPath}", ex);
}
}
+
+ private static bool IsSvgData(byte[] data)
+ {
+ if (data.Length < 5)
+ return false;
+ string start = System.Text.Encoding.ASCII.GetString(data, 0, Math.Min(100, data.Length));
+ return start.Contains("
Date: Wed, 9 Apr 2025 17:13:44 +0800
Subject: [PATCH 0939/1335] Fix svg render issue
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index cd5a4cf7154..9e31d2b4ebf 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -393,7 +393,7 @@ private static ImageSource LoadSvgImage(string path, bool loadFullImage = false)
// Load and render the SVG
var converter = new FileSvgReader(drawingSettings);
- var drawing = converter.Read(path);
+ var drawing = converter.Read(new Uri(path));
// Calculate scale to achieve desired height
var drawingBounds = drawing.Bounds;
@@ -407,9 +407,11 @@ private static ImageSource LoadSvgImage(string path, bool loadFullImage = false)
// Convert the Drawing to a Bitmap
var drawingVisual = new DrawingVisual();
- using DrawingContext drawingContext = drawingVisual.RenderOpen();
- drawingContext.PushTransform(new ScaleTransform(scale, scale));
- drawingContext.DrawDrawing(drawing);
+ using (DrawingContext drawingContext = drawingVisual.RenderOpen())
+ {
+ drawingContext.PushTransform(new ScaleTransform(scale, scale));
+ drawingContext.DrawDrawing(drawing);
+ }
// Create a RenderTargetBitmap to hold the rendered image
var bitmap = new RenderTargetBitmap(
From 62a5dd784daff12d945c80ac2b1c756fd8571638 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 17:24:40 +0800
Subject: [PATCH 0940/1335] Delete temporary files
---
.../ChromiumBookmarkLoader.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 7e29cb350dd..156dd2f0e94 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -136,6 +136,10 @@ private void LoadFaviconsFromDb(string dbPath, List bookmarks)
Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
return;
}
+ finally
+ {
+ File.Delete(tempDbPath);
+ }
try
{
From 150ea841912f5dc280a42e6d522f78c86afe60b0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 17:27:34 +0800
Subject: [PATCH 0941/1335] Make sure temporary files deleted
---
.../FirefoxBookmarkLoader.cs | 46 ++++++++++---------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
index b356d08b885..75f26d32252 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs
@@ -41,6 +41,8 @@ protected List GetBookmarksFromPath(string placesPath)
if (string.IsNullOrEmpty(placesPath) || !File.Exists(placesPath))
return bookmarks;
+ var tempDbPath = Path.Combine(_faviconCacheDir, $"tempplaces_{Guid.NewGuid()}.sqlite");
+
try
{
// Try to register file monitoring
@@ -54,7 +56,6 @@ protected List GetBookmarksFromPath(string placesPath)
}
// Use a copy to avoid lock issues with the original file
- var tempDbPath = Path.Combine(_faviconCacheDir, $"tempplaces_{Guid.NewGuid()}.sqlite");
File.Copy(placesPath, tempDbPath, true);
// Connect to database and execute query
@@ -83,31 +84,32 @@ protected List GetBookmarksFromPath(string placesPath)
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(dbConnection);
dbConnection.Close();
-
- // Delete temporary file
- try
- {
- File.Delete(tempDbPath);
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
- }
}
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to load Firefox bookmarks: {placesPath}", ex);
}
+ // Delete temporary file
+ try
+ {
+ File.Delete(tempDbPath);
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
+ }
+
return bookmarks;
}
private void LoadFaviconsFromDb(string faviconDbPath, List bookmarks)
{
+ var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.sqlite");
+
try
{
// Use a copy to avoid lock issues with the original file
- var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.sqlite");
File.Copy(faviconDbPath, tempDbPath, true);
var defaultIconPath = Path.Combine(
@@ -177,21 +179,21 @@ ORDER BY i.width DESC -- Select largest icon available
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(connection);
connection.Close();
-
- // Delete temporary file
- try
- {
- File.Delete(tempDbPath);
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
- }
}
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {faviconDbPath}", ex);
}
+
+ // Delete temporary file
+ try
+ {
+ File.Delete(tempDbPath);
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
+ }
}
private static void SaveBitmapData(byte[] imageData, string outputPath)
From 33800795ed27bddd4e3a5cfb9e3db6b2bba73763 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 17:29:28 +0800
Subject: [PATCH 0942/1335] Remove useless try catch
---
.../ChromiumBookmarkLoader.cs | 121 +++++++++---------
1 file changed, 57 insertions(+), 64 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 156dd2f0e94..4b9499c2700 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -122,45 +122,43 @@ private static void EnumerateFolderBookmark(JsonElement folderElement, ICollecti
private void LoadFaviconsFromDb(string dbPath, List bookmarks)
{
+ // Use a copy to avoid lock issues with the original file
+ var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.db");
+
try
{
- // Use a copy to avoid lock issues with the original file
- var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.db");
+ File.Copy(dbPath, tempDbPath, true);
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
+ return;
+ }
+ finally
+ {
+ File.Delete(tempDbPath);
+ }
- try
- {
- File.Copy(dbPath, tempDbPath, true);
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
- return;
- }
- finally
- {
- File.Delete(tempDbPath);
- }
+ try
+ {
+ using var connection = new SqliteConnection($"Data Source={tempDbPath}");
+ connection.Open();
- try
+ foreach (var bookmark in bookmarks)
{
- using var connection = new SqliteConnection($"Data Source={tempDbPath}");
- connection.Open();
-
- foreach (var bookmark in bookmarks)
+ try
{
- try
- {
- var url = bookmark.Url;
- if (string.IsNullOrEmpty(url)) continue;
+ var url = bookmark.Url;
+ if (string.IsNullOrEmpty(url)) continue;
- // Extract domain from URL
- if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
- continue;
+ // Extract domain from URL
+ if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
+ continue;
- var domain = uri.Host;
+ var domain = uri.Host;
- using var cmd = connection.CreateCommand();
- cmd.CommandText = @"
+ using var cmd = connection.CreateCommand();
+ cmd.CommandText = @"
SELECT f.id, b.image_data
FROM favicons f
JOIN favicon_bitmaps b ON f.id = b.icon_id
@@ -169,51 +167,46 @@ WHERE m.page_url LIKE @url
ORDER BY b.width DESC
LIMIT 1";
- cmd.Parameters.AddWithValue("@url", $"%{domain}%");
+ cmd.Parameters.AddWithValue("@url", $"%{domain}%");
- using var reader = cmd.ExecuteReader();
- if (!reader.Read() || reader.IsDBNull(1))
- continue;
+ using var reader = cmd.ExecuteReader();
+ if (!reader.Read() || reader.IsDBNull(1))
+ continue;
- var iconId = reader.GetInt64(0).ToString();
- var imageData = (byte[])reader["image_data"];
+ var iconId = reader.GetInt64(0).ToString();
+ var imageData = (byte[])reader["image_data"];
- if (imageData is not { Length: > 0 })
- continue;
+ if (imageData is not { Length: > 0 })
+ continue;
- var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
- SaveBitmapData(imageData, faviconPath);
+ var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
+ SaveBitmapData(imageData, faviconPath);
- bookmark.FaviconPath = faviconPath;
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to extract bookmark favicon: {bookmark.Url}", ex);
- }
+ bookmark.FaviconPath = faviconPath;
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to extract bookmark favicon: {bookmark.Url}", ex);
}
-
- // https://github.com/dotnet/efcore/issues/26580
- SqliteConnection.ClearPool(connection);
- connection.Close();
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to connect to SQLite: {tempDbPath}", ex);
}
- // Delete temporary file
- try
- {
- File.Delete(tempDbPath);
- }
- catch (Exception ex)
- {
- Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
- }
+ // https://github.com/dotnet/efcore/issues/26580
+ SqliteConnection.ClearPool(connection);
+ connection.Close();
+ }
+ catch (Exception ex)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to connect to SQLite: {tempDbPath}", ex);
+ }
+
+ // Delete temporary file
+ try
+ {
+ File.Delete(tempDbPath);
}
catch (Exception ex)
{
- Main._context.API.LogException(ClassName, $"Failed to load favicon DB: {dbPath}", ex);
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex);
}
}
From 2d29a42dc950f612e2161bd5f6c49d09444ef8bb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 17:32:48 +0800
Subject: [PATCH 0943/1335] Improve code quality
---
.../ChromiumBookmarkLoader.cs | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 4b9499c2700..66be0890388 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -131,13 +131,10 @@ private void LoadFaviconsFromDb(string dbPath, List bookmarks)
}
catch (Exception ex)
{
+ File.Delete(tempDbPath);
Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
return;
}
- finally
- {
- File.Delete(tempDbPath);
- }
try
{
From d3fdd99e1085b10480d12fd660f89ba5b7f7d50f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 18:09:54 +0800
Subject: [PATCH 0944/1335] Fix ConnectionLostException for JsonRPC v2 plugins
---
Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 18 +++------------
.../Plugin/JsonRPCPluginBase.cs | 4 ++--
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 22 ++++++++++++++-----
3 files changed, 21 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
index 88d595301be..9f64e418ca7 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core.Resource;
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -7,10 +6,10 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin;
using Microsoft.IO;
-using System.Windows;
namespace Flow.Launcher.Core.Plugin
{
@@ -20,7 +19,7 @@ namespace Flow.Launcher.Core.Plugin
///
internal abstract class JsonRPCPlugin : JsonRPCPluginBase
{
- public const string JsonRPC = "JsonRPC";
+ public new const string JsonRPC = "JsonRPC";
protected abstract Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default);
protected abstract string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default);
@@ -29,9 +28,6 @@ internal abstract class JsonRPCPlugin : JsonRPCPluginBase
private int RequestId { get; set; }
- private string SettingConfigurationPath => Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");
- private string SettingPath => Path.Combine(Context.CurrentPluginMetadata.PluginSettingsDirectoryPath, "Settings.json");
-
public override List LoadContextMenus(Result selectedResult)
{
var request = new JsonRPCRequestModel(RequestId++,
@@ -57,13 +53,6 @@ public override List LoadContextMenus(Result selectedResult)
}
};
- private static readonly JsonSerializerOptions settingSerializeOption = new()
- {
- WriteIndented = true
- };
-
- private readonly Dictionary _settingControls = new();
-
private async Task> DeserializedResultAsync(Stream output)
{
await using (output)
@@ -122,7 +111,6 @@ protected override async Task ExecuteResultAsync(JsonRPCResult result)
return !result.JsonRPCAction.DontHideAfterAction;
}
-
///
/// Execute external program and return the output
///
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
index 779dcf887d8..b134e2d50fe 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
@@ -1,11 +1,11 @@
-using Flow.Launcher.Core.Resource;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index abe563c145a..d240ac9bef2 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -10,7 +10,6 @@
using StreamJsonRpc;
using IAsyncDisposable = System.IAsyncDisposable;
-
namespace Flow.Launcher.Core.Plugin
{
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, IAsyncReloadable, IResultUpdated
@@ -23,7 +22,6 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I
private JsonRpc RPC { get; set; }
-
protected override async Task ExecuteResultAsync(JsonRPCResult result)
{
var res = await RPC.InvokeAsync(result.JsonRPCAction.Method,
@@ -55,7 +53,6 @@ public override async Task> QueryAsync(Query query, CancellationTok
return results;
}
-
public override async Task InitAsync(PluginInitContext context)
{
await base.InitAsync(context);
@@ -88,7 +85,6 @@ protected enum MessageHandlerType
protected abstract MessageHandlerType MessageHandler { get; }
-
private void SetupJsonRPC()
{
var formatter = new SystemTextJsonFormatter { JsonSerializerOptions = RequestSerializeOption };
@@ -118,9 +114,16 @@ public virtual async Task ReloadDataAsync()
{
await RPC.InvokeAsync("reload_data", Context);
}
- catch (RemoteMethodNotFoundException e)
+ catch (RemoteMethodNotFoundException)
+ {
+ }
+ catch (ConnectionLostException)
{
}
+ catch (Exception e)
+ {
+ Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call reload_data", e);
+ }
}
public virtual async ValueTask DisposeAsync()
@@ -129,8 +132,15 @@ public virtual async ValueTask DisposeAsync()
{
await RPC.InvokeAsync("close");
}
- catch (RemoteMethodNotFoundException e)
+ catch (RemoteMethodNotFoundException)
+ {
+ }
+ catch (ConnectionLostException)
+ {
+ }
+ catch (Exception e)
{
+ Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call close", e);
}
finally
{
From 8730a5fce8079a955a98533307c8c91383ce1f95 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 18:10:44 +0800
Subject: [PATCH 0945/1335] Improve log message
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index d240ac9bef2..eda016d9401 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -122,7 +122,7 @@ public virtual async Task ReloadDataAsync()
}
catch (Exception e)
{
- Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call reload_data", e);
+ Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e);
}
}
@@ -140,7 +140,7 @@ public virtual async ValueTask DisposeAsync()
}
catch (Exception e)
{
- Context.API.LogException(nameof(JsonRPCPluginV2), "Failed to call close", e);
+ Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e);
}
finally
{
From 4095eb4b86cccca1d9be969c0cac59e52b48dd64 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 19:26:52 +0800
Subject: [PATCH 0946/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs | 17 +++++++++--------
Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs | 7 ++-----
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 6 ++++--
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
index 9f64e418ca7..b19bb6c79af 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPlugin.cs
@@ -7,7 +7,6 @@
using System.Threading;
using System.Threading.Tasks;
using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin;
using Microsoft.IO;
@@ -21,6 +20,8 @@ internal abstract class JsonRPCPlugin : JsonRPCPluginBase
{
public new const string JsonRPC = "JsonRPC";
+ private static readonly string ClassName = nameof(JsonRPCPlugin);
+
protected abstract Task RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default);
protected abstract string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default);
@@ -148,11 +149,11 @@ protected string Execute(ProcessStartInfo startInfo)
var error = standardError.ReadToEnd();
if (!string.IsNullOrEmpty(error))
{
- Log.Error($"|JsonRPCPlugin.Execute|{error}");
+ Context.API.LogError(ClassName, error);
return string.Empty;
}
- Log.Error("|JsonRPCPlugin.Execute|Empty standard output and standard error.");
+ Context.API.LogError(ClassName, "Empty standard output and standard error.");
return string.Empty;
}
@@ -160,8 +161,8 @@ protected string Execute(ProcessStartInfo startInfo)
}
catch (Exception e)
{
- Log.Exception(
- $"|JsonRPCPlugin.Execute|Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>",
+ Context.API.LogException(ClassName,
+ $"Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>",
e);
return string.Empty;
}
@@ -172,7 +173,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati
using var process = Process.Start(startInfo);
if (process == null)
{
- Log.Error("|JsonRPCPlugin.ExecuteAsync|Can't start new process");
+ Context.API.LogError(ClassName, "Can't start new process");
return Stream.Null;
}
@@ -192,7 +193,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati
}
catch (Exception e)
{
- Log.Exception("|JsonRPCPlugin.ExecuteAsync|Exception when kill process", e);
+ Context.API.LogException(ClassName, "Exception when kill process", e);
}
});
@@ -213,7 +214,7 @@ protected async Task ExecuteAsync(ProcessStartInfo startInfo, Cancellati
{
case (0, 0):
const string errorMessage = "Empty JSON-RPC Response.";
- Log.Warn($"|{nameof(JsonRPCPlugin)}.{nameof(ExecuteAsync)}|{errorMessage}");
+ Context.API.LogWarn(ClassName, errorMessage);
break;
case (_, not 0):
throw new InvalidDataException(Encoding.UTF8.GetString(errorBuffer.ToArray())); // The process has exited with an error message
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
index b134e2d50fe..df0438409f3 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
@@ -19,10 +19,9 @@ namespace Flow.Launcher.Core.Plugin
///
public abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISettingProvider, ISavable
{
- protected PluginInitContext Context;
public const string JsonRPC = "JsonRPC";
- private int RequestId { get; set; }
+ protected PluginInitContext Context;
private string SettingConfigurationPath =>
Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");
@@ -107,7 +106,6 @@ protected void ExecuteFlowLauncherAPI(string method, object[] parameters)
public abstract Task> QueryAsync(Query query, CancellationToken token);
-
private async Task InitSettingAsync()
{
JsonRpcConfigurationModel configuration = null;
@@ -119,7 +117,6 @@ private async Task InitSettingAsync()
await File.ReadAllTextAsync(SettingConfigurationPath));
}
-
Settings ??= new JsonRPCPluginSettings
{
Configuration = configuration, SettingPath = SettingPath, API = Context.API
@@ -130,7 +127,7 @@ private async Task InitSettingAsync()
public virtual async Task InitAsync(PluginInitContext context)
{
- this.Context = context;
+ Context = context;
await InitSettingAsync();
}
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index eda016d9401..6dccfa59b1a 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -16,6 +16,8 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I
{
public const string JsonRpc = "JsonRPC";
+ private static readonly string ClassName = nameof(JsonRPCPluginV2);
+
protected abstract IDuplexPipe ClientPipe { get; set; }
protected StreamReader ErrorStream { get; set; }
@@ -122,7 +124,7 @@ public virtual async Task ReloadDataAsync()
}
catch (Exception e)
{
- Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e);
+ Context.API.LogException(ClassName, $"Failed to call reload_data for plugin {Context.CurrentPluginMetadata.Name}", e);
}
}
@@ -140,7 +142,7 @@ public virtual async ValueTask DisposeAsync()
}
catch (Exception e)
{
- Context.API.LogException(nameof(JsonRPCPluginV2), $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e);
+ Context.API.LogException(ClassName, $"Failed to call close for plugin {Context.CurrentPluginMetadata.Name}", e);
}
finally
{
From 5a2db37d39fcd1c614e06e7d54a938bc37a9d3b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 19:43:22 +0800
Subject: [PATCH 0947/1335] Add code comments
---
Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
index 6dccfa59b1a..148fd969e49 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
@@ -118,9 +118,11 @@ public virtual async Task ReloadDataAsync()
}
catch (RemoteMethodNotFoundException)
{
+ // Ignored
}
catch (ConnectionLostException)
{
+ // Ignored
}
catch (Exception e)
{
@@ -136,9 +138,11 @@ public virtual async ValueTask DisposeAsync()
}
catch (RemoteMethodNotFoundException)
{
+ // Ignored
}
catch (ConnectionLostException)
{
+ // Ignored
}
catch (Exception e)
{
From 4400734963a6eabc5e13fdc031ed57619755e784 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:12:09 +0800
Subject: [PATCH 0948/1335] Remove InternationalizationManager.Instance
---
.../Resource/InternationalizationManager.cs | 12 ---------
Flow.Launcher/ActionKeywords.xaml.cs | 27 ++++++++-----------
Flow.Launcher/Converters/TextConverter.cs | 3 +--
.../CustomQueryHotkeySetting.xaml.cs | 8 +++---
Flow.Launcher/CustomShortcutSetting.xaml.cs | 10 +++----
Flow.Launcher/Helper/HotKeyMapper.cs | 13 +++++----
Flow.Launcher/HotkeyControl.xaml.cs | 13 +++------
Flow.Launcher/HotkeyControlDialog.xaml.cs | 13 +++++----
.../Resources/Pages/WelcomePage1.xaml.cs | 9 ++++---
.../SettingsPaneGeneralViewModel.cs | 27 +++++++++----------
.../ViewModels/SettingsPaneHotkeyViewModel.cs | 17 ++++++------
.../ViewModels/SettingsPaneProxyViewModel.cs | 3 +--
.../Views/SettingsPaneGeneral.xaml.cs | 4 ++-
13 files changed, 65 insertions(+), 94 deletions(-)
delete mode 100644 Flow.Launcher.Core/Resource/InternationalizationManager.cs
diff --git a/Flow.Launcher.Core/Resource/InternationalizationManager.cs b/Flow.Launcher.Core/Resource/InternationalizationManager.cs
deleted file mode 100644
index 5d718466c4b..00000000000
--- a/Flow.Launcher.Core/Resource/InternationalizationManager.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using CommunityToolkit.Mvvm.DependencyInjection;
-
-namespace Flow.Launcher.Core.Resource
-{
- [Obsolete("InternationalizationManager.Instance is obsolete. Use Ioc.Default.GetRequiredService() instead.")]
- public static class InternationalizationManager
- {
- public static Internationalization Instance
- => Ioc.Default.GetRequiredService();
- }
-}
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index d403d484734..ad24f2a761f 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -1,8 +1,6 @@
using System.Windows;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
-using Flow.Launcher.Core;
using System.Linq;
using System.Collections.Generic;
@@ -10,20 +8,19 @@ namespace Flow.Launcher
{
public partial class ActionKeywords
{
- private readonly PluginPair plugin;
- private readonly Internationalization translater = InternationalizationManager.Instance;
- private readonly PluginViewModel pluginViewModel;
+ private readonly PluginPair _plugin;
+ private readonly PluginViewModel _pluginViewModel;
public ActionKeywords(PluginViewModel pluginViewModel)
{
InitializeComponent();
- plugin = pluginViewModel.PluginPair;
- this.pluginViewModel = pluginViewModel;
+ _plugin = pluginViewModel.PluginPair;
+ _pluginViewModel = pluginViewModel;
}
private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e)
{
- tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeparator, plugin.Metadata.ActionKeywords.ToArray());
+ tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeparator, _plugin.Metadata.ActionKeywords.ToArray());
tbAction.Focus();
}
@@ -34,7 +31,7 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
- var oldActionKeywords = plugin.Metadata.ActionKeywords;
+ var oldActionKeywords = _plugin.Metadata.ActionKeywords;
var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator).ToList();
newActionKeywords.RemoveAll(string.IsNullOrEmpty);
@@ -48,7 +45,7 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
if (oldActionKeywords.Count != newActionKeywords.Count)
{
- ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
+ ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
return;
}
@@ -58,18 +55,16 @@ private void btnDone_OnClick(object sender, RoutedEventArgs _)
if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords))
{
// User just changes the sequence of action keywords
- var msg = translater.GetTranslation("newActionKeywordsSameAsOld");
- MessageBoxEx.Show(msg);
+ App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsSameAsOld"));
}
else
{
- ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
+ ReplaceActionKeyword(_plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
}
}
else
{
- string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
- App.API.ShowMsgBox(msg);
+ App.API.ShowMsgBox(App.API.GetTranslation("newActionKeywordsHasBeenAssigned"));
}
}
@@ -85,7 +80,7 @@ private void ReplaceActionKeyword(string id, IReadOnlyList removedAction
}
// Update action keywords text and close window
- pluginViewModel.OnActionKeywordsChanged();
+ _pluginViewModel.OnActionKeywordsChanged();
Close();
}
}
diff --git a/Flow.Launcher/Converters/TextConverter.cs b/Flow.Launcher/Converters/TextConverter.cs
index 5f0e1ea82c2..2c4dad4a956 100644
--- a/Flow.Launcher/Converters/TextConverter.cs
+++ b/Flow.Launcher/Converters/TextConverter.cs
@@ -1,7 +1,6 @@
using System;
using System.Globalization;
using System.Windows.Data;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Converters;
@@ -23,7 +22,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
if (translationKey is null)
return id;
- return InternationalizationManager.Instance.GetTranslation(translationKey);
+ return App.API.GetTranslation(translationKey);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new InvalidOperationException();
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 53fa173a511..8b193fa1dee 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Helper;
+using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
using System.Collections.ObjectModel;
using System.Linq;
@@ -53,14 +52,13 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
Close();
}
-
public void UpdateItem(CustomPluginHotkey item)
{
updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("invalidPluginHotkey"));
+ App.API.ShowMsgBox(App.API.GetTranslation("invalidPluginHotkey"));
Close();
return;
}
@@ -68,7 +66,7 @@ public void UpdateItem(CustomPluginHotkey item)
tbAction.Text = updateCustomHotkey.ActionKeyword;
HotkeyControl.SetHotkey(updateCustomHotkey.Hotkey, false);
update = true;
- lblAdd.Text = InternationalizationManager.Instance.GetTranslation("update");
+ lblAdd.Text = App.API.GetTranslation("update");
}
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 416f8e04951..ecbdea60627 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -1,9 +1,7 @@
-using Flow.Launcher.Core.Resource;
-using System;
+using System;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.Core;
namespace Flow.Launcher
{
@@ -41,15 +39,15 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
{
- if (String.IsNullOrEmpty(Key) || String.IsNullOrEmpty(Value))
+ if (string.IsNullOrEmpty(Key) || string.IsNullOrEmpty(Value))
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("emptyShortcut"));
+ App.API.ShowMsgBox(App.API.GetTranslation("emptyShortcut"));
return;
}
// Check if key is modified or adding a new one
if (((update && originalKey != Key) || !update) && _hotkeyVm.DoesShortcutExist(Key))
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("duplicateShortcut"));
+ App.API.ShowMsgBox(App.API.GetTranslation("duplicateShortcut"));
return;
}
DialogResult = !update || originalKey != Key || originalValue != Value;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 7b2fdfcf499..de5f5295b18 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -3,7 +3,6 @@
using System;
using NHotkey;
using NHotkey.Wpf;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.ViewModel;
using ChefKeys;
using Flow.Launcher.Infrastructure.Logger;
@@ -56,8 +55,8 @@ private static void SetWithChefKeys(string hotkeyStr)
string.Format("|HotkeyMapper.SetWithChefKeys|Error registering hotkey: {0} \nStackTrace:{1}",
e.Message,
e.StackTrace));
- string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
- string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
+ string errorMsg = string.Format(App.API.GetTranslation("registerHotkeyFailed"), hotkeyStr);
+ string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle");
MessageBoxEx.Show(errorMsg, errorMsgTitle);
}
}
@@ -82,8 +81,8 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
e.Message,
e.StackTrace,
hotkeyStr));
- string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr);
- string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
+ string errorMsg = string.Format(App.API.GetTranslation("registerHotkeyFailed"), hotkeyStr);
+ string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle");
App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
@@ -107,8 +106,8 @@ internal static void RemoveHotkey(string hotkeyStr)
string.Format("|HotkeyMapper.RemoveHotkey|Error removing hotkey: {0} \nStackTrace:{1}",
e.Message,
e.StackTrace));
- string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("unregisterHotkeyFailed"), hotkeyStr);
- string errorMsgTitle = InternationalizationManager.Instance.GetTranslation("MessageBoxTitle");
+ string errorMsg = string.Format(App.API.GetTranslation("unregisterHotkeyFailed"), hotkeyStr);
+ string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle");
MessageBoxEx.Show(errorMsg, errorMsgTitle);
}
}
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index 678280bbaf2..8762a934bbb 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -5,7 +5,6 @@
using System.Windows;
using System.Windows.Input;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -65,7 +64,6 @@ private static void OnHotkeyChanged(DependencyObject d, DependencyPropertyChange
hotkeyControl.RefreshHotkeyInterface(hotkeyControl.Hotkey);
}
-
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
nameof(ChangeHotkey),
typeof(ICommand),
@@ -79,7 +77,6 @@ public ICommand? ChangeHotkey
set { SetValue(ChangeHotkeyProperty, value); }
}
-
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register(
nameof(Type),
typeof(HotkeyType),
@@ -227,19 +224,18 @@ private void RefreshHotkeyInterface(string hotkey)
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
- public string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
+ public string EmptyHotkey => App.API.GetTranslation("none");
public ObservableCollection KeysToDisplay { get; set; } = new();
public HotkeyModel CurrentHotkey { get; private set; } = new(false, false, false, false, Key.None);
-
public void GetNewHotkey(object sender, RoutedEventArgs e)
{
- OpenHotkeyDialog();
+ _ = OpenHotkeyDialogAsync();
}
- private async Task OpenHotkeyDialog()
+ private async Task OpenHotkeyDialogAsync()
{
if (!string.IsNullOrEmpty(Hotkey))
{
@@ -262,12 +258,11 @@ private async Task OpenHotkeyDialog()
}
}
-
private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
{
if (triggerValidate)
{
- bool hotkeyAvailable = false;
+ bool hotkeyAvailable;
// TODO: This is a temporary way to enforce changing only the open flow hotkey to Win, and will be removed by PR #3157
if (keyModel.ToString() == "LWin" || keyModel.ToString() == "RWin")
{
diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs
index 2f8c5eb2616..c7af8c5b8bb 100644
--- a/Flow.Launcher/HotkeyControlDialog.xaml.cs
+++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs
@@ -5,7 +5,6 @@
using System.Windows.Input;
using ChefKeys;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -34,7 +33,7 @@ public enum EResultType
public EResultType ResultType { get; private set; } = EResultType.Cancel;
public string ResultValue { get; private set; } = string.Empty;
- public static string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
+ public static string EmptyHotkey => App.API.GetTranslation("none");
private static bool isOpenFlowHotkey;
@@ -42,7 +41,7 @@ public HotkeyControlDialog(string hotkey, string defaultHotkey, string windowTit
{
WindowTitle = windowTitle switch
{
- "" or null => InternationalizationManager.Instance.GetTranslation("hotkeyRegTitle"),
+ "" or null => App.API.GetTranslation("hotkeyRegTitle"),
_ => windowTitle
};
DefaultHotkey = defaultHotkey;
@@ -141,14 +140,14 @@ private void SetKeysToDisplay(HotkeyModel? hotkey)
if (_hotkeySettings.RegisteredHotkeys.FirstOrDefault(v => v.Hotkey == hotkey) is { } registeredHotkeyData)
{
var description = string.Format(
- InternationalizationManager.Instance.GetTranslation(registeredHotkeyData.DescriptionResourceKey),
+ App.API.GetTranslation(registeredHotkeyData.DescriptionResourceKey),
registeredHotkeyData.DescriptionFormatVariables
);
Alert.Visibility = Visibility.Visible;
if (registeredHotkeyData.RemoveHotkey is not null)
{
tbMsg.Text = string.Format(
- InternationalizationManager.Instance.GetTranslation("hotkeyUnavailableEditable"),
+ App.API.GetTranslation("hotkeyUnavailableEditable"),
description
);
SaveBtn.IsEnabled = false;
@@ -160,7 +159,7 @@ private void SetKeysToDisplay(HotkeyModel? hotkey)
else
{
tbMsg.Text = string.Format(
- InternationalizationManager.Instance.GetTranslation("hotkeyUnavailableUneditable"),
+ App.API.GetTranslation("hotkeyUnavailableUneditable"),
description
);
SaveBtn.IsEnabled = false;
@@ -176,7 +175,7 @@ private void SetKeysToDisplay(HotkeyModel? hotkey)
if (!CheckHotkeyAvailability(hotkey.Value, true))
{
- tbMsg.Text = InternationalizationManager.Instance.GetTranslation("hotkeyUnavailable");
+ tbMsg.Text = App.API.GetTranslation("hotkeyUnavailable");
Alert.Visibility = Visibility.Visible;
SaveBtn.IsEnabled = false;
SaveBtn.Visibility = Visibility.Visible;
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 880bfd9bcc2..64f52edffe3 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -17,7 +17,9 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
Ioc.Default.GetRequiredService().PageNum = 1;
InitializeComponent();
}
- private Internationalization _translater => InternationalizationManager.Instance;
+
+ private readonly Internationalization _translater = Ioc.Default.GetRequiredService();
+
public List Languages => _translater.LoadAvailableLanguages();
public Settings Settings { get; set; }
@@ -30,12 +32,11 @@ public string CustomLanguage
}
set
{
- InternationalizationManager.Instance.ChangeLanguage(value);
+ _translater.ChangeLanguage(value);
- if (InternationalizationManager.Instance.PromptShouldUsePinyin(value))
+ if (_translater.PromptShouldUsePinyin(value))
Settings.ShouldUsePinyin = true;
}
}
-
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 35dbab64776..57eb796d3c7 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Windows.Forms;
-using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
@@ -19,12 +17,14 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
public Settings Settings { get; }
private readonly Updater _updater;
private readonly IPortable _portable;
+ private readonly Internationalization _translater;
- public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable)
+ public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable, Internationalization translater)
{
Settings = settings;
_updater = updater;
_portable = portable;
+ _translater = translater;
UpdateEnumDropdownLocalizations();
}
@@ -32,7 +32,6 @@ public class SearchWindowScreenData : DropdownDataGeneric {
public class SearchWindowAlignData : DropdownDataGeneric { }
public class SearchPrecisionData : DropdownDataGeneric { }
public class LastQueryModeData : DropdownDataGeneric { }
-
public bool StartFlowLauncherOnSystemStartup
{
@@ -61,7 +60,7 @@ public bool StartFlowLauncherOnSystemStartup
}
catch (Exception e)
{
- Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
e.Message);
}
}
@@ -89,7 +88,7 @@ public bool UseLogonTaskForStartup
}
catch (Exception e)
{
- Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
+ Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
e.Message);
}
}
@@ -121,7 +120,7 @@ public List ScreenNumbers
}
// This is only required to set at startup. When portable mode enabled/disabled a restart is always required
- private bool _portableMode = DataLocation.PortableDataLocationInUse();
+ private static bool _portableMode = DataLocation.PortableDataLocationInUse();
public bool PortableMode
{
@@ -173,9 +172,9 @@ public string Language
get => Settings.Language;
set
{
- InternationalizationManager.Instance.ChangeLanguage(value);
+ _translater.ChangeLanguage(value);
- if (InternationalizationManager.Instance.PromptShouldUsePinyin(value))
+ if (_translater.PromptShouldUsePinyin(value))
ShouldUsePinyin = true;
UpdateEnumDropdownLocalizations();
@@ -188,14 +187,14 @@ public bool ShouldUsePinyin
set => Settings.ShouldUsePinyin = value;
}
- public List Languages => InternationalizationManager.Instance.LoadAvailableLanguages();
+ public List Languages => _translater.LoadAvailableLanguages();
public string AlwaysPreviewToolTip => string.Format(
- InternationalizationManager.Instance.GetTranslation("AlwaysPreviewToolTip"),
+ App.API.GetTranslation("AlwaysPreviewToolTip"),
Settings.PreviewHotkey
);
- private string GetFileFromDialog(string title, string filter = "")
+ private static string GetFileFromDialog(string title, string filter = "")
{
var dlg = new OpenFileDialog
{
@@ -237,7 +236,7 @@ public bool AutoUpdates
private void SelectPython()
{
var selectedFile = GetFileFromDialog(
- InternationalizationManager.Instance.GetTranslation("selectPythonExecutable"),
+ App.API.GetTranslation("selectPythonExecutable"),
"Python|pythonw.exe"
);
@@ -249,7 +248,7 @@ private void SelectPython()
private void SelectNode()
{
var selectedFile = GetFileFromDialog(
- InternationalizationManager.Instance.GetTranslation("selectNodeExecutable"),
+ App.API.GetTranslation("selectNodeExecutable"),
"node|*.exe"
);
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
index b13aaefe3e9..7a7c19dd358 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs
@@ -1,7 +1,6 @@
using System.Linq;
using System.Windows;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
@@ -41,15 +40,15 @@ private void CustomHotkeyDelete()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(App.API.GetTranslation("pleaseSelectAnItem"));
return;
}
var result = App.API.ShowMsgBox(
string.Format(
- InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
+ App.API.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey
),
- InternationalizationManager.Instance.GetTranslation("delete"),
+ App.API.GetTranslation("delete"),
MessageBoxButton.YesNo
);
@@ -66,7 +65,7 @@ private void CustomHotkeyEdit()
var item = SelectedCustomPluginHotkey;
if (item is null)
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(App.API.GetTranslation("pleaseSelectAnItem"));
return;
}
@@ -87,15 +86,15 @@ private void CustomShortcutDelete()
var item = SelectedCustomShortcut;
if (item is null)
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(App.API.GetTranslation("pleaseSelectAnItem"));
return;
}
var result = App.API.ShowMsgBox(
string.Format(
- InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
+ App.API.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value
),
- InternationalizationManager.Instance.GetTranslation("delete"),
+ App.API.GetTranslation("delete"),
MessageBoxButton.YesNo
);
@@ -111,7 +110,7 @@ private void CustomShortcutEdit()
var item = SelectedCustomShortcut;
if (item is null)
{
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem"));
+ App.API.ShowMsgBox(App.API.GetTranslation("pleaseSelectAnItem"));
return;
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index e2f9e516ca4..38a6ef31eaa 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -1,7 +1,6 @@
using System.Net;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -22,7 +21,7 @@ public SettingsPaneProxyViewModel(Settings settings, Updater updater)
private void OnTestProxyClicked()
{
var message = TestProxy();
- App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation(message));
+ App.API.ShowMsgBox(App.API.GetTranslation(message));
}
private string TestProxy()
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index dd7fd13a995..569d489d2c6 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -2,6 +2,7 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
+using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
@@ -18,7 +19,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
var settings = Ioc.Default.GetRequiredService();
var updater = Ioc.Default.GetRequiredService();
var portable = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable);
+ var translater = Ioc.Default.GetRequiredService();
+ _viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable, translater);
DataContext = _viewModel;
InitializeComponent();
}
From 0a8963b74ee05da73afbcd05d9e817925c79477b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:16:33 +0800
Subject: [PATCH 0949/1335] Remove Notification.Show & _mainViewModel.Show();
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/Helper/HotKeyMapper.cs | 2 +-
.../SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs | 6 ++----
Flow.Launcher/ViewModel/MainViewModel.cs | 3 +--
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 90fefe0a642..89faa105ea7 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -343,7 +343,7 @@ public void Dispose()
public void OnSecondAppStarted()
{
- Ioc.Default.GetRequiredService().Show();
+ API.ShowMainWindow();
}
#endregion
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index de5f5295b18..b7b39ff313f 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -136,7 +136,7 @@ internal static void SetCustomQueryHotkey(CustomPluginHotkey hotkey)
if (_mainViewModel.ShouldIgnoreHotkeys())
return;
- _mainViewModel.Show();
+ App.API.ShowMainWindow();
_mainViewModel.ChangeQueryText(hotkey.ActionKeyword, true);
});
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 57eb796d3c7..069a7cb24d8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -60,8 +60,7 @@ public bool StartFlowLauncherOnSystemStartup
}
catch (Exception e)
{
- Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
- e.Message);
+ App.API.ShowMsg(App.API.GetTranslation("setAutoStartFailed"), e.Message);
}
}
}
@@ -88,8 +87,7 @@ public bool UseLogonTaskForStartup
}
catch (Exception e)
{
- Notification.Show(App.API.GetTranslation("setAutoStartFailed"),
- e.Message);
+ App.API.ShowMsg(App.API.GetTranslation("setAutoStartFailed"), e.Message);
}
}
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 66481cad665..4a6c1d63971 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -16,7 +16,6 @@
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
-using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -275,7 +274,7 @@ private async Task ReloadPluginDataAsync()
Hide();
await PluginManager.ReloadDataAsync().ConfigureAwait(false);
- Notification.Show(App.API.GetTranslation("success"),
+ App.API.ShowMsg(App.API.GetTranslation("success"),
App.API.GetTranslation("completedSuccessfully"));
}
From 1bd7f1471ac73e60d2aeb62fbe6b099b381942b9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:19:09 +0800
Subject: [PATCH 0950/1335] Improve GetTranslation usage
---
Flow.Launcher.Core/Updater.cs | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 20b884b3d0d..83d4fd9e0a7 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -9,8 +9,6 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
@@ -131,7 +129,7 @@ private static async Task GitHubUpdateManagerAsync(string reposit
await using var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false);
- var releases = await System.Text.Json.JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false);
+ var releases = await JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false);
var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First();
var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/");
@@ -146,10 +144,9 @@ private static async Task GitHubUpdateManagerAsync(string reposit
return manager;
}
- private static string NewVersionTips(string version)
+ private string NewVersionTips(string version)
{
- var translator = Ioc.Default.GetRequiredService();
- var tips = string.Format(translator.GetTranslation("newVersionTips"), version);
+ var tips = string.Format(_api.GetTranslation("newVersionTips"), version);
return tips;
}
From 509705413729ac658cd5ae70df06349a710a0615 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:20:32 +0800
Subject: [PATCH 0951/1335] Improve log code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 4c85fb061e3..29d91dc8d28 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -205,7 +205,7 @@ public static async Task InitializePluginsAsync()
}
catch (Exception e)
{
- Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e);
+ Log.Exception(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
pair.Metadata.Disabled = true;
failedPlugins.Enqueue(pair);
}
From 9f11c8739aee2ac3362b025f69e858b9e2c20240 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:26:27 +0800
Subject: [PATCH 0952/1335] Remove _mainViewModel.ChangeQueryText
---
Flow.Launcher/Helper/HotKeyMapper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index b7b39ff313f..5e3b3028108 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -137,7 +137,7 @@ internal static void SetCustomQueryHotkey(CustomPluginHotkey hotkey)
return;
App.API.ShowMainWindow();
- _mainViewModel.ChangeQueryText(hotkey.ActionKeyword, true);
+ App.API.ChangeQuery(hotkey.ActionKeyword, true);
});
}
From f47699829c4200754491b60082330f6f721b5e29 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 9 Apr 2025 21:27:03 +0800
Subject: [PATCH 0953/1335] Remove MessageBoxEx.Show
---
Flow.Launcher/Helper/HotKeyMapper.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 5e3b3028108..0771a60749a 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -57,7 +57,7 @@ private static void SetWithChefKeys(string hotkeyStr)
e.StackTrace));
string errorMsg = string.Format(App.API.GetTranslation("registerHotkeyFailed"), hotkeyStr);
string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle");
- MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
@@ -108,7 +108,7 @@ internal static void RemoveHotkey(string hotkeyStr)
e.StackTrace));
string errorMsg = string.Format(App.API.GetTranslation("unregisterHotkeyFailed"), hotkeyStr);
string errorMsgTitle = App.API.GetTranslation("MessageBoxTitle");
- MessageBoxEx.Show(errorMsg, errorMsgTitle);
+ App.API.ShowMsgBox(errorMsg, errorMsgTitle);
}
}
From 7fdc2161c43acb1196ea29ea1614934268f7f118 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 9 Apr 2025 23:36:51 +0900
Subject: [PATCH 0954/1335] Fix small things for merging dev
---
Flow.Launcher/Languages/en.xaml | 1 -
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 8 ++++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index dc0799f90f4..1b0400d7b57 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -130,7 +130,6 @@
Open
Use Legacy Korean IME
You can change the IME settings directly from here without opening a separate settings window
- Wait time before showing results after typing stops. Higher values wait longer. (ms)
Search Plugin
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index ca8d2fd6c17..6b0f9d4406a 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -220,12 +220,12 @@
+ ValidationMode="InvalidInputOverwritten"
+ Value="{Binding SearchDelayTimeValue}" />
@@ -325,7 +325,7 @@
IsIconVisible="True"
Length="Long"
Message="{DynamicResource KoreanImeGuide}"
- Type="Info"
+ Type="Warning"
Visibility="{Binding LegacyKoreanIMEEnabled, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=Inverted, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
From 77ffafc582e34898e17167ac80830c6c8181ccb4 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 9 Apr 2025 23:43:36 +0900
Subject: [PATCH 0955/1335] Fix string
---
Flow.Launcher/Languages/en.xaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 1b0400d7b57..9315f05c906 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -148,6 +148,10 @@
Change Action Keywords
Plugin seach delay time
Change Plugin Seach Delay Time
+ Advanced Settings:
+ Enabled
+ Priority
+ Search Delay
Current Priority
New Priority
Priority
From 3c49d8e7304a352a49b9f96541eab9e8141d7fe9 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 00:38:35 +0900
Subject: [PATCH 0956/1335] Fix Binding error
---
Flow.Launcher/Resources/Controls/InfoBar.xaml | 36 ++++++++++---------
.../Resources/Controls/InfoBar.xaml.cs | 4 +--
.../SettingsPaneGeneralViewModel.cs | 16 ++++++---
.../Views/SettingsPaneGeneral.xaml | 1 +
4 files changed, 32 insertions(+), 25 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml b/Flow.Launcher/Resources/Controls/InfoBar.xaml
index 1713b3459b3..f82a32a8baa 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml
@@ -2,6 +2,7 @@
x:Class="Flow.Launcher.Resources.Controls.InfoBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -26,21 +27,22 @@
-
-
-
+
+
+
+ Text="{Binding RelativeSource={RelativeSource AncestorType=cc:InfoBar}, Path=Title}" />
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
index f50bc349e83..8b82dc3b6f5 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,9 +19,7 @@ private void InfoBar_Loaded(object sender, RoutedEventArgs e)
UpdateMessageVisibility();
UpdateOrientation();
UpdateIconAlignmentAndMargin();
-
- // DataContext 설정 (예시)
- this.DataContext = this; // InfoBar 자체를 DataContext로 사용
+ //this.DataContext = this;
}
public static readonly DependencyProperty TypeProperty =
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 9590f728303..b98d7600091 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -188,15 +188,21 @@ public string Language
UpdateEnumDropdownLocalizations();
}
}
-
- public bool LegacyKoreanIMEEnabled
+ public bool LegacyKoreanIMEEnabled
{
get => IsLegacyKoreanIMEEnabled();
set
{
- SetLegacyKoreanIMEEnabled(value);
- OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
- OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled 변경: {value}");
+ if (SetLegacyKoreanIMEEnabled(value))
+ {
+ OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ }
+ else
+ {
+ Debug.WriteLine("[DEBUG] LegacyKoreanIMEEnabled 설정 실패");
+ }
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 6b0f9d4406a..16db1c6769b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -322,6 +322,7 @@
Title="{DynamicResource KoreanImeTitle}"
Margin="0 12 0 0"
Closable="False"
+ DataContext="{Binding RelativeSource={RelativeSource AncestorType=Border}, Path=DataContext}"
IsIconVisible="True"
Length="Long"
Message="{DynamicResource KoreanImeGuide}"
From d9a353b4522b1471e18d684fe270256626094323 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 00:52:34 +0900
Subject: [PATCH 0957/1335] - Fix String and adjust messages - Adjust Margin -
Cleanup comment
---
Flow.Launcher/Languages/en.xaml | 11 +-
.../SettingsPaneGeneralViewModel.cs | 169 +++++++++---------
.../Views/SettingsPaneGeneral.xaml | 6 +-
3 files changed, 93 insertions(+), 93 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 9315f05c906..bf430b6f54f 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -118,18 +118,17 @@
Very short
Information for Korean IME user
- You're using the Korean language! The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
- If you experience any problems, you may need to enable compatibility mode for the Korean IME.
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
Open Setting in Windows 11 and go to:
Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
and enable "Use previous version of Microsoft IME".
- You can open the relevant menu using the option below, or change the setting directly without manually opening the settings page.
Open Language and Region System Settings
- Opens the Korean IME setting locationKorean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
Open
- Use Legacy Korean IME
- You can change the IME settings directly from here without opening a separate settings window
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
Search Plugin
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index b98d7600091..701de43613b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -189,127 +189,128 @@ public string Language
}
}
public bool LegacyKoreanIMEEnabled
+{
+ get => IsLegacyKoreanIMEEnabled();
+ set
{
- get => IsLegacyKoreanIMEEnabled();
- set
+ Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled changed: {value}");
+ if (SetLegacyKoreanIMEEnabled(value))
{
- Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled 변경: {value}");
- if (SetLegacyKoreanIMEEnabled(value))
- {
- OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
- OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
- }
- else
- {
- Debug.WriteLine("[DEBUG] LegacyKoreanIMEEnabled 설정 실패");
- }
+ OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
}
- }
-
- public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
-
- public bool KoreanIMERegistryValueIsZero
- {
- get
+ else
{
- object value = GetLegacyKoreanIMERegistryValue();
- if (value is int intValue)
- {
- return intValue == 0;
- }
- else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
- {
- return parsedValue == 0;
- }
-
- return false;
+ Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
}
}
+}
- bool IsKoreanIMEExist()
- {
- return GetLegacyKoreanIMERegistryValue() != null;
- }
+public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
- bool IsLegacyKoreanIMEEnabled()
+public bool KoreanIMERegistryValueIsZero
+{
+ get
{
object value = GetLegacyKoreanIMERegistryValue();
-
if (value is int intValue)
{
- return intValue == 1;
+ return intValue == 0;
}
else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
{
- return parsedValue == 1;
+ return parsedValue == 0;
}
return false;
}
+}
+
+bool IsKoreanIMEExist()
+{
+ return GetLegacyKoreanIMERegistryValue() != null;
+}
+
+bool IsLegacyKoreanIMEEnabled()
+{
+ object value = GetLegacyKoreanIMERegistryValue();
- bool SetLegacyKoreanIMEEnabled(bool enable)
+ if (value is int intValue)
{
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
+ return intValue == 1;
+ }
+ else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ {
+ return parsedValue == 1;
+ }
+
+ return false;
+}
- try
+bool SetLegacyKoreanIMEEnabled(bool enable)
+{
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
+ {
+ using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
{
- using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
+ if (key != null)
{
- if (key != null)
- {
- int value = enable ? 1 : 0;
- key.SetValue(valueName, value, RegistryValueKind.DWord);
- return true;
- }
- else
- {
- Debug.WriteLine($"[IME DEBUG] 레지스트리 키 생성 또는 열기 실패: {subKeyPath}");
- }
+ int value = enable ? 1 : 0;
+ key.SetValue(valueName, value, RegistryValueKind.DWord);
+ return true;
+ }
+ else
+ {
+ Debug.WriteLine($"[IME DEBUG] Failed to create or open registry key: {subKeyPath}");
}
}
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] 레지스트리 설정 중 예외 발생: {ex.Message}");
- }
-
- return false;
}
-
- private object GetLegacyKoreanIMERegistryValue()
+ catch (Exception ex)
{
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
+ Debug.WriteLine($"[IME DEBUG] Exception occurred while setting registry: {ex.Message}");
+ }
- try
+ return false;
+}
+
+private object GetLegacyKoreanIMERegistryValue()
+{
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
+ {
+ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
{
- using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
+ if (key != null)
{
- if (key != null)
- {
- return key.GetValue(valueName);
- }
+ return key.GetValue(valueName);
}
}
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] 예외 발생: {ex.Message}");
- }
-
- return null;
}
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
+ }
+
+ return null;
+}
- private void OpenImeSettings()
+private void OpenImeSettings()
+{
+ try
{
- try
- {
- Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
- }
- catch (Exception e)
- {
- Debug.WriteLine($"Error opening IME settings: {e.Message}");
- }
+ Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
}
+ catch (Exception e)
+ {
+ Debug.WriteLine($"Error opening IME settings: {e.Message}");
+ }
+}
+
public bool ShouldUsePinyin
{
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 16db1c6769b..5304824fed5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -320,7 +320,7 @@
-
+
+ Sub="{DynamicResource KoreanImeOpenLinkToolTip}">
From be0a9b7eadbee301e8441319f67ec714070383dc Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 01:11:36 +0900
Subject: [PATCH 0958/1335] clean up comment
---
Flow.Launcher/Resources/Controls/InfoBar.xaml.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
index 8b82dc3b6f5..d447192cfb6 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,7 +19,6 @@ private void InfoBar_Loaded(object sender, RoutedEventArgs e)
UpdateMessageVisibility();
UpdateOrientation();
UpdateIconAlignmentAndMargin();
- //this.DataContext = this;
}
public static readonly DependencyProperty TypeProperty =
@@ -48,7 +47,7 @@ public string Message
set
{
SetValue(MessageProperty, value);
- UpdateMessageVisibility(); // Message 속성 변경 시 Visibility 업데이트
+ UpdateMessageVisibility(); // Visibility update when change Message
}
}
@@ -74,7 +73,7 @@ public string Title
set
{
SetValue(TitleProperty, value);
- UpdateTitleVisibility(); // Title 속성 변경 시 Visibility 업데이트
+ UpdateTitleVisibility(); // Visibility update when change Title
}
}
From 317f241c26feea8c970ce5cc36bf0d4422b46300 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 01:25:12 +0900
Subject: [PATCH 0959/1335] - Add Comment - Applied changes from CodeRabbit
---
.../Resources/Controls/InfoBar.xaml.cs | 2 +
.../SettingsPaneGeneralViewModel.cs | 177 +++++++++---------
2 files changed, 94 insertions(+), 85 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
index d447192cfb6..f4e26ea7c09 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -19,6 +19,8 @@ private void InfoBar_Loaded(object sender, RoutedEventArgs e)
UpdateMessageVisibility();
UpdateOrientation();
UpdateIconAlignmentAndMargin();
+ UpdateIconVisibility();
+ UpdateCloseButtonVisibility();
}
public static readonly DependencyProperty TypeProperty =
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 701de43613b..432ac998c0e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -34,6 +34,7 @@ public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortabl
_portable = portable;
_translater = translater;
UpdateEnumDropdownLocalizations();
+ // Initialize the Korean IME status by checking registry
IsLegacyKoreanIMEEnabled();
OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
@@ -188,129 +189,135 @@ public string Language
UpdateEnumDropdownLocalizations();
}
}
+
+ // The new Korean IME used in Windows 11 has compatibility issues with WPF. This issue is difficult to resolve within
+ // WPF itself, but it can be avoided by having the user switch to the legacy IME at the system level. Therefore,
+ // we provide guidance and a direct button for users to make this change themselves. If the relevant registry key does
+ // not exist (i.e., the Korean IME is not installed), this setting will not be shown at all.
+ #region Korean IME
public bool LegacyKoreanIMEEnabled
-{
- get => IsLegacyKoreanIMEEnabled();
- set
{
- Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled changed: {value}");
- if (SetLegacyKoreanIMEEnabled(value))
+ get => IsLegacyKoreanIMEEnabled();
+ set
{
- OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
- OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled changed: {value}");
+ if (SetLegacyKoreanIMEEnabled(value))
+ {
+ OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
+ }
+ else
+ {
+ Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
+ }
}
- else
+ }
+
+ public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+
+ public bool KoreanIMERegistryValueIsZero
+ {
+ get
{
- Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
+ object value = GetLegacyKoreanIMERegistryValue();
+ if (value is int intValue)
+ {
+ return intValue == 0;
+ }
+ else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ {
+ return parsedValue == 0;
+ }
+
+ return false;
}
}
-}
-public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+ bool IsKoreanIMEExist()
+ {
+ return GetLegacyKoreanIMERegistryValue() != null;
+ }
-public bool KoreanIMERegistryValueIsZero
-{
- get
+ bool IsLegacyKoreanIMEEnabled()
{
object value = GetLegacyKoreanIMERegistryValue();
+
if (value is int intValue)
{
- return intValue == 0;
+ return intValue == 1;
}
else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
{
- return parsedValue == 0;
+ return parsedValue == 1;
}
return false;
}
-}
-
-bool IsKoreanIMEExist()
-{
- return GetLegacyKoreanIMERegistryValue() != null;
-}
-
-bool IsLegacyKoreanIMEEnabled()
-{
- object value = GetLegacyKoreanIMERegistryValue();
- if (value is int intValue)
- {
- return intValue == 1;
- }
- else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ bool SetLegacyKoreanIMEEnabled(bool enable)
{
- return parsedValue == 1;
- }
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
- return false;
-}
-
-bool SetLegacyKoreanIMEEnabled(bool enable)
-{
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
-
- try
- {
- using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
+ try
{
- if (key != null)
+ using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
{
- int value = enable ? 1 : 0;
- key.SetValue(valueName, value, RegistryValueKind.DWord);
- return true;
- }
- else
- {
- Debug.WriteLine($"[IME DEBUG] Failed to create or open registry key: {subKeyPath}");
+ if (key != null)
+ {
+ int value = enable ? 1 : 0;
+ key.SetValue(valueName, value, RegistryValueKind.DWord);
+ return true;
+ }
+ else
+ {
+ Debug.WriteLine($"[IME DEBUG] Failed to create or open registry key: {subKeyPath}");
+ }
}
}
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] Exception occurred while setting registry: {ex.Message}");
- }
-
- return false;
-}
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[IME DEBUG] Exception occurred while setting registry: {ex.Message}");
+ }
-private object GetLegacyKoreanIMERegistryValue()
-{
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
+ return false;
+ }
- try
+ private object GetLegacyKoreanIMERegistryValue()
{
- using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
{
- if (key != null)
+ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
{
- return key.GetValue(valueName);
+ if (key != null)
+ {
+ return key.GetValue(valueName);
+ }
}
}
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
- }
-
- return null;
-}
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
+ }
-private void OpenImeSettings()
-{
- try
- {
- Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ return null;
}
- catch (Exception e)
+
+ private void OpenImeSettings()
{
- Debug.WriteLine($"Error opening IME settings: {e.Message}");
+ try
+ {
+ Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine($"Error opening IME settings: {e.Message}");
+ }
}
-}
-
+ #endregion
public bool ShouldUsePinyin
{
From 1c1bad087ce11066e315e5ea9efd1de4fcae76cb Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 01:37:06 +0900
Subject: [PATCH 0960/1335] Cleanup Code
---
Flow.Launcher/Resources/Controls/InfoBar.xaml | 2 +-
.../Resources/Controls/InfoBar.xaml.cs | 19 +++++++++----------
.../SettingsPaneGeneralViewModel.cs | 2 --
3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml b/Flow.Launcher/Resources/Controls/InfoBar.xaml
index f82a32a8baa..3c6780690ad 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml
@@ -28,7 +28,7 @@
Date: Thu, 10 Apr 2025 01:42:35 +0900
Subject: [PATCH 0961/1335] Remove namespace Add Default Case
---
Flow.Launcher/Resources/Controls/InfoBar.xaml | 3 ++-
Flow.Launcher/Resources/Controls/InfoBar.xaml.cs | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml b/Flow.Launcher/Resources/Controls/InfoBar.xaml
index 3c6780690ad..2ddcbdd0cc8 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml
@@ -3,7 +3,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
- xmlns:converters="clr-namespace:Flow.Launcher.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
@@ -69,10 +68,12 @@
Width="32"
Height="32"
VerticalAlignment="Center"
+ AutomationProperties.Name="Close InfoBar"
Click="PART_CloseButton_Click"
Content=""
FontFamily="Segoe MDL2 Assets"
FontSize="12"
+ ToolTip="Close"
Visibility="Visible" />
diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
index 77470dbc2d1..ebf763e22ab 100644
--- a/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/InfoBar.xaml.cs
@@ -175,6 +175,11 @@ private void UpdateStyle()
PART_IconBorder.Background = (Brush)FindResource("InfoBarErrorIcon");
PART_Icon.Glyph = "\xF13D";
break;
+ default:
+ PART_Border.Background = (Brush)FindResource("InfoBarInfoBG");
+ PART_IconBorder.Background = (Brush)FindResource("InfoBarInfoIcon");
+ PART_Icon.Glyph = "\xF13F";
+ break;
}
}
From ebff80caea3dd3d7e0cf05ee95ef6b3515b6aa23 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 01:46:29 +0900
Subject: [PATCH 0962/1335] Add Error Message
---
.../SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 3a20f81d568..33a7428dbbe 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -206,7 +206,8 @@ public bool LegacyKoreanIMEEnabled
}
else
{
- Debug.WriteLine("[DEBUG] Failed to set LegacyKoreanIMEEnabled");
+ //Since this is rarely seen text, language support is not provided.
+ App.API.ShowMsg("Failed to change Korean IME setting", "Please check your system registry access or contact support.");
}
}
}
From 22c0f59f202e993878ab2a0f884bb78b9a5ee75d Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 10 Apr 2025 22:06:44 +0900
Subject: [PATCH 0963/1335] Add badge area in xaml
---
Flow.Launcher/ResultListBox.xaml | 95 +++++++++++++++++---------------
1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index 4c3bd1d120f..59a16e10cd7 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -90,62 +90,69 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Date: Fri, 11 Apr 2025 06:43:38 +0900
Subject: [PATCH 0964/1335] Fix Fontcolor binding
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index ffa5eea4122..c18d5fa600e 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2785,6 +2785,7 @@
+
@@ -2872,7 +2873,7 @@
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
- Foreground="{DynamicResource Color05B}"
+ Foreground="{TemplateBinding Foreground}"
InputScope="{TemplateBinding InputScope}"
SelectionBrush="{TemplateBinding SelectionBrush}"
TextAlignment="{TemplateBinding TextAlignment}" />
From de21a43a81a36fd9fb1c5589c60c757dcce1d542 Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 07:23:21 +0900
Subject: [PATCH 0965/1335] Adjust Template
---
Flow.Launcher/Languages/en.xaml | 1 +
.../Resources/Controls/InstalledPluginDisplay.xaml | 5 ++++-
Flow.Launcher/Resources/CustomControlTemplate.xaml | 8 +++++---
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 609859d0dab..a7fbca90a73 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -109,6 +109,7 @@
Shadow effect is not allowed while current theme has blur effect enabled
Search Delay
Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
Wait time before showing results after typing stops. Higher values wait longer. (ms)
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 2310362443a..619da22dc64 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -96,8 +96,11 @@
PlaceholderText="{Binding DefaultSearchDelay}"
SmallChange="10"
SpinButtonPlacementMode="Compact"
- ToolTip="{DynamicResource searchDelayToolTip}"
+ ToolTip="{DynamicResource searchDelayNumberBoxToolTip}"
+ ToolTipService.InitialShowDelay="0"
+ ToolTipService.ShowOnDisabled="True"
Value="{Binding PluginSearchDelayTime, Mode=TwoWay}" />
+
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index c18d5fa600e..ae3cc80181e 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2784,10 +2784,12 @@
-
+
-
+
+
+
@@ -2873,7 +2875,7 @@
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
- Foreground="{TemplateBinding Foreground}"
+ Foreground="{DynamicResource ForeGround}"
InputScope="{TemplateBinding InputScope}"
SelectionBrush="{TemplateBinding SelectionBrush}"
TextAlignment="{TemplateBinding TextAlignment}" />
From dac66d0c39e410683cbafe1e01e5df8b479f7dda Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 07:27:16 +0900
Subject: [PATCH 0966/1335] Add removed tooltip
---
Flow.Launcher/Languages/en.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index a7fbca90a73..e53b75ae826 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -44,6 +44,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
+ Reset search window position
Type here to search
From d76b406c82d8f59937d5bf55b28559ffac9f5ef6 Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 09:15:30 +0900
Subject: [PATCH 0967/1335] Fix template binding
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index ae3cc80181e..de84e40d9b4 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2875,7 +2875,6 @@
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
- Foreground="{DynamicResource ForeGround}"
InputScope="{TemplateBinding InputScope}"
SelectionBrush="{TemplateBinding SelectionBrush}"
TextAlignment="{TemplateBinding TextAlignment}" />
From 96915d7e97c99809a7608ab6e9606e665a90bff2 Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 09:17:12 +0900
Subject: [PATCH 0968/1335] Fix Style
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index de84e40d9b4..5a6b9a2485e 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2804,7 +2804,7 @@
-
+
From 5e54416d3a40952f6c36fc8f5173c7bde4d7b096 Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 09:21:30 +0900
Subject: [PATCH 0969/1335] Remove Dulplicated setter
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index 5a6b9a2485e..1ff6ca49c17 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -1285,7 +1285,6 @@
BasedOn="{StaticResource DefaultComboBoxStyle}"
TargetType="ComboBox">
-
From c5f2868a9b620303525715edb971a56bd6c384c9 Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 09:25:45 +0900
Subject: [PATCH 0970/1335] Fix small warning
---
.../Converters/QuerySuggestionBoxConverter.cs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
index ed94771f04e..0d6f2e469aa 100644
--- a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
+++ b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
@@ -43,8 +44,16 @@ values[2] is not string queryText ||
// Check if Text will be larger than our QueryTextBox
Typeface typeface = new Typeface(queryTextBox.FontFamily, queryTextBox.FontStyle, queryTextBox.FontWeight, queryTextBox.FontStretch);
- // TODO: Obsolete warning?
- var ft = new FormattedText(queryTextBox.Text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, typeface, queryTextBox.FontSize, Brushes.Black);
+ var dpi = VisualTreeHelper.GetDpi(queryTextBox);
+ var ft = new FormattedText(
+ queryTextBox.Text,
+ CultureInfo.CurrentCulture,
+ FlowDirection.LeftToRight,
+ typeface,
+ queryTextBox.FontSize,
+ Brushes.Black,
+ dpi.PixelsPerDip
+ );
var offset = queryTextBox.Padding.Right;
From 2f1e009d704a2efefffe61828a3fb44341883dd7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 10:37:49 +0800
Subject: [PATCH 0971/1335] Remove blank lines
---
Flow.Launcher/ResultListBox.xaml | 2 --
Flow.Launcher/ViewModel/ResultViewModel.cs | 1 -
2 files changed, 3 deletions(-)
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index 59a16e10cd7..b57cb0d40f2 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -151,8 +151,6 @@
-
-
Date: Fri, 11 Apr 2025 11:08:28 +0800
Subject: [PATCH 0972/1335] Remove debug codes & Improve code quality
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 82 +++++++++++++
.../SettingsPaneGeneralViewModel.cs | 110 +++---------------
2 files changed, 95 insertions(+), 97 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index f9c548de863..815f31280eb 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows;
@@ -517,5 +518,86 @@ public static bool IsNotificationSupported()
}
#endregion
+
+ #region Korean IME
+
+ public static bool IsKoreanIMEExist()
+ {
+ return GetLegacyKoreanIMERegistryValue() != null;
+ }
+
+ public static bool IsLegacyKoreanIMEEnabled()
+ {
+ object value = GetLegacyKoreanIMERegistryValue();
+
+ if (value is int intValue)
+ {
+ return intValue == 1;
+ }
+ else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ {
+ return parsedValue == 1;
+ }
+
+ return false;
+ }
+
+ public static bool SetLegacyKoreanIMEEnabled(bool enable)
+ {
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
+ {
+ using RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath);
+ if (key != null)
+ {
+ int value = enable ? 1 : 0;
+ key.SetValue(valueName, value, RegistryValueKind.DWord);
+ return true;
+ }
+ }
+ catch (System.Exception)
+ {
+ // Ignored
+ }
+
+ return false;
+ }
+
+ public static object GetLegacyKoreanIMERegistryValue()
+ {
+ const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
+ const string valueName = "NoTsf3Override5";
+
+ try
+ {
+ using RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath);
+ if (key != null)
+ {
+ return key.GetValue(valueName);
+ }
+ }
+ catch (System.Exception)
+ {
+ // Ignored
+ }
+
+ return null;
+ }
+
+ public static void OpenImeSettings()
+ {
+ try
+ {
+ Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
+ }
+ catch (System.Exception)
+ {
+ // Ignored
+ }
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 33a7428dbbe..7eba1602f1e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -1,20 +1,16 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
+using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
-using Microsoft.Win32;
using OpenFileDialog = System.Windows.Forms.OpenFileDialog;
-using System.Windows.Input;
-
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -25,8 +21,6 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
private readonly IPortable _portable;
private readonly Internationalization _translater;
- public ICommand OpenImeSettingsCommand { get; }
-
public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable, Internationalization translater)
{
Settings = settings;
@@ -34,7 +28,6 @@ public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortabl
_portable = portable;
_translater = translater;
UpdateEnumDropdownLocalizations();
- OpenImeSettingsCommand = new RelayCommand(OpenImeSettings);
}
public class SearchWindowScreenData : DropdownDataGeneric { }
@@ -187,21 +180,22 @@ public string Language
UpdateEnumDropdownLocalizations();
}
}
-
+
+ #region Korean IME
+
// The new Korean IME used in Windows 11 has compatibility issues with WPF. This issue is difficult to resolve within
// WPF itself, but it can be avoided by having the user switch to the legacy IME at the system level. Therefore,
// we provide guidance and a direct button for users to make this change themselves. If the relevant registry key does
// not exist (i.e., the Korean IME is not installed), this setting will not be shown at all.
- #region Korean IME
+
public bool LegacyKoreanIMEEnabled
{
- get => IsLegacyKoreanIMEEnabled();
+ get => Win32Helper.IsLegacyKoreanIMEEnabled();
set
{
- Debug.WriteLine($"[DEBUG] LegacyKoreanIMEEnabled changed: {value}");
- if (SetLegacyKoreanIMEEnabled(value))
+ if (Win32Helper.SetLegacyKoreanIMEEnabled(value))
{
- OnPropertyChanged(nameof(LegacyKoreanIMEEnabled));
+ OnPropertyChanged();
OnPropertyChanged(nameof(KoreanIMERegistryValueIsZero));
}
else
@@ -212,13 +206,13 @@ public bool LegacyKoreanIMEEnabled
}
}
- public bool KoreanIMERegistryKeyExists => IsKoreanIMEExist();
+ public bool KoreanIMERegistryKeyExists => Win32Helper.IsKoreanIMEExist();
public bool KoreanIMERegistryValueIsZero
{
get
{
- object value = GetLegacyKoreanIMERegistryValue();
+ object value = Win32Helper.GetLegacyKoreanIMERegistryValue();
if (value is int intValue)
{
return intValue == 0;
@@ -232,90 +226,12 @@ public bool KoreanIMERegistryValueIsZero
}
}
- bool IsKoreanIMEExist()
- {
- return GetLegacyKoreanIMERegistryValue() != null;
- }
-
- bool IsLegacyKoreanIMEEnabled()
- {
- object value = GetLegacyKoreanIMERegistryValue();
-
- if (value is int intValue)
- {
- return intValue == 1;
- }
- else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
- {
- return parsedValue == 1;
- }
-
- return false;
- }
-
- bool SetLegacyKoreanIMEEnabled(bool enable)
- {
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
-
- try
- {
- using (RegistryKey key = Registry.CurrentUser.CreateSubKey(subKeyPath))
- {
- if (key != null)
- {
- int value = enable ? 1 : 0;
- key.SetValue(valueName, value, RegistryValueKind.DWord);
- return true;
- }
- else
- {
- Debug.WriteLine($"[IME DEBUG] Failed to create or open registry key: {subKeyPath}");
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] Exception occurred while setting registry: {ex.Message}");
- }
-
- return false;
- }
-
- private object GetLegacyKoreanIMERegistryValue()
- {
- const string subKeyPath = @"Software\Microsoft\input\tsf\tsf3override\{A028AE76-01B1-46C2-99C4-ACD9858AE02F}";
- const string valueName = "NoTsf3Override5";
-
- try
- {
- using (RegistryKey key = Registry.CurrentUser.OpenSubKey(subKeyPath))
- {
- if (key != null)
- {
- return key.GetValue(valueName);
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"[IME DEBUG] Exception occurred: {ex.Message}");
- }
-
- return null;
- }
-
+ [RelayCommand]
private void OpenImeSettings()
{
- try
- {
- Process.Start(new ProcessStartInfo("ms-settings:regionlanguage") { UseShellExecute = true });
- }
- catch (Exception e)
- {
- Debug.WriteLine($"Error opening IME settings: {e.Message}");
- }
+ Win32Helper.OpenImeSettings();
}
+
#endregion
public bool ShouldUsePinyin
From b14cf89d6878ee42cab2d5ef08249c6d186c8bb9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 11:11:58 +0800
Subject: [PATCH 0973/1335] Remove useless using
---
.../SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 7eba1602f1e..2697a508e53 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -10,7 +10,6 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
-using OpenFileDialog = System.Windows.Forms.OpenFileDialog;
namespace Flow.Launcher.SettingPages.ViewModels;
@@ -20,7 +19,7 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
private readonly Updater _updater;
private readonly IPortable _portable;
private readonly Internationalization _translater;
-
+
public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable, Internationalization translater)
{
Settings = settings;
From 1517db8326c3e42d876e78aa12aa2f5daf0f7cab Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 11:21:22 +0800
Subject: [PATCH 0974/1335] Revert wrong changes on en.xaml
---
Flow.Launcher/Languages/en.xaml | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index bf430b6f54f..0df77b127ec 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -110,12 +110,7 @@
Search Delay
Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
Information for Korean IME user
The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
@@ -393,9 +388,7 @@
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
Custom Query Hotkey
From c5f2fcaddf11858b9c1ba111375cc0ec9ec63141 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 11:22:27 +0800
Subject: [PATCH 0975/1335] Revert wrong changes on en.xaml
---
Flow.Launcher/Languages/en.xaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 0df77b127ec..f1c0a67cbe6 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -161,7 +161,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Plugin Store
From 218635a035558b0562b009ae9cbd7605d27e823a Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 12:56:31 +0900
Subject: [PATCH 0976/1335] Add logic to check whether the Korean IME is in use
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 4 ++++
.../ViewModels/SettingsPaneGeneralViewModel.cs | 14 +++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 815f31280eb..2df632545f3 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -21,6 +21,10 @@ public static class Win32Helper
{
#region Blur Handling
+ public static bool IsWindows11()
+ {
+ return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= 22000;
+ }
public static bool IsBackdropSupported()
{
// Mica and Acrylic only supported Windows 11 22000+
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 2697a508e53..13ae6589495 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
@@ -205,7 +206,18 @@ public bool LegacyKoreanIMEEnabled
}
}
- public bool KoreanIMERegistryKeyExists => Win32Helper.IsKoreanIMEExist();
+ public bool KoreanIMERegistryKeyExists
+ {
+ get
+ {
+ bool registryKeyExists = Win32Helper.IsKoreanIMEExist();
+ bool koreanLanguageInstalled = InputLanguage.InstalledInputLanguages.Cast().Any(lang => lang.Culture.Name.StartsWith("ko"));
+ bool isWindows11 = Win32Helper.IsWindows11();
+
+ // Return true if Windows 11 with Korean IME installed, or if the registry key exists
+ return (isWindows11 && koreanLanguageInstalled) || registryKeyExists;
+ }
+ }
public bool KoreanIMERegistryValueIsZero
{
From b842f08b5147de1cc504f723df3a870064801bbd Mon Sep 17 00:00:00 2001
From: DB p
Date: Fri, 11 Apr 2025 13:23:17 +0900
Subject: [PATCH 0977/1335] Add logic to block space key input when registering
an action keyword for plugins that do not support multiple action keywords.
---
.../Views/ActionKeywordSetting.xaml | 1 +
.../Views/ActionKeywordSetting.xaml.cs | 21 +++++++++++
.../SearchSourceSetting.xaml | 36 ++++++++++---------
.../SearchSourceSetting.xaml.cs | 26 ++++++++++++++
4 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
index d4250534860..37a7ccb8d5b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
@@ -80,6 +80,7 @@
Width="135"
HorizontalAlignment="Left"
VerticalAlignment="Center"
+ DataObject.Pasting="TextBox_Pasting"
PreviewKeyDown="TxtCurrentActionKeyword_OnKeyDown"
Text="{Binding ActionKeyword}" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index 73c35b1c845..b928a981562 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
@@ -93,7 +94,27 @@ private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
OnDoneButtonClick(sender, e);
e.Handled = true;
}
+ if (e.Key == Key.Space)
+ {
+ e.Handled = true;
+ }
+ }
+ private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
+ {
+ if (e.DataObject.GetDataPresent(DataFormats.Text))
+ {
+ string text = e.DataObject.GetData(DataFormats.Text) as string;
+ if (!string.IsNullOrEmpty(text) && text.Any(char.IsWhiteSpace))
+ {
+ e.CancelCommand();
+ }
+ }
+ else
+ {
+ e.CancelCommand();
+ }
}
+
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml
index 3df50b3edc8..746c9cf848f 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml
@@ -56,13 +56,13 @@
-
+
-
+
@@ -139,13 +139,13 @@
Name="imgPreviewIcon"
Width="24"
Height="24"
- Margin="14,0,0,0"
+ Margin="14 0 0 0"
VerticalAlignment="Center" />
@@ -196,16 +198,16 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
- BorderThickness="0,1,0,0">
+ BorderThickness="0 1 0 0">
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index 58577dbc18a..0a1bdf6a25f 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -1,5 +1,7 @@
using System.Collections.Generic;
+using System.Linq;
using System.Windows;
+using System.Windows.Input;
using Microsoft.Win32;
namespace Flow.Launcher.Plugin.WebSearch
@@ -143,6 +145,30 @@ private async void OnSelectIconClick(object sender, RoutedEventArgs e)
}
}
}
+
+ //Block Space Input
+ private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Space)
+ {
+ e.Handled = true;
+ }
+ }
+ private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
+ {
+ if (e.DataObject.GetDataPresent(DataFormats.Text))
+ {
+ string text = e.DataObject.GetData(DataFormats.Text) as string;
+ if (!string.IsNullOrEmpty(text) && text.Any(char.IsWhiteSpace))
+ {
+ e.CancelCommand();
+ }
+ }
+ else
+ {
+ e.CancelCommand();
+ }
+ }
}
public enum Action
From a6c7430094f86dd369971adade4fc7afbf383358 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 12:36:19 +0800
Subject: [PATCH 0978/1335] Code quality
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 10 ++++++----
.../ViewModels/SettingsPaneGeneralViewModel.cs | 10 +++++-----
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 2df632545f3..54604a27118 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -21,10 +21,6 @@ public static class Win32Helper
{
#region Blur Handling
- public static bool IsWindows11()
- {
- return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= 22000;
- }
public static bool IsBackdropSupported()
{
// Mica and Acrylic only supported Windows 11 22000+
@@ -525,6 +521,12 @@ public static bool IsNotificationSupported()
#region Korean IME
+ public static bool IsWindows11()
+ {
+ return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+ Environment.OSVersion.Version.Build >= 22000;
+ }
+
public static bool IsKoreanIMEExist()
{
return GetLegacyKoreanIMERegistryValue() != null;
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 13ae6589495..021c9d7fe61 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -210,9 +210,9 @@ public bool KoreanIMERegistryKeyExists
{
get
{
- bool registryKeyExists = Win32Helper.IsKoreanIMEExist();
- bool koreanLanguageInstalled = InputLanguage.InstalledInputLanguages.Cast().Any(lang => lang.Culture.Name.StartsWith("ko"));
- bool isWindows11 = Win32Helper.IsWindows11();
+ var registryKeyExists = Win32Helper.IsKoreanIMEExist();
+ var koreanLanguageInstalled = InputLanguage.InstalledInputLanguages.Cast().Any(lang => lang.Culture.Name.StartsWith("ko"));
+ var isWindows11 = Win32Helper.IsWindows11();
// Return true if Windows 11 with Korean IME installed, or if the registry key exists
return (isWindows11 && koreanLanguageInstalled) || registryKeyExists;
@@ -223,12 +223,12 @@ public bool KoreanIMERegistryValueIsZero
{
get
{
- object value = Win32Helper.GetLegacyKoreanIMERegistryValue();
+ var value = Win32Helper.GetLegacyKoreanIMERegistryValue();
if (value is int intValue)
{
return intValue == 0;
}
- else if (value != null && int.TryParse(value.ToString(), out int parsedValue))
+ else if (value != null && int.TryParse(value.ToString(), out var parsedValue))
{
return parsedValue == 0;
}
From 71923194b61abd1aaec2df4b8e1275581078096f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 12:38:48 +0800
Subject: [PATCH 0979/1335] Change IME settings icon
---
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index 5304824fed5..4782d356ef3 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -341,7 +341,7 @@
From e29bf745149d7dc9178562fdec8e222cc9271b46 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 12:50:00 +0800
Subject: [PATCH 0980/1335] Fix explorer settings panel margin
---
.../Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 1bdb9d36a89..6ca7be84db6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -598,7 +598,7 @@
From 3e20c518a0d6c45af027f8387dcb21c782466bdf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 14:51:25 +0800
Subject: [PATCH 0981/1335] Code quality
---
Flow.Launcher/ViewModel/ResultsViewModel.cs | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 61566b41571..02fb379fa07 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -19,7 +19,7 @@ public class ResultsViewModel : BaseModel
public ResultCollection Results { get; }
- private readonly object _collectionLock = new object();
+ private readonly object _collectionLock = new();
private readonly Settings _settings;
private int MaxResults => _settings?.MaxResultsToShow ?? 6;
@@ -89,7 +89,7 @@ public double ItemHeightSize
#region Private Methods
- private int InsertIndexOf(int newScore, IList list)
+ private static int InsertIndexOf(int newScore, IList list)
{
int index = 0;
for (; index < list.Count; index++)
@@ -118,7 +118,6 @@ private int NewIndex(int i)
}
}
-
#endregion
#region Public Methods
@@ -190,10 +189,10 @@ public void AddResults(ICollection resultsForUpdates, Cancella
if (token.IsCancellationRequested)
return;
- UpdateResults(newResults, token, reselect);
+ UpdateResults(newResults, reselect, token);
}
- private void UpdateResults(List newResults, CancellationToken token = default, bool reselect = true)
+ private void UpdateResults(List newResults, bool reselect = true, CancellationToken token = default)
{
lock (_collectionLock)
{
From 47398f104f316675f4193af1ff6df1865f587047 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 14:58:47 +0800
Subject: [PATCH 0982/1335] Add ShowPluginBadges settings
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 +
Flow.Launcher/ResultListBox.xaml | 2 +-
Flow.Launcher/ViewModel/ResultViewModel.cs | 5 +++++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index e304a1b5040..b48f047c5ee 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -101,6 +101,7 @@ public string Theme
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
public double SoundVolume { get; set; } = 50;
+ public bool ShowPluginBadges { get; set; } = false;
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index b57cb0d40f2..03bff03eb7d 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -146,7 +146,7 @@
VerticalAlignment="Bottom"
RenderOptions.BitmapScalingMode="Fant"
Source="{Binding Image, TargetNullValue={x:Null}}"
- Visibility="{Binding ShowBadge, Converter={StaticResource BoolToVisibilityConverter}}" />
+ Visibility="{Binding ShowBadge}" />
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index 0975398dc2e..41e5dd12e23 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -123,6 +123,11 @@ public Visibility ShowGlyph
}
}
+ public Visibility ShowBadge
+ {
+ get => Settings.ShowPluginBadges ? Visibility.Visible : Visibility.Collapsed;
+ }
+
private bool GlyphAvailable => Glyph is not null;
private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null;
From 579dc061718ac2b151d8b9cf1523fd4c93e0b03f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:00:46 +0800
Subject: [PATCH 0983/1335] Code quality
---
Flow.Launcher.Plugin/Result.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 9104854389d..2e4befdc209 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -60,7 +60,7 @@ public string CopyText
/// GlyphInfo is prioritized if not null
public string IcoPath
{
- get { return _icoPath; }
+ get => _icoPath;
set
{
// As a standard this property will handle prepping and converting to absolute local path for icon image processing
@@ -101,7 +101,6 @@ public string IcoPath
///
public GlyphInfo Glyph { get; init; }
-
///
/// An action to take in the form of a function call when the result has been selected.
///
@@ -143,7 +142,7 @@ public string IcoPath
///
public string PluginDirectory
{
- get { return _pluginDirectory; }
+ get => _pluginDirectory;
set
{
_pluginDirectory = value;
From 471c3edc6fc679ebfb5b72f5be9ed418c3575bba Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:21:11 +0800
Subject: [PATCH 0984/1335] Add BadgePath & BadgeIcon property
---
Flow.Launcher.Plugin/Result.cs | 150 ++++++++++++++---------
Flow.Launcher/ViewModel/MainViewModel.cs | 11 +-
2 files changed, 102 insertions(+), 59 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 2e4befdc209..7e520175e7e 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -12,12 +12,19 @@ namespace Flow.Launcher.Plugin
///
public class Result
{
+ ///
+ /// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users.
+ ///
+ public const int MaxScore = int.MaxValue;
+
private string _pluginDirectory;
private string _icoPath;
private string _copyText = string.Empty;
+ private string _badgePath;
+
///
/// The title of the result. This is always required.
///
@@ -80,6 +87,33 @@ public string IcoPath
}
}
+ ///
+ /// The image to be displayed for the badge of the result.
+ ///
+ /// Can be a local file path or a URL.
+ /// If null or empty, will use plugin icon
+ public string BadgePath
+ {
+ get => _badgePath;
+ set
+ {
+ // As a standard this property will handle prepping and converting to absolute local path for icon image processing
+ if (!string.IsNullOrEmpty(value)
+ && !string.IsNullOrEmpty(PluginDirectory)
+ && !Path.IsPathRooted(value)
+ && !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
+ && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
+ && !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase))
+ {
+ _badgePath = Path.Combine(PluginDirectory, value);
+ }
+ else
+ {
+ _badgePath = value;
+ }
+ }
+ }
+
///
/// Determines if Icon has a border radius
///
@@ -94,7 +128,12 @@ public string IcoPath
///
/// Delegate to load an icon for this result.
///
- public IconDelegate Icon;
+ public IconDelegate Icon { get; set; }
+
+ ///
+ /// Delegate to load an icon for the badge of this result.
+ ///
+ public IconDelegate BadgeIcon { get; set; }
///
/// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons)
@@ -154,47 +193,6 @@ public string PluginDirectory
}
}
- ///
- public override string ToString()
- {
- return Title + SubTitle + Score;
- }
-
- ///
- /// Clones the current result
- ///
- public Result Clone()
- {
- return new Result
- {
- Title = Title,
- SubTitle = SubTitle,
- ActionKeywordAssigned = ActionKeywordAssigned,
- CopyText = CopyText,
- AutoCompleteText = AutoCompleteText,
- IcoPath = IcoPath,
- RoundedIcon = RoundedIcon,
- Icon = Icon,
- Glyph = Glyph,
- Action = Action,
- AsyncAction = AsyncAction,
- Score = Score,
- TitleHighlightData = TitleHighlightData,
- OriginQuery = OriginQuery,
- PluginDirectory = PluginDirectory,
- ContextData = ContextData,
- PluginID = PluginID,
- TitleToolTip = TitleToolTip,
- SubTitleToolTip = SubTitleToolTip,
- PreviewPanel = PreviewPanel,
- ProgressBar = ProgressBar,
- ProgressBarColor = ProgressBarColor,
- Preview = Preview,
- AddSelectedCount = AddSelectedCount,
- RecordKey = RecordKey
- };
- }
-
///
/// Additional data associated with this result
///
@@ -223,16 +221,6 @@ public Result Clone()
///
public Lazy PreviewPanel { get; set; }
- ///
- /// Run this result, asynchronously
- ///
- ///
- ///
- public ValueTask ExecuteAsync(ActionContext context)
- {
- return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
- }
-
///
/// Progress bar display. Providing an int value between 0-100 will trigger the progress bar to be displayed on the result
///
@@ -254,11 +242,6 @@ public ValueTask ExecuteAsync(ActionContext context)
///
public bool AddSelectedCount { get; set; } = true;
- ///
- /// Maximum score. This can be useful when set one result to the top by default. This is the score for the results set to the topmost by users.
- ///
- public const int MaxScore = int.MaxValue;
-
///
/// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records.
/// This can be useful when your plugin will change the Title or SubTitle of the result dynamically.
@@ -267,6 +250,59 @@ public ValueTask ExecuteAsync(ActionContext context)
///
public string RecordKey { get; set; } = null;
+ ///
+ /// Run this result, asynchronously
+ ///
+ ///
+ ///
+ public ValueTask ExecuteAsync(ActionContext context)
+ {
+ return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false);
+ }
+
+ ///
+ public override string ToString()
+ {
+ return Title + SubTitle + Score;
+ }
+
+ ///
+ /// Clones the current result
+ ///
+ public Result Clone()
+ {
+ return new Result
+ {
+ Title = Title,
+ SubTitle = SubTitle,
+ ActionKeywordAssigned = ActionKeywordAssigned,
+ CopyText = CopyText,
+ AutoCompleteText = AutoCompleteText,
+ IcoPath = IcoPath,
+ BadgePath = BadgePath,
+ RoundedIcon = RoundedIcon,
+ Icon = Icon,
+ BadgeIcon = BadgeIcon,
+ Glyph = Glyph,
+ Action = Action,
+ AsyncAction = AsyncAction,
+ Score = Score,
+ TitleHighlightData = TitleHighlightData,
+ OriginQuery = OriginQuery,
+ PluginDirectory = PluginDirectory,
+ ContextData = ContextData,
+ PluginID = PluginID,
+ TitleToolTip = TitleToolTip,
+ SubTitleToolTip = SubTitleToolTip,
+ PreviewPanel = PreviewPanel,
+ ProgressBar = ProgressBar,
+ ProgressBarColor = ProgressBarColor,
+ Preview = Preview,
+ AddSelectedCount = AddSelectedCount,
+ RecordKey = RecordKey
+ };
+ }
+
///
/// Info of the preview section of a
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 4a6c1d63971..38efca72b74 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,8 +1268,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
// Task.Yield will force it to run in ThreadPool
await Task.Yield();
- IReadOnlyList results =
- await PluginManager.QueryForPluginAsync(plugin, query, token);
+ var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
if (token.IsCancellationRequested)
return;
@@ -1285,6 +1284,14 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
resultsCopy = DeepCloneResults(results, token);
}
+ foreach (var result in results)
+ {
+ if (string.IsNullOrEmpty(result.BadgePath))
+ {
+ result.BadgePath = plugin.Metadata.IcoPath;
+ }
+ }
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect)))
{
From b85c2f48f9a3233991671971b9207996582b177d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:35:36 +0800
Subject: [PATCH 0985/1335] Add related settings in appreance page
---
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher/Languages/en.xaml | 2 ++
.../SettingPages/Views/SettingsPaneTheme.xaml | 16 ++++++++++++++--
Flow.Launcher/ViewModel/ResultViewModel.cs | 2 +-
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index b48f047c5ee..d97a9ed1aee 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -101,7 +101,7 @@ public string Theme
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
public double SoundVolume { get; set; } = 50;
- public bool ShowPluginBadges { get; set; } = false;
+ public bool ShowBadges { get; set; } = false;
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 609859d0dab..66721d8288d 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -283,6 +283,8 @@
Use Segoe Fluent Icons
Use Segoe Fluent Icons for query results where supported
Press Key
+ Show Result Badges
+ Show badges for query results where supported
HTTP Proxy
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 49306cd2df1..574002a0525 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -698,11 +698,10 @@
-
+
+
+
+
+
+
Settings.ShowPluginBadges ? Visibility.Visible : Visibility.Collapsed;
+ get => Settings.ShowBadges ? Visibility.Visible : Visibility.Collapsed;
}
private bool GlyphAvailable => Glyph is not null;
From 9e3e0f6e3c561b1106e63e0439162ec3df33a60f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:38:00 +0800
Subject: [PATCH 0986/1335] Change name to BadgeIcoPath
---
Flow.Launcher.Plugin/Result.cs | 12 ++++++------
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 7e520175e7e..70d11dadd93 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -23,7 +23,7 @@ public class Result
private string _copyText = string.Empty;
- private string _badgePath;
+ private string _badgeIcoPath;
///
/// The title of the result. This is always required.
@@ -92,9 +92,9 @@ public string IcoPath
///
/// Can be a local file path or a URL.
/// If null or empty, will use plugin icon
- public string BadgePath
+ public string BadgeIcoPath
{
- get => _badgePath;
+ get => _badgeIcoPath;
set
{
// As a standard this property will handle prepping and converting to absolute local path for icon image processing
@@ -105,11 +105,11 @@ public string BadgePath
&& !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
&& !value.StartsWith("data:image", StringComparison.OrdinalIgnoreCase))
{
- _badgePath = Path.Combine(PluginDirectory, value);
+ _badgeIcoPath = Path.Combine(PluginDirectory, value);
}
else
{
- _badgePath = value;
+ _badgeIcoPath = value;
}
}
}
@@ -279,7 +279,7 @@ public Result Clone()
CopyText = CopyText,
AutoCompleteText = AutoCompleteText,
IcoPath = IcoPath,
- BadgePath = BadgePath,
+ BadgeIcoPath = BadgeIcoPath,
RoundedIcon = RoundedIcon,
Icon = Icon,
BadgeIcon = BadgeIcon,
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 38efca72b74..0abd14ec5e6 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1286,9 +1286,9 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
foreach (var result in results)
{
- if (string.IsNullOrEmpty(result.BadgePath))
+ if (string.IsNullOrEmpty(result.BadgeIcoPath))
{
- result.BadgePath = plugin.Metadata.IcoPath;
+ result.BadgeIcoPath = plugin.Metadata.IcoPath;
}
}
From d338c5551d9cf136fffcf74e269f3446215a09e4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:47:41 +0800
Subject: [PATCH 0987/1335] Fix badge icon url issue
---
Flow.Launcher.Plugin/Result.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 70d11dadd93..ac00d5af5ec 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -188,8 +188,9 @@ public string PluginDirectory
// When the Result object is returned from the query call, PluginDirectory is not provided until
// UpdatePluginMetadata call is made at PluginManager.cs L196. Once the PluginDirectory becomes available
- // we need to update (only if not Uri path) the IcoPath with the full absolute path so the image can be loaded.
+ // we need to update (only if not Uri path) the IcoPath and BadgeIcoPath with the full absolute path so the image can be loaded.
IcoPath = _icoPath;
+ BadgeIcoPath = _badgeIcoPath;
}
}
From a1ce6b348dbc679bed986de05447e8fb86d7e21b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:48:49 +0800
Subject: [PATCH 0988/1335] Fix result badge ico path update issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 0abd14ec5e6..c1a237c6ad9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1284,7 +1284,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
resultsCopy = DeepCloneResults(results, token);
}
- foreach (var result in results)
+ foreach (var result in resultsCopy)
{
if (string.IsNullOrEmpty(result.BadgeIcoPath))
{
From ec99a365b9d27a708464b4506a41d55259c15961 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:49:39 +0800
Subject: [PATCH 0989/1335] Support badge path for result update interface
---
Flow.Launcher/ViewModel/MainViewModel.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index c1a237c6ad9..2155f7bf83c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -245,6 +245,14 @@ public void RegisterResultsUpdatedEvent()
// make a clone to avoid possible issue that plugin will also change the list and items when updating view model
var resultsCopy = DeepCloneResults(e.Results, token);
+ foreach (var result in resultsCopy)
+ {
+ if (string.IsNullOrEmpty(result.BadgeIcoPath))
+ {
+ result.BadgeIcoPath = pair.Metadata.IcoPath;
+ }
+ }
+
PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query);
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
token)))
From 2eda64aa7af74dad5f3cf21fda8e8a8e6230fe64 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 15:51:26 +0800
Subject: [PATCH 0990/1335] Support badge icon loading
---
Flow.Launcher/ResultListBox.xaml | 2 +-
Flow.Launcher/ViewModel/ResultViewModel.cs | 46 ++++++++++++++++++++--
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index 03bff03eb7d..63c461c43ea 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -145,7 +145,7 @@
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
RenderOptions.BitmapScalingMode="Fant"
- Source="{Binding Image, TargetNullValue={x:Null}}"
+ Source="{Binding BadgeImage, TargetNullValue={x:Null}}"
Visibility="{Binding ShowBadge}" />
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index 61e228de1bc..4137d5f58ed 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -125,13 +125,21 @@ public Visibility ShowGlyph
public Visibility ShowBadge
{
- get => Settings.ShowBadges ? Visibility.Visible : Visibility.Collapsed;
+ get
+ {
+ if (Settings.ShowBadges && BadgeIconAvailable)
+ return Visibility.Visible;
+
+ return Visibility.Collapsed;
+ }
}
private bool GlyphAvailable => Glyph is not null;
private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null;
+ private bool BadgeIconAvailable => !string.IsNullOrEmpty(Result.BadgeIcoPath) || Result.BadgeIcon is not null;
+
private bool PreviewImageAvailable => !string.IsNullOrEmpty(Result.Preview.PreviewImagePath) || Result.Preview.PreviewDelegate != null;
public string OpenResultModifiers => Settings.OpenResultModifiers;
@@ -145,9 +153,11 @@ public Visibility ShowBadge
: Result.SubTitleToolTip;
private volatile bool _imageLoaded;
+ private volatile bool _badgeImageLoaded;
private volatile bool _previewImageLoaded;
private ImageSource _image = ImageLoader.LoadingImage;
+ private ImageSource _badgeImage = ImageLoader.LoadingImage;
private ImageSource _previewImage = ImageLoader.LoadingImage;
public ImageSource Image
@@ -165,6 +175,21 @@ public ImageSource Image
private set => _image = value;
}
+ public ImageSource BadgeImage
+ {
+ get
+ {
+ if (!_badgeImageLoaded)
+ {
+ _badgeImageLoaded = true;
+ _ = LoadBadgeImageAsync();
+ }
+
+ return _badgeImage;
+ }
+ private set => _badgeImage = value;
+ }
+
public ImageSource PreviewImage
{
get
@@ -210,7 +235,7 @@ private async Task LoadImageAsync()
{
var imagePath = Result.IcoPath;
var iconDelegate = Result.Icon;
- if (ImageLoader.TryGetValue(imagePath, false, out ImageSource img))
+ if (ImageLoader.TryGetValue(imagePath, false, out var img))
{
_image = img;
}
@@ -221,11 +246,26 @@ private async Task LoadImageAsync()
}
}
+ private async Task LoadBadgeImageAsync()
+ {
+ var badgeImagePath = Result.BadgeIcoPath;
+ var badgeIconDelegate = Result.BadgeIcon;
+ if (ImageLoader.TryGetValue(badgeImagePath, false, out var img))
+ {
+ _badgeImage = img;
+ }
+ else
+ {
+ // We need to modify the property not field here to trigger the OnPropertyChanged event
+ BadgeImage = await LoadImageInternalAsync(badgeImagePath, badgeIconDelegate, false).ConfigureAwait(false);
+ }
+ }
+
private async Task LoadPreviewImageAsync()
{
var imagePath = Result.Preview.PreviewImagePath ?? Result.IcoPath;
var iconDelegate = Result.Preview.PreviewDelegate ?? Result.Icon;
- if (ImageLoader.TryGetValue(imagePath, true, out ImageSource img))
+ if (ImageLoader.TryGetValue(imagePath, true, out var img))
{
_previewImage = img;
}
From 01f896a57844184fb24e883fe5939c9689d96403 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 16:11:39 +0800
Subject: [PATCH 0991/1335] Support global query only
---
.../UserSettings/Settings.cs | 1 +
Flow.Launcher/Languages/en.xaml | 2 ++
.../SettingPages/Views/SettingsPaneTheme.xaml | 23 ++++++++++++++-----
Flow.Launcher/ViewModel/ResultViewModel.cs | 11 ++++++---
4 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index d97a9ed1aee..7c2457a72c7 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -102,6 +102,7 @@ public string Theme
public bool UseSound { get; set; } = true;
public double SoundVolume { get; set; } = 50;
public bool ShowBadges { get; set; } = false;
+ public bool ShowBadgesGlobalOnly { get; set; } = false;
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 66721d8288d..87db45fbe1b 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -285,6 +285,8 @@
Press Key
Show Result Badges
Show badges for query results where supported
+ Show Result Badges Only for Global Query
+ Show badges only for global query results
HTTP Proxy
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 574002a0525..57c9a5b70dc 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -711,16 +711,27 @@
-
-
-
+
+
+
+
+
+
+
Result.OriginQuery.ActionKeyword == Query.GlobalPluginWildcardSign;
+
private bool GlyphAvailable => Glyph is not null;
private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null;
From e6477e886b3e3589727fa8481dd92a98a6206df4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 16:13:55 +0800
Subject: [PATCH 0992/1335] Fix global query determination issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 6 +++---
Flow.Launcher/ViewModel/ResultViewModel.cs | 3 ++-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2155f7bf83c..f6b9aa67c94 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1208,11 +1208,11 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
_lastQuery = query;
- if (query.ActionKeyword == Plugin.Query.GlobalPluginWildcardSign)
+ if (string.IsNullOrEmpty(query.ActionKeyword))
{
- // Wait 45 millisecond for query change in global query
+ // Wait 15 millisecond for query change in global query
// if query changes, return so that it won't be calculated
- await Task.Delay(45, _updateSource.Token);
+ await Task.Delay(15, _updateSource.Token);
if (_updateSource.Token.IsCancellationRequested)
return;
}
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index 27b385805c7..68c794aec30 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Drawing.Text;
using System.IO;
@@ -137,7 +138,7 @@ public Visibility ShowBadge
}
}
- public bool IsGlobalQuery => Result.OriginQuery.ActionKeyword == Query.GlobalPluginWildcardSign;
+ public bool IsGlobalQuery => string.IsNullOrEmpty(Result.OriginQuery.ActionKeyword);
private bool GlyphAvailable => Glyph is not null;
From 8aff3c9f2ae49358d59760675c4ab552da865ad4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 16:14:23 +0800
Subject: [PATCH 0993/1335] Improve strings
---
Flow.Launcher/Languages/en.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 87db45fbe1b..024258f1bbc 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -285,8 +285,8 @@
Press Key
Show Result Badges
Show badges for query results where supported
- Show Result Badges Only for Global Query
- Show badges only for global query results
+ Show Result Badges for Global Query Only
+ Show badges for global query results only
HTTP Proxy
From c1893366982d2f7d729a0cbdca6363c1d5b1218c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 16:46:45 +0800
Subject: [PATCH 0994/1335] Fix possible directory not found issue when saving
storage
---
Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 3 ++-
Flow.Launcher.Infrastructure/Storage/JsonStorage.cs | 8 +++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 43bb8dadecb..414743d22c9 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -82,8 +82,8 @@ private static async ValueTask DeserializeAsync(Stream stream, T defaultData)
public void Save()
{
+ FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it
var serialized = MemoryPackSerializer.Serialize(Data);
-
File.WriteAllBytes(FilePath, serialized);
}
@@ -103,6 +103,7 @@ public void ClearData()
// so we need to pass it to SaveAsync
public async ValueTask SaveAsync(T data)
{
+ FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it
await using var stream = new FileStream(FilePath, FileMode.Create);
await MemoryPackSerializer.SerializeAsync(stream, data);
}
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index cdf3ae90962..f283be59e18 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -183,7 +183,10 @@ private void BackupOriginFile()
public void Save()
{
- string serialized = JsonSerializer.Serialize(Data,
+ // User may delete the directory, so we need to check it
+ FilesFolders.ValidateDirectory(DirectoryPath);
+
+ var serialized = JsonSerializer.Serialize(Data,
new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(TempFilePath, serialized);
@@ -193,6 +196,9 @@ public void Save()
public async Task SaveAsync()
{
+ // User may delete the directory, so we need to check it
+ FilesFolders.ValidateDirectory(DirectoryPath);
+
await using var tempOutput = File.OpenWrite(TempFilePath);
await JsonSerializer.SerializeAsync(tempOutput, Data,
new JsonSerializerOptions { WriteIndented = true });
From 5c43dd45b236c6074f63dc314f0d3668c1653e09 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 16:48:02 +0800
Subject: [PATCH 0995/1335] Code quality
---
Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 414743d22c9..b85111756f5 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -82,7 +82,9 @@ private static async ValueTask DeserializeAsync(Stream stream, T defaultData)
public void Save()
{
- FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it
+ // User may delete the directory, so we need to check it
+ FilesFolders.ValidateDirectory(DirectoryPath);
+
var serialized = MemoryPackSerializer.Serialize(Data);
File.WriteAllBytes(FilePath, serialized);
}
@@ -103,7 +105,9 @@ public void ClearData()
// so we need to pass it to SaveAsync
public async ValueTask SaveAsync(T data)
{
- FilesFolders.ValidateDirectory(DirectoryPath); // User may delete the directory, so we need to check it
+ // User may delete the directory, so we need to check it
+ FilesFolders.ValidateDirectory(DirectoryPath);
+
await using var stream = new FileStream(FilePath, FileMode.Create);
await MemoryPackSerializer.SerializeAsync(stream, data);
}
From e6377d046348058c1b32cb2905960747468a5101 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 18:40:03 +0800
Subject: [PATCH 0996/1335] Fix old Program plugin constructor issue
---
.../Storage/BinaryStorage.cs | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index b85111756f5..64f80918199 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -40,6 +41,16 @@ public BinaryStorage(string filename)
FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}");
}
+ // Let the old Program plugin get this constructor
+ [Obsolete("This constructor is obsolete. Use BinaryStorage(string filename) instead.")]
+ public BinaryStorage(string filename, string directoryPath = null!)
+ {
+ directoryPath ??= DataLocation.CacheDirectory;
+ FilesFolders.ValidateDirectory(directoryPath);
+
+ FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
+ }
+
public async ValueTask TryLoadAsync(T defaultData)
{
if (Data != null) return Data;
From 3aa324d1201a79f7bdb05e21b22775fa85195b6f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 21:52:51 +0800
Subject: [PATCH 0997/1335] Throw plugin exception for plugin save interface
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 29d91dc8d28..94519bf6fdc 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -64,7 +64,14 @@ public static void Save()
foreach (var plugin in AllPlugins)
{
var savable = plugin.Plugin as ISavable;
- savable?.Save();
+ try
+ {
+ savable?.Save();
+ }
+ catch (Exception e)
+ {
+ throw new FlowPluginException(plugin.Metadata, e);
+ }
}
API.SavePluginSettings();
From bae0fa5c0e128538caf71943407088125289085b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 22:00:36 +0800
Subject: [PATCH 0998/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 8 ++++----
.../Resource/Internationalization.cs | 17 ++++++++---------
Flow.Launcher/PublicAPIInstance.cs | 14 ++++++++------
3 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 94519bf6fdc..1d13dcfd3d0 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -37,7 +37,7 @@ public static class PluginManager
private static PluginsSettings Settings;
private static List _metadatas;
- private static List _modifiedPlugins = new();
+ private static readonly List _modifiedPlugins = new();
///
/// Directories that will hold Flow Launcher plugin directory
@@ -299,7 +299,7 @@ public static async Task> QueryForPluginAsync(PluginPair pair, Quer
{
Title = $"{metadata.Name}: Failed to respond!",
SubTitle = "Select this result for more info",
- IcoPath = Flow.Launcher.Infrastructure.Constant.ErrorIcon,
+ IcoPath = Constant.ErrorIcon,
PluginDirectory = metadata.PluginDirectory,
ActionKeywordAssigned = query.ActionKeyword,
PluginID = metadata.ID,
@@ -376,8 +376,8 @@ public static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
// hence the actionKeyword != Query.GlobalPluginWildcardSign logic
- return actionKeyword != Query.GlobalPluginWildcardSign
- && NonGlobalPlugins.ContainsKey(actionKeyword);
+ return actionKeyword != Query.GlobalPluginWildcardSign
+ && NonGlobalPlugins.ContainsKey(actionKeyword);
}
///
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index ffa17ab4d5f..df841dbbe0e 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -22,8 +22,8 @@ public class Internationalization
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
private readonly Settings _settings;
- private readonly List _languageDirectories = new List();
- private readonly List _oldResources = new List();
+ private readonly List _languageDirectories = new();
+ private readonly List _oldResources = new();
private readonly string SystemLanguageCode;
public Internationalization(Settings settings)
@@ -144,7 +144,7 @@ public void ChangeLanguage(string languageCode)
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
}
- private Language GetLanguageByLanguageCode(string languageCode)
+ private static Language GetLanguageByLanguageCode(string languageCode)
{
var lowercase = languageCode.ToLower();
var language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == lowercase);
@@ -239,7 +239,7 @@ public List LoadAvailableLanguages()
return list;
}
- public string GetTranslation(string key)
+ public static string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
if (translation is string)
@@ -257,8 +257,7 @@ private void UpdatePluginMetadataTranslations()
{
foreach (var p in PluginManager.GetPluginsForInterface())
{
- var pluginI18N = p.Plugin as IPluginI18n;
- if (pluginI18N == null) return;
+ if (p.Plugin is not IPluginI18n pluginI18N) return;
try
{
p.Metadata.Name = pluginI18N.GetTranslatedPluginTitle();
@@ -272,11 +271,11 @@ private void UpdatePluginMetadataTranslations()
}
}
- public string LanguageFile(string folder, string language)
+ private static string LanguageFile(string folder, string language)
{
if (Directory.Exists(folder))
{
- string path = Path.Combine(folder, language);
+ var path = Path.Combine(folder, language);
if (File.Exists(path))
{
return path;
@@ -284,7 +283,7 @@ public string LanguageFile(string folder, string language)
else
{
Log.Error($"|Internationalization.LanguageFile|Language path can't be found <{path}>");
- string english = Path.Combine(folder, DefaultFile);
+ var english = Path.Combine(folder, DefaultFile);
if (File.Exists(english))
{
return english;
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 95ef6c9f3bd..5438eac7dac 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -38,20 +38,23 @@ namespace Flow.Launcher
public class PublicAPIInstance : IPublicAPI, IRemovable
{
private readonly Settings _settings;
- private readonly Internationalization _translater;
private readonly MainViewModel _mainVM;
+ // Must use getter to access Application.Current.Resources.MergedDictionaries so earlier
private Theme _theme;
private Theme Theme => _theme ??= Ioc.Default.GetRequiredService();
+ // Must use getter to avoid circular dependency
+ private Updater _updater;
+ private Updater Updater => _updater ??= Ioc.Default.GetRequiredService();
+
private readonly object _saveSettingsLock = new();
#region Constructor
- public PublicAPIInstance(Settings settings, Internationalization translater, MainViewModel mainVM)
+ public PublicAPIInstance(Settings settings, MainViewModel mainVM)
{
_settings = settings;
- _translater = translater;
_mainVM = mainVM;
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
@@ -100,8 +103,7 @@ public event VisibilityChangedEventHandler VisibilityChanged
remove => _mainVM.VisibilityChanged -= value;
}
- // Must use Ioc.Default.GetRequiredService() to avoid circular dependency
- public void CheckForNewUpdate() => _ = Ioc.Default.GetRequiredService().UpdateAppAsync(false);
+ public void CheckForNewUpdate() => _ = Updater.UpdateAppAsync(false);
public void SaveAppAllSettings()
{
@@ -178,7 +180,7 @@ public void CopyToClipboard(string stringToCopy, bool directCopy = false, bool s
public void StopLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Collapsed;
- public string GetTranslation(string key) => _translater.GetTranslation(key);
+ public string GetTranslation(string key) => Internationalization.GetTranslation(key);
public List GetAllPlugins() => PluginManager.AllPlugins.ToList();
From 526f00261d2ccf9a148aec46d92708affef2e4d4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 22:02:03 +0800
Subject: [PATCH 0999/1335] Throw plugin exception for plugin dispose interface
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 23 ++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 1d13dcfd3d0..f8a09457533 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -88,14 +88,21 @@ public static async ValueTask DisposePluginsAsync()
private static async Task DisposePluginAsync(PluginPair pluginPair)
{
- switch (pluginPair.Plugin)
- {
- case IDisposable disposable:
- disposable.Dispose();
- break;
- case IAsyncDisposable asyncDisposable:
- await asyncDisposable.DisposeAsync();
- break;
+ try
+ {
+ switch (pluginPair.Plugin)
+ {
+ case IDisposable disposable:
+ disposable.Dispose();
+ break;
+ case IAsyncDisposable asyncDisposable:
+ await asyncDisposable.DisposeAsync();
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ throw new FlowPluginException(pluginPair.Metadata, e);
}
}
From deb22ad0fe02820dcdfe6431793e7ee9ecdf1d75 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 22:05:04 +0800
Subject: [PATCH 1000/1335] Set CanClose earlier
---
Flow.Launcher/MainWindow.xaml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 30afe67a1f3..bf7a45b1d25 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -291,15 +291,15 @@ private async void OnClosing(object sender, CancelEventArgs e)
{
if (!CanClose)
{
+ CanClose = true;
_notifyIcon.Visible = false;
App.API.SaveAppAllSettings();
e.Cancel = true;
await ImageLoader.WaitSaveAsync();
await PluginManager.DisposePluginsAsync();
Notification.Uninstall();
- // After plugins are all disposed, we can close the main window
- CanClose = true;
- // Use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event
+ // After plugins are all disposed, we shutdown application to close app
+ // We use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event
Application.Current.Shutdown();
}
}
From 58c3b73ff7d65078185e7072fbac379fc823021a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 22:13:58 +0800
Subject: [PATCH 1001/1335] Fix directory path issue
---
Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs | 6 +++---
.../Storage/FlowLauncherJsonStorage.cs | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 64f80918199..8ff10816cca 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -45,10 +45,10 @@ public BinaryStorage(string filename)
[Obsolete("This constructor is obsolete. Use BinaryStorage(string filename) instead.")]
public BinaryStorage(string filename, string directoryPath = null!)
{
- directoryPath ??= DataLocation.CacheDirectory;
- FilesFolders.ValidateDirectory(directoryPath);
+ DirectoryPath = directoryPath ?? DataLocation.CacheDirectory;
+ FilesFolders.ValidateDirectory(DirectoryPath);
- FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
+ FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}");
}
public async ValueTask TryLoadAsync(T defaultData)
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index 8b4062b6b24..ca78b2f200a 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -17,11 +17,11 @@ namespace Flow.Launcher.Infrastructure.Storage
public FlowLauncherJsonStorage()
{
- var directoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName);
- FilesFolders.ValidateDirectory(directoryPath);
+ DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName);
+ FilesFolders.ValidateDirectory(DirectoryPath);
var filename = typeof(T).Name;
- FilePath = Path.Combine(directoryPath, $"{filename}{FileSuffix}");
+ FilePath = Path.Combine(DirectoryPath, $"{filename}{FileSuffix}");
}
public new void Save()
From 4527b334331a64b8ede630e84447de438f83cf5d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 11 Apr 2025 22:16:04 +0800
Subject: [PATCH 1002/1335] Code quality
---
Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
index 1de5841a530..6c506cfc06c 100644
--- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
+++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
@@ -264,12 +264,12 @@ public static string GetPreviousExistingDirectory(Func locationExi
var index = path.LastIndexOf('\\');
if (index > 0 && index < (path.Length - 1))
{
- string previousDirectoryPath = path.Substring(0, index + 1);
- return locationExists(previousDirectoryPath) ? previousDirectoryPath : "";
+ string previousDirectoryPath = path[..(index + 1)];
+ return locationExists(previousDirectoryPath) ? previousDirectoryPath : string.Empty;
}
else
{
- return "";
+ return string.Empty;
}
}
@@ -285,7 +285,7 @@ public static string ReturnPreviousDirectoryIfIncompleteString(string path)
// not full path, get previous level directory string
var indexOfSeparator = path.LastIndexOf('\\');
- return path.Substring(0, indexOfSeparator + 1);
+ return path[..(indexOfSeparator + 1)];
}
return path;
From c66cbae78bfa96ecbec3a627ac40bed4d2b442ca Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 12 Apr 2025 00:56:07 +0900
Subject: [PATCH 1003/1335] - Adjust Badge layout - Fix glyph margin in
win11light
---
Flow.Launcher/ResultListBox.xaml | 15 +++++----------
Flow.Launcher/Themes/Win11Light.xaml | 4 ++--
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml
index 63c461c43ea..8231027f4d6 100644
--- a/Flow.Launcher/ResultListBox.xaml
+++ b/Flow.Launcher/ResultListBox.xaml
@@ -102,8 +102,6 @@
+
+
-
+
-
+
From f8d82f3f9b5388bf22b2eb3ea93ec9f38fee6c77 Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 12 Apr 2025 08:57:04 +0900
Subject: [PATCH 1004/1335] Change default query font size Change
showPlaceholder to true from false
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index e304a1b5040..e1c6fbd1fb0 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -82,7 +82,7 @@ public string Theme
/* Appearance Settings. It should be separated from the setting later.*/
public double WindowHeightSize { get; set; } = 42;
public double ItemHeightSize { get; set; } = 58;
- public double QueryBoxFontSize { get; set; } = 20;
+ public double QueryBoxFontSize { get; set; } = 18;
public double ResultItemFontSize { get; set; } = 16;
public double ResultSubItemFontSize { get; set; } = 13;
public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name;
@@ -114,7 +114,7 @@ public string Theme
public double? SettingWindowLeft { get; set; } = null;
public WindowState SettingWindowState { get; set; } = WindowState.Normal;
- bool _showPlaceholder { get; set; } = false;
+ bool _showPlaceholder { get; set; } = true;
public bool ShowPlaceholder
{
get => _showPlaceholder;
From 6b9c9e9eb7451dd195f7d519126b528740474161 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 12 Apr 2025 08:08:26 +0800
Subject: [PATCH 1005/1335] Log exception instead of throw exception
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index f8a09457533..52d6fd736db 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -61,16 +61,16 @@ private static void DeletePythonBinding()
///
public static void Save()
{
- foreach (var plugin in AllPlugins)
+ foreach (var pluginPair in AllPlugins)
{
- var savable = plugin.Plugin as ISavable;
+ var savable = pluginPair.Plugin as ISavable;
try
{
savable?.Save();
}
catch (Exception e)
{
- throw new FlowPluginException(plugin.Metadata, e);
+ API.LogException(ClassName, $"Failed to save plugin {pluginPair.Metadata.Name}", e);
}
}
@@ -102,7 +102,7 @@ private static async Task DisposePluginAsync(PluginPair pluginPair)
}
catch (Exception e)
{
- throw new FlowPluginException(pluginPair.Metadata, e);
+ API.LogException(ClassName, $"Failed to dispose plugin {pluginPair.Metadata.Name}", e);
}
}
From eaac72b6969f59e975a571ea1c00ccf7945c577b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 12 Apr 2025 10:52:59 +0800
Subject: [PATCH 1006/1335] Handle TaskSchedulerUnhandledException
---
Flow.Launcher/App.xaml.cs | 10 ++++++++++
Flow.Launcher/Helper/ErrorReporting.cs | 9 +++++++++
2 files changed, 19 insertions(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 89faa105ea7..a9cd1a8b986 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -153,6 +153,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
+ RegisterTaskSchedulerUnhandledException();
var imageLoadertask = ImageLoader.InitializeAsync();
@@ -284,6 +285,15 @@ private static void RegisterAppDomainExceptions()
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
}
+ ///
+ /// let exception throw as normal is better for Debug
+ ///
+ [Conditional("RELEASE")]
+ private static void RegisterTaskSchedulerUnhandledException()
+ {
+ TaskScheduler.UnobservedTaskException += ErrorReporting.TaskSchedulerUnobservedTaskException;
+ }
+
#endregion
#region IDisposable
diff --git a/Flow.Launcher/Helper/ErrorReporting.cs b/Flow.Launcher/Helper/ErrorReporting.cs
index 5b79c520d60..1787b1d9106 100644
--- a/Flow.Launcher/Helper/ErrorReporting.cs
+++ b/Flow.Launcher/Helper/ErrorReporting.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using System.Windows.Threading;
using NLog;
using Flow.Launcher.Infrastructure;
@@ -30,6 +31,14 @@ public static void DispatcherUnhandledException(object sender, DispatcherUnhandl
e.Handled = true;
}
+ public static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ {
+ //handle unobserved task exceptions
+ Report(e.Exception);
+ //prevent application exist, so the user can copy prompted error info
+ e.SetObserved();
+ }
+
public static string RuntimeInfo()
{
var info =
From 6264447057adcabf96773e09bbd0bff0b51fdcab Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 12 Apr 2025 12:45:40 +0900
Subject: [PATCH 1007/1335] Change theme reset value
---
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index f78704ef2d5..aa8ab7c4c37 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -494,7 +494,7 @@ public void Reset()
{
SelectedQueryBoxFont = new FontFamily(DefaultFont);
SelectedQueryBoxFontFaces = new FamilyTypeface { Stretch = FontStretches.Normal, Weight = FontWeights.Normal, Style = FontStyles.Normal };
- QueryBoxFontSize = 20;
+ QueryBoxFontSize = 18;
SelectedResultFont = new FontFamily(DefaultFont);
SelectedResultFontFaces = new FamilyTypeface { Stretch = FontStretches.Normal, Weight = FontWeights.Normal, Style = FontStyles.Normal };
From 1b8336bd266e0763cbef20707fe4402e57757bf7 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 12 Apr 2025 14:05:03 +0900
Subject: [PATCH 1008/1335] Adjust Theme Color
---
Flow.Launcher/Resources/Light.xaml | 4 ++--
Flow.Launcher/Themes/Circle System.xaml | 4 ++--
Flow.Launcher/Themes/Win11Light.xaml | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml
index aaa23c8e2d5..f6a5444b333 100644
--- a/Flow.Launcher/Resources/Light.xaml
+++ b/Flow.Launcher/Resources/Light.xaml
@@ -18,9 +18,9 @@
- #0C000000
+ #7EFFFFFF
-
+
diff --git a/Flow.Launcher/Themes/Circle System.xaml b/Flow.Launcher/Themes/Circle System.xaml
index 24c7bd65bc8..9fb43b645ae 100644
--- a/Flow.Launcher/Themes/Circle System.xaml
+++ b/Flow.Launcher/Themes/Circle System.xaml
@@ -14,8 +14,8 @@
True
Auto
- #E5E6E6E6
- #DF1F1F1F
+ #CEFAFAFA
+ #D6202020
@@ -68,6 +68,7 @@
x:Key="ItemTitleStyle"
BasedOn="{StaticResource BaseItemTitleStyle}"
TargetType="{x:Type TextBlock}">
+
@@ -75,6 +76,7 @@
x:Key="ItemSubTitleStyle"
BasedOn="{StaticResource BaseItemSubTitleStyle}"
TargetType="{x:Type TextBlock}">
+
@@ -84,7 +86,7 @@
TargetType="{x:Type Rectangle}">
-
+
#d6d4d7
@@ -113,7 +117,7 @@
+
+
+
6
4 0 4 0
@@ -172,7 +192,7 @@
BasedOn="{StaticResource ClockPanel}"
TargetType="{x:Type StackPanel}">
-
+
@@ -206,7 +226,7 @@
x:Key="PreviewBorderStyle"
BasedOn="{StaticResource BasePreviewBorderStyle}"
TargetType="{x:Type Border}">
-
+
-
+
@@ -59,7 +59,7 @@
-
+
@@ -79,7 +79,9 @@
+ TargetType="{x:Type Line}">
+
+
+
-
+
From 0d9ec48e589f629541e81de131a69a19bbf078ea Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 16:36:34 +0800
Subject: [PATCH 1034/1335] Code quality
---
.../ExternalPlugins/CommunityPluginSource.cs | 12 ++++++------
Flow.Launcher.Infrastructure/Http/Http.cs | 7 +++----
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
index e9713564ec7..27891a2d4a4 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -19,7 +19,7 @@ public record CommunityPluginSource(string ManifestFileUrl)
private List plugins = new();
- private static JsonSerializerOptions PluginStoreItemSerializationOption = new JsonSerializerOptions()
+ private static readonly JsonSerializerOptions PluginStoreItemSerializationOption = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
@@ -45,18 +45,18 @@ public async Task> FetchAsync(CancellationToken token)
if (response.StatusCode == HttpStatusCode.OK)
{
- this.plugins = await response.Content
+ plugins = await response.Content
.ReadFromJsonAsync>(PluginStoreItemSerializationOption, cancellationToken: token)
.ConfigureAwait(false);
- this.latestEtag = response.Headers.ETag?.Tag;
+ latestEtag = response.Headers.ETag?.Tag;
- Log.Info(nameof(CommunityPluginSource), $"Loaded {this.plugins.Count} plugins from {ManifestFileUrl}");
- return this.plugins;
+ Log.Info(nameof(CommunityPluginSource), $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
+ return plugins;
}
else if (response.StatusCode == HttpStatusCode.NotModified)
{
Log.Info(nameof(CommunityPluginSource), $"Resource {ManifestFileUrl} has not been modified.");
- return this.plugins;
+ return plugins;
}
else
{
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 030aff7cfc0..0f2f302f1a8 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -16,15 +16,14 @@ public static class Http
{
private const string UserAgent = @"Mozilla/5.0 (Trident/7.0; rv:11.0) like Gecko";
- private static HttpClient client = new HttpClient();
+ private static readonly HttpClient client = new();
static Http()
{
// need to be added so it would work on a win10 machine
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls
- | SecurityProtocolType.Tls11
- | SecurityProtocolType.Tls12;
+ | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
client.DefaultRequestHeaders.Add("User-Agent", UserAgent);
HttpClient.DefaultProxy = WebProxy;
@@ -72,7 +71,7 @@ var userName when string.IsNullOrEmpty(userName) =>
ProxyProperty.Port => (new Uri($"http://{Proxy.Server}:{Proxy.Port}"), WebProxy.Credentials),
ProxyProperty.UserName => (WebProxy.Address, new NetworkCredential(Proxy.UserName, Proxy.Password)),
ProxyProperty.Password => (WebProxy.Address, new NetworkCredential(Proxy.UserName, Proxy.Password)),
- _ => throw new ArgumentOutOfRangeException()
+ _ => throw new ArgumentOutOfRangeException(null)
};
}
catch (UriFormatException e)
From 230df80b877549ac72ef93f76b88f495fcd0d83f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 16:44:14 +0800
Subject: [PATCH 1035/1335] Improve CommunityPluginSource http exception
handler
---
.../ExternalPlugins/CommunityPluginSource.cs | 54 ++++++++++++-------
Flow.Launcher.Core/Updater.cs | 6 ++-
2 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
index 27891a2d4a4..dd79fbc7ab1 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -6,6 +6,7 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
+using System.Net.Sockets;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
@@ -15,6 +16,8 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
public record CommunityPluginSource(string ManifestFileUrl)
{
+ private static readonly string ClassName = nameof(CommunityPluginSource);
+
private string latestEtag = "";
private List plugins = new();
@@ -34,36 +37,51 @@ public record CommunityPluginSource(string ManifestFileUrl)
///
public async Task> FetchAsync(CancellationToken token)
{
- Log.Info(nameof(CommunityPluginSource), $"Loading plugins from {ManifestFileUrl}");
+ Log.Info(ClassName, $"Loading plugins from {ManifestFileUrl}");
var request = new HttpRequestMessage(HttpMethod.Get, ManifestFileUrl);
request.Headers.Add("If-None-Match", latestEtag);
- using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token)
+ try
+ {
+ using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token)
.ConfigureAwait(false);
- if (response.StatusCode == HttpStatusCode.OK)
- {
- plugins = await response.Content
- .ReadFromJsonAsync>(PluginStoreItemSerializationOption, cancellationToken: token)
- .ConfigureAwait(false);
- latestEtag = response.Headers.ETag?.Tag;
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ plugins = await response.Content
+ .ReadFromJsonAsync>(PluginStoreItemSerializationOption, cancellationToken: token)
+ .ConfigureAwait(false);
+ latestEtag = response.Headers.ETag?.Tag;
- Log.Info(nameof(CommunityPluginSource), $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
- return plugins;
+ Log.Info(ClassName, $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
+ return plugins;
+ }
+ else if (response.StatusCode == HttpStatusCode.NotModified)
+ {
+ Log.Info(ClassName, $"Resource {ManifestFileUrl} has not been modified.");
+ return plugins;
+ }
+ else
+ {
+ Log.Warn(ClassName,
+ $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
+ return plugins;
+ }
}
- else if (response.StatusCode == HttpStatusCode.NotModified)
+ catch (Exception e)
{
- Log.Info(nameof(CommunityPluginSource), $"Resource {ManifestFileUrl} has not been modified.");
+ if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
+ {
+ Log.Exception(ClassName, $"Check your connection and proxy settings to {ManifestFileUrl}.", e);
+ }
+ else
+ {
+ Log.Exception(ClassName, "Error Occurred", e);
+ }
return plugins;
}
- else
- {
- Log.Warn(nameof(CommunityPluginSource),
- $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
- throw new Exception($"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
- }
}
}
}
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index 83d4fd9e0a7..f018bdfc70d 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -93,10 +93,14 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
}
catch (Exception e)
{
- if ((e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException))
+ if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
+ {
Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
+ }
else
+ {
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
+ }
if (!silentUpdate)
_api.ShowMsg(_api.GetTranslation("update_flowlauncher_fail"),
From e31f14e60d94ab655513d9b7d962d6b9570b0f69 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:11:36 +0800
Subject: [PATCH 1036/1335] Use local reference instead
---
Flow.Launcher.Infrastructure/Http/Http.cs | 26 ++++++++++---------
.../Image/ImageLoader.cs | 21 ++++++---------
Flow.Launcher.Infrastructure/Logger/Log.cs | 6 -----
Flow.Launcher.Infrastructure/Stopwatch.cs | 21 +++++++--------
.../Storage/BinaryStorage.cs | 6 +++--
.../Storage/FlowLauncherJsonStorage.cs | 11 +++-----
.../Storage/JsonStorage.cs | 4 ++-
.../Storage/PluginBinaryStorage.cs | 11 +++-----
.../Storage/PluginJsonStorage.cs | 11 +++-----
9 files changed, 47 insertions(+), 70 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs
index 0f2f302f1a8..12edf34a432 100644
--- a/Flow.Launcher.Infrastructure/Http/Http.cs
+++ b/Flow.Launcher.Infrastructure/Http/Http.cs
@@ -1,19 +1,21 @@
-using System.IO;
+using System;
+using System.IO;
using System.Net;
using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
-using JetBrains.Annotations;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using System;
-using System.Threading;
using Flow.Launcher.Plugin;
-using CommunityToolkit.Mvvm.DependencyInjection;
+using JetBrains.Annotations;
namespace Flow.Launcher.Infrastructure.Http
{
public static class Http
{
+ private static readonly string ClassName = nameof(Http);
+
private const string UserAgent = @"Mozilla/5.0 (Trident/7.0; rv:11.0) like Gecko";
private static readonly HttpClient client = new();
@@ -33,7 +35,7 @@ static Http()
public static HttpProxy Proxy
{
- private get { return proxy; }
+ private get => proxy;
set
{
proxy = value;
@@ -77,7 +79,7 @@ var userName when string.IsNullOrEmpty(userName) =>
catch (UriFormatException e)
{
Ioc.Default.GetRequiredService().ShowMsg("Please try again", "Unable to parse Http Proxy");
- Log.Exception("Flow.Launcher.Infrastructure.Http", "Unable to parse Uri", e);
+ Log.Exception(ClassName, "Unable to parse Uri", e);
}
}
@@ -133,7 +135,7 @@ public static async Task DownloadAsync([NotNull] string url, [NotNull] string fi
}
catch (HttpRequestException e)
{
- Log.Exception("Infrastructure.Http", "Http Request Error", e, "DownloadAsync");
+ Log.Exception(ClassName, "Http Request Error", e, "DownloadAsync");
throw;
}
}
@@ -146,7 +148,7 @@ public static async Task DownloadAsync([NotNull] string url, [NotNull] string fi
/// The Http result as string. Null if cancellation requested
public static Task GetAsync([NotNull] string url, CancellationToken token = default)
{
- Log.Debug($"|Http.Get|Url <{url}>");
+ Log.Debug(ClassName, $"Url <{url}>");
return GetAsync(new Uri(url), token);
}
@@ -158,7 +160,7 @@ public static Task GetAsync([NotNull] string url, CancellationToken toke
/// The Http result as string. Null if cancellation requested
public static async Task GetAsync([NotNull] Uri url, CancellationToken token = default)
{
- Log.Debug($"|Http.Get|Url <{url}>");
+ Log.Debug(ClassName, $"Url <{url}>");
using var response = await client.GetAsync(url, token);
var content = await response.Content.ReadAsStringAsync(token);
if (response.StatusCode != HttpStatusCode.OK)
@@ -190,7 +192,7 @@ public static Task GetStreamAsync([NotNull] string url,
public static async Task GetStreamAsync([NotNull] Uri url,
CancellationToken token = default)
{
- Log.Debug($"|Http.Get|Url <{url}>");
+ Log.Debug(ClassName, $"Url <{url}>");
return await client.GetStreamAsync(url, token);
}
@@ -201,7 +203,7 @@ public static async Task GetResponseAsync(string url, HttpC
public static async Task GetResponseAsync([NotNull] Uri url, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead,
CancellationToken token = default)
{
- Log.Debug($"|Http.Get|Url <{url}>");
+ Log.Debug(ClassName, $"Url <{url}>");
return await client.GetAsync(url, completionOption, token);
}
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index 9e31d2b4ebf..a49385a02b1 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -7,9 +7,8 @@
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
-using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
-using Flow.Launcher.Plugin;
using SharpVectors.Converters;
using SharpVectors.Renderers.Wpf;
@@ -17,10 +16,6 @@ namespace Flow.Launcher.Infrastructure.Image
{
public static class ImageLoader
{
- // We should not initialize API in static constructor because it will create another API instance
- private static IPublicAPI api = null;
- private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
-
private static readonly string ClassName = nameof(ImageLoader);
private static readonly ImageCache ImageCache = new();
@@ -58,14 +53,14 @@ public static async Task InitializeAsync()
_ = Task.Run(async () =>
{
- await API.StopwatchLogInfoAsync(ClassName, "Preload images cost", async () =>
+ await Stopwatch.InfoAsync(ClassName, "Preload images cost", async () =>
{
foreach (var (path, isFullImage) in usage)
{
await LoadAsync(path, isFullImage);
}
});
- API.LogInfo(ClassName, $"Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
+ Log.Info(ClassName, $"Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
});
}
@@ -81,7 +76,7 @@ await _storage.SaveAsync(ImageCache.EnumerateEntries()
}
catch (System.Exception e)
{
- API.LogException(ClassName, "Failed to save image cache to file", e);
+ Log.Exception(ClassName, "Failed to save image cache to file", e);
}
finally
{
@@ -176,8 +171,8 @@ private static async ValueTask LoadInternalAsync(string path, bool
}
catch (System.Exception e2)
{
- API.LogException(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
- API.LogException(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
+ Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
+ Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
ImageSource image = ImageCache[Constant.MissingImgIcon, false];
ImageCache[path, false] = image;
@@ -243,7 +238,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
{
image = Image;
type = ImageType.Error;
- API.LogException(ClassName, $"Failed to load image file from path {path}: {ex.Message}", ex);
+ Log.Exception(ClassName, $"Failed to load image file from path {path}: {ex.Message}", ex);
}
}
else
@@ -267,7 +262,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag
{
image = Image;
type = ImageType.Error;
- API.LogException(ClassName, $"Failed to load SVG image from path {path}: {ex.Message}", ex);
+ Log.Exception(ClassName, $"Failed to load SVG image from path {path}: {ex.Message}", ex);
}
}
else
diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs
index 807d631c704..25cfbbd3d91 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -227,12 +227,6 @@ public static void Warn(string className, string message, [CallerMemberName] str
{
LogInternal(LogLevel.Warn, className, message, methodName);
}
-
- /// Example: "|ClassName.MethodName|Message"
- public static void Warn(string message)
- {
- LogInternal(message, LogLevel.Warn);
- }
}
public enum LOGLEVEL
diff --git a/Flow.Launcher.Infrastructure/Stopwatch.cs b/Flow.Launcher.Infrastructure/Stopwatch.cs
index 784d323fe52..870e0fe263a 100644
--- a/Flow.Launcher.Infrastructure/Stopwatch.cs
+++ b/Flow.Launcher.Infrastructure/Stopwatch.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Logger;
@@ -9,54 +10,50 @@ public static class Stopwatch
///
/// This stopwatch will appear only in Debug mode
///
- public static long Debug(string message, Action action)
+ public static long Debug(string className, string message, Action action, [CallerMemberName] string methodName = "")
{
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
action();
stopWatch.Stop();
var milliseconds = stopWatch.ElapsedMilliseconds;
- string info = $"{message} <{milliseconds}ms>";
- Log.Debug(info);
+ Log.Debug(className, $"{message} <{milliseconds}ms>", methodName);
return milliseconds;
}
///
/// This stopwatch will appear only in Debug mode
///
- public static async Task DebugAsync(string message, Func action)
+ public static async Task DebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "")
{
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
await action();
stopWatch.Stop();
var milliseconds = stopWatch.ElapsedMilliseconds;
- string info = $"{message} <{milliseconds}ms>";
- Log.Debug(info);
+ Log.Debug(className, $"{message} <{milliseconds}ms>", methodName);
return milliseconds;
}
- public static long Normal(string message, Action action)
+ public static long Info(string className, string message, Action action, [CallerMemberName] string methodName = "")
{
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
action();
stopWatch.Stop();
var milliseconds = stopWatch.ElapsedMilliseconds;
- string info = $"{message} <{milliseconds}ms>";
- Log.Info(info);
+ Log.Info(className, $"{message} <{milliseconds}ms>", methodName);
return milliseconds;
}
- public static async Task NormalAsync(string message, Func action)
+ public static async Task InfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "")
{
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
await action();
stopWatch.Stop();
var milliseconds = stopWatch.ElapsedMilliseconds;
- string info = $"{message} <{milliseconds}ms>";
- Log.Info(info);
+ Log.Info(className, $"{message} <{milliseconds}ms>", methodName);
return milliseconds;
}
}
diff --git a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
index 8ff10816cca..48e6b55238c 100644
--- a/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/BinaryStorage.cs
@@ -20,6 +20,8 @@ namespace Flow.Launcher.Infrastructure.Storage
///
public class BinaryStorage : ISavable
{
+ private static readonly string ClassName = "BinaryStorage";
+
protected T? Data;
public const string FileSuffix = ".cache";
@@ -59,7 +61,7 @@ public async ValueTask TryLoadAsync(T defaultData)
{
if (new FileInfo(FilePath).Length == 0)
{
- Log.Error($"|BinaryStorage.TryLoad|Zero length cache file <{FilePath}>");
+ Log.Error(ClassName, $"Zero length cache file <{FilePath}>");
Data = defaultData;
await SaveAsync();
}
@@ -69,7 +71,7 @@ public async ValueTask TryLoadAsync(T defaultData)
}
else
{
- Log.Info("|BinaryStorage.TryLoad|Cache file not exist, load default data");
+ Log.Info(ClassName, "Cache file not exist, load default data");
Data = defaultData;
await SaveAsync();
}
diff --git a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
index ca78b2f200a..158e0cdf58c 100644
--- a/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs
@@ -1,8 +1,7 @@
using System.IO;
using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
@@ -11,10 +10,6 @@ namespace Flow.Launcher.Infrastructure.Storage
{
private static readonly string ClassName = "FlowLauncherJsonStorage";
- // We should not initialize API in static constructor because it will create another API instance
- private static IPublicAPI api = null;
- private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
-
public FlowLauncherJsonStorage()
{
DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName);
@@ -32,7 +27,7 @@ public FlowLauncherJsonStorage()
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
}
}
@@ -44,7 +39,7 @@ public FlowLauncherJsonStorage()
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save FL settings to path: {FilePath}", e);
}
}
}
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index f283be59e18..0b10382ee9b 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -16,6 +16,8 @@ namespace Flow.Launcher.Infrastructure.Storage
///
public class JsonStorage : ISavable where T : new()
{
+ private static readonly string ClassName = "JsonStorage";
+
protected T? Data;
// need a new directory name
@@ -104,7 +106,7 @@ private async ValueTask LoadBackupOrDefaultAsync()
private void RestoreBackup()
{
- Log.Info($"|JsonStorage.Load|Failed to load settings.json, {BackupFilePath} restored successfully");
+ Log.Info(ClassName, $"Failed to load settings.json, {BackupFilePath} restored successfully");
if (File.Exists(FilePath))
File.Replace(BackupFilePath, FilePath, null);
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
index d18060e3df0..01da96d6259 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginBinaryStorage.cs
@@ -1,7 +1,6 @@
using System.IO;
using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Plugin;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
@@ -10,10 +9,6 @@ namespace Flow.Launcher.Infrastructure.Storage
{
private static readonly string ClassName = "PluginBinaryStorage";
- // We should not initialize API in static constructor because it will create another API instance
- private static IPublicAPI api = null;
- private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
-
public PluginBinaryStorage(string cacheName, string cacheDirectory)
{
DirectoryPath = cacheDirectory;
@@ -30,7 +25,7 @@ public PluginBinaryStorage(string cacheName, string cacheDirectory)
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
}
}
@@ -42,7 +37,7 @@ public PluginBinaryStorage(string cacheName, string cacheDirectory)
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save plugin caches to path: {FilePath}", e);
}
}
}
diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
index e8cbd70fb98..14715294958 100644
--- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
@@ -1,8 +1,7 @@
using System.IO;
using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Infrastructure.Storage
@@ -14,10 +13,6 @@ namespace Flow.Launcher.Infrastructure.Storage
private static readonly string ClassName = "PluginJsonStorage";
- // We should not initialize API in static constructor because it will create another API instance
- private static IPublicAPI api = null;
- private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
-
public PluginJsonStorage()
{
// C# related, add python related below
@@ -42,7 +37,7 @@ public PluginJsonStorage(T data) : this()
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
}
}
@@ -54,7 +49,7 @@ public PluginJsonStorage(T data) : this()
}
catch (System.Exception e)
{
- API.LogException(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
+ Log.Exception(ClassName, $"Failed to save plugin settings to path: {FilePath}", e);
}
}
}
From dde933a96b8372ab4d5bea0658c27e44172e7e0c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:26:21 +0800
Subject: [PATCH 1037/1335] Use api functions instead
---
Flow.Launcher.Core/Configuration/Portable.cs | 19 +++++++------
.../ExternalPlugins/CommunityPluginSource.cs | 25 +++++++++--------
.../Environments/AbstractPluginEnvironment.cs | 5 ++--
Flow.Launcher.Core/Plugin/PluginConfig.cs | 28 +++++++++++--------
Flow.Launcher.Core/Plugin/PluginManager.cs | 17 ++++++-----
.../Resource/Internationalization.cs | 23 ++++++++-------
Flow.Launcher.Core/Resource/Theme.cs | 15 +++++-----
Flow.Launcher.Core/Updater.cs | 11 ++++----
8 files changed, 79 insertions(+), 64 deletions(-)
diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs
index 2b570d2c088..7f02cef0990 100644
--- a/Flow.Launcher.Core/Configuration/Portable.cs
+++ b/Flow.Launcher.Core/Configuration/Portable.cs
@@ -1,21 +1,22 @@
-using Microsoft.Win32;
-using Squirrel;
-using System;
+using System;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Windows;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
-using System.Linq;
-using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Plugin;
+using Flow.Launcher.Plugin.SharedCommands;
+using Microsoft.Win32;
+using Squirrel;
namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
+ private static readonly string ClassName = nameof(Portable);
+
private readonly IPublicAPI API = Ioc.Default.GetRequiredService();
///
@@ -51,7 +52,7 @@ public void DisablePortableMode()
}
catch (Exception e)
{
- Log.Exception("|Portable.DisablePortableMode|Error occurred while disabling portable mode", e);
+ API.LogException(ClassName, "Error occurred while disabling portable mode", e);
}
}
@@ -75,7 +76,7 @@ public void EnablePortableMode()
}
catch (Exception e)
{
- Log.Exception("|Portable.EnablePortableMode|Error occurred while enabling portable mode", e);
+ API.LogException(ClassName, "Error occurred while enabling portable mode", e);
}
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
index dd79fbc7ab1..ac27c523c7e 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -1,7 +1,4 @@
-using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin;
-using System;
+using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
@@ -11,11 +8,18 @@
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Infrastructure.Http;
+using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.ExternalPlugins
{
public record CommunityPluginSource(string ManifestFileUrl)
{
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
private static readonly string ClassName = nameof(CommunityPluginSource);
private string latestEtag = "";
@@ -37,7 +41,7 @@ public record CommunityPluginSource(string ManifestFileUrl)
///
public async Task> FetchAsync(CancellationToken token)
{
- Log.Info(ClassName, $"Loading plugins from {ManifestFileUrl}");
+ API.LogInfo(ClassName, $"Loading plugins from {ManifestFileUrl}");
var request = new HttpRequestMessage(HttpMethod.Get, ManifestFileUrl);
@@ -55,18 +59,17 @@ public async Task> FetchAsync(CancellationToken token)
.ConfigureAwait(false);
latestEtag = response.Headers.ETag?.Tag;
- Log.Info(ClassName, $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
+ API.LogInfo(ClassName, $"Loaded {plugins.Count} plugins from {ManifestFileUrl}");
return plugins;
}
else if (response.StatusCode == HttpStatusCode.NotModified)
{
- Log.Info(ClassName, $"Resource {ManifestFileUrl} has not been modified.");
+ API.LogInfo(ClassName, $"Resource {ManifestFileUrl} has not been modified.");
return plugins;
}
else
{
- Log.Warn(ClassName,
- $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
+ API.LogWarn(ClassName, $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
return plugins;
}
}
@@ -74,11 +77,11 @@ public async Task> FetchAsync(CancellationToken token)
{
if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
{
- Log.Exception(ClassName, $"Check your connection and proxy settings to {ManifestFileUrl}.", e);
+ API.LogException(ClassName, $"Check your connection and proxy settings to {ManifestFileUrl}.", e);
}
else
{
- Log.Exception(ClassName, "Error Occurred", e);
+ API.LogException(ClassName, "Error Occurred", e);
}
return plugins;
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
index bbb6cf63870..14796a87a93 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
@@ -5,7 +5,6 @@
using System.Windows;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
@@ -14,6 +13,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
+ private static readonly string ClassName = nameof(AbstractPluginEnvironment);
+
protected readonly IPublicAPI API = Ioc.Default.GetRequiredService();
internal abstract string Language { get; }
@@ -120,7 +121,7 @@ internal IEnumerable Setup()
else
{
API.ShowMsgBox(string.Format(API.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
- Log.Error("PluginsLoader",
+ API.LogError(ClassName,
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
diff --git a/Flow.Launcher.Core/Plugin/PluginConfig.cs b/Flow.Launcher.Core/Plugin/PluginConfig.cs
index 163f970469d..f7457b4e1b1 100644
--- a/Flow.Launcher.Core/Plugin/PluginConfig.cs
+++ b/Flow.Launcher.Core/Plugin/PluginConfig.cs
@@ -3,14 +3,20 @@
using System.Linq;
using System.IO;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin;
using System.Text.Json;
+using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Core.Plugin
{
internal abstract class PluginConfig
{
+ private static readonly string ClassName = nameof(PluginConfig);
+
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
///
/// Parse plugin metadata in the given directories
///
@@ -32,7 +38,7 @@ public static List Parse(string[] pluginDirectories)
}
catch (Exception e)
{
- Log.Exception($"|PluginConfig.ParsePLuginConfigs|Can't delete <{directory}>", e);
+ API.LogException(ClassName, $"Can't delete <{directory}>", e);
}
}
else
@@ -49,11 +55,11 @@ public static List Parse(string[] pluginDirectories)
duplicateList
.ForEach(
- x => Log.Warn("PluginConfig",
- string.Format("Duplicate plugin name: {0}, id: {1}, version: {2} " +
- "not loaded due to version not the highest of the duplicates",
- x.Name, x.ID, x.Version),
- "GetUniqueLatestPluginMetadata"));
+ x => API.LogWarn(ClassName,
+ string.Format("Duplicate plugin name: {0}, id: {1}, version: {2} " +
+ "not loaded due to version not the highest of the duplicates",
+ x.Name, x.ID, x.Version),
+ "GetUniqueLatestPluginMetadata"));
return uniqueList;
}
@@ -101,7 +107,7 @@ private static PluginMetadata GetPluginMetadata(string pluginDirectory)
string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName);
if (!File.Exists(configPath))
{
- Log.Error($"|PluginConfig.GetPluginMetadata|Didn't find config file <{configPath}>");
+ API.LogError(ClassName, $"Didn't find config file <{configPath}>");
return null;
}
@@ -117,19 +123,19 @@ private static PluginMetadata GetPluginMetadata(string pluginDirectory)
}
catch (Exception e)
{
- Log.Exception($"|PluginConfig.GetPluginMetadata|invalid json for config <{configPath}>", e);
+ API.LogException(ClassName, $"Invalid json for config <{configPath}>", e);
return null;
}
if (!AllowedLanguage.IsAllowed(metadata.Language))
{
- Log.Error($"|PluginConfig.GetPluginMetadata|Invalid language <{metadata.Language}> for config <{configPath}>");
+ API.LogError(ClassName, $"Invalid language <{metadata.Language}> for config <{configPath}>");
return null;
}
if (!File.Exists(metadata.ExecuteFilePath))
{
- Log.Error($"|PluginConfig.GetPluginMetadata|execute file path didn't exist <{metadata.ExecuteFilePath}> for conifg <{configPath}");
+ API.LogError(ClassName, $"Execute file path didn't exist <{metadata.ExecuteFilePath}> for conifg <{configPath}");
return null;
}
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 52d6fd736db..72303c8b754 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -9,7 +9,6 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
@@ -214,12 +213,12 @@ public static async Task InitializePluginsAsync()
() => pair.Plugin.InitAsync(new PluginInitContext(pair.Metadata, API)));
pair.Metadata.InitTime += milliseconds;
- Log.Info(
- $"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
+ API.LogInfo(ClassName,
+ $"Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>");
}
catch (Exception e)
{
- Log.Exception(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
+ API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
pair.Metadata.Disabled = true;
failedPlugins.Enqueue(pair);
}
@@ -370,8 +369,8 @@ public static List GetContextMenusForPlugin(Result result)
}
catch (Exception e)
{
- Log.Exception(
- $"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{pluginPair.Metadata.Name}>",
+ API.LogException(ClassName,
+ $"Can't load context menus for plugin <{pluginPair.Metadata.Name}>",
e);
}
}
@@ -563,7 +562,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
}
catch (Exception e)
{
- Log.Exception($"|PluginManager.InstallPlugin|Failed to delete temp folder {tempFolderPluginPath}", e);
+ API.LogException(ClassName, $"Failed to delete temp folder {tempFolderPluginPath}", e);
}
if (checkModified)
@@ -608,7 +607,7 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo
}
catch (Exception e)
{
- Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin settings folder for {plugin.Name}", e);
+ API.LogException(ClassName, $"Failed to delete plugin settings folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"),
string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name));
}
@@ -624,7 +623,7 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo
}
catch (Exception e)
{
- Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin cache folder for {plugin.Name}", e);
+ API.LogException(ClassName, $"Failed to delete plugin cache folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginCacheTitle"),
string.Format(API.GetTranslation("failedToRemovePluginCacheMessage"), plugin.Name));
}
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index df841dbbe0e..1dfc6d4ed59 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -6,7 +6,6 @@
using System.Windows;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Globalization;
@@ -17,11 +16,14 @@ namespace Flow.Launcher.Core.Resource
{
public class Internationalization
{
+ private static readonly string ClassName = nameof(Internationalization);
+
private const string Folder = "Languages";
private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
private readonly Settings _settings;
+ private readonly IPublicAPI _api;
private readonly List _languageDirectories = new();
private readonly List _oldResources = new();
private readonly string SystemLanguageCode;
@@ -29,6 +31,7 @@ public class Internationalization
public Internationalization(Settings settings)
{
_settings = settings;
+ _api = Ioc.Default.GetRequiredService();
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@@ -80,7 +83,7 @@ private void AddPluginLanguageDirectories()
}
else
{
- Log.Error($"|Internationalization.AddPluginLanguageDirectories|Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
+ _api.LogError(ClassName, $"Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
}
}
@@ -144,13 +147,13 @@ public void ChangeLanguage(string languageCode)
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
}
- private static Language GetLanguageByLanguageCode(string languageCode)
+ private Language GetLanguageByLanguageCode(string languageCode)
{
var lowercase = languageCode.ToLower();
var language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == lowercase);
if (language == null)
{
- Log.Error($"|Internationalization.GetLanguageByLanguageCode|Language code can't be found <{languageCode}>");
+ _api.LogError(ClassName, $"Language code can't be found <{languageCode}>");
return AvailableLanguages.English;
}
else
@@ -239,7 +242,7 @@ public List LoadAvailableLanguages()
return list;
}
- public static string GetTranslation(string key)
+ public string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
if (translation is string)
@@ -248,7 +251,7 @@ public static string GetTranslation(string key)
}
else
{
- Log.Error($"|Internationalization.GetTranslation|No Translation for key {key}");
+ _api.LogError(ClassName, $"No Translation for key {key}");
return $"No Translation for key {key}";
}
}
@@ -266,12 +269,12 @@ private void UpdatePluginMetadataTranslations()
}
catch (Exception e)
{
- Log.Exception($"|Internationalization.UpdatePluginMetadataTranslations|Failed for <{p.Metadata.Name}>", e);
+ _api.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
}
}
}
- private static string LanguageFile(string folder, string language)
+ private string LanguageFile(string folder, string language)
{
if (Directory.Exists(folder))
{
@@ -282,7 +285,7 @@ private static string LanguageFile(string folder, string language)
}
else
{
- Log.Error($"|Internationalization.LanguageFile|Language path can't be found <{path}>");
+ _api.LogError(ClassName, $"Language path can't be found <{path}>");
var english = Path.Combine(folder, DefaultFile);
if (File.Exists(english))
{
@@ -290,7 +293,7 @@ private static string LanguageFile(string folder, string language)
}
else
{
- Log.Error($"|Internationalization.LanguageFile|Default English Language path can't be found <{path}>");
+ _api.LogError(ClassName, $"Default English Language path can't be found <{path}>");
return string.Empty;
}
}
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 59e76e2d2e9..64ffec907d9 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -13,7 +13,6 @@
using System.Windows.Shell;
using System.Windows.Threading;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
@@ -25,6 +24,8 @@ public class Theme
{
#region Properties & Fields
+ private readonly string ClassName = nameof(Theme);
+
public bool BlurEnabled { get; private set; }
private const string ThemeMetadataNamePrefix = "Name:";
@@ -73,7 +74,7 @@ public Theme(IPublicAPI publicAPI, Settings settings)
}
else
{
- Log.Error("Current theme resource not found. Initializing with default theme.");
+ _api.LogError(ClassName, "Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
};
}
@@ -92,7 +93,7 @@ private void MakeSureThemeDirectoriesExist()
}
catch (Exception e)
{
- Log.Exception($"|Theme.MakesureThemeDirectoriesExist|Exception when create directory <{dir}>", e);
+ _api.LogException(ClassName, $"Exception when create directory <{dir}>", e);
}
}
}
@@ -135,7 +136,7 @@ public void UpdateFonts()
}
catch (Exception e)
{
- Log.Exception("Error occurred while updating theme fonts", e);
+ _api.LogException(ClassName, "Error occurred while updating theme fonts", e);
}
}
@@ -387,7 +388,7 @@ public ThemeData GetCurrentTheme()
var matchingTheme = themes.FirstOrDefault(t => t.FileNameWithoutExtension == _settings.Theme);
if (matchingTheme == null)
{
- Log.Warn($"No matching theme found for '{_settings.Theme}'. Falling back to the first available theme.");
+ _api.LogWarn(ClassName, $"No matching theme found for '{_settings.Theme}'. Falling back to the first available theme.");
}
return matchingTheme ?? themes.FirstOrDefault();
}
@@ -440,7 +441,7 @@ public bool ChangeTheme(string theme = null)
}
catch (DirectoryNotFoundException)
{
- Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
+ _api.LogError(ClassName, $"Theme <{theme}> path can't be found");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_path_not_exists"), theme));
@@ -450,7 +451,7 @@ public bool ChangeTheme(string theme = null)
}
catch (XamlParseException)
{
- Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
+ _api.LogError(ClassName, $"Theme <{theme}> fail to parse");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_parse_error"), theme));
diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs
index f018bdfc70d..bc3655f69e7 100644
--- a/Flow.Launcher.Core/Updater.cs
+++ b/Flow.Launcher.Core/Updater.cs
@@ -12,7 +12,6 @@
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using JetBrains.Annotations;
@@ -24,6 +23,8 @@ public class Updater
{
public string GitHubRepository { get; init; }
+ private static readonly string ClassName = nameof(Updater);
+
private readonly IPublicAPI _api;
public Updater(IPublicAPI publicAPI, string gitHubRepository)
@@ -51,7 +52,7 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString());
var currentVersion = Version.Parse(Constant.Version);
- Log.Info($"|Updater.UpdateApp|Future Release <{Formatted(newUpdateInfo.FutureReleaseEntry)}>");
+ _api.LogInfo(ClassName, $"Future Release <{Formatted(newUpdateInfo.FutureReleaseEntry)}>");
if (newReleaseVersion <= currentVersion)
{
@@ -84,7 +85,7 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
var newVersionTips = NewVersionTips(newReleaseVersion.ToString());
- Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
+ _api.LogInfo(ClassName, $"Update success:{newVersionTips}");
if (_api.ShowMsgBox(newVersionTips, _api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
@@ -95,11 +96,11 @@ public async Task UpdateAppAsync(bool silentUpdate = true)
{
if (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)
{
- Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
+ _api.LogException(ClassName, $"Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e);
}
else
{
- Log.Exception($"|Updater.UpdateApp|Error Occurred", e);
+ _api.LogException(ClassName, $"Error Occurred", e);
}
if (!silentUpdate)
From b13ab3b893baefecdb788ab605e6e5d03bf504f3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:27:17 +0800
Subject: [PATCH 1038/1335] Remove useless DI
---
Flow.Launcher/SettingWindow.xaml.cs | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 28140f0245c..b4a3ae47a92 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -6,7 +6,6 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin;
using Flow.Launcher.SettingPages.Views;
using Flow.Launcher.ViewModel;
using ModernWpf.Controls;
@@ -16,7 +15,6 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
- private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
@@ -26,7 +24,6 @@ public SettingWindow()
_settings = Ioc.Default.GetRequiredService();
DataContext = viewModel;
_viewModel = viewModel;
- _api = Ioc.Default.GetRequiredService();
InitializePosition();
InitializeComponent();
}
@@ -49,7 +46,7 @@ private void OnClosed(object sender, EventArgs e)
_settings.SettingWindowTop = Top;
_settings.SettingWindowLeft = Left;
_viewModel.Save();
- _api.SavePluginSettings();
+ App.API.SavePluginSettings();
}
private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
From 4a7915b9ffde654751bc3dbd3451cd070c1da018 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:50:44 +0800
Subject: [PATCH 1039/1335] Use api fuctions forr main project
---
.../Resource/Internationalization.cs | 24 ++++++++++---------
Flow.Launcher/App.xaml.cs | 18 +++++++-------
.../Converters/QuerySuggestionBoxConverter.cs | 5 ++--
Flow.Launcher/Helper/AutoStartup.cs | 14 ++++++-----
Flow.Launcher/Helper/HotKeyMapper.cs | 8 ++++---
Flow.Launcher/MessageBoxEx.xaml.cs | 6 ++---
Flow.Launcher/Msg.xaml.cs | 1 -
Flow.Launcher/Notification.cs | 7 +++---
Flow.Launcher/ProgressBoxEx.xaml.cs | 5 ++--
Flow.Launcher/PublicAPIInstance.cs | 8 +++----
Flow.Launcher/ReportWindow.xaml.cs | 6 +++--
Flow.Launcher/ViewModel/MainViewModel.cs | 13 +++++-----
Flow.Launcher/ViewModel/ResultViewModel.cs | 8 +++----
13 files changed, 67 insertions(+), 56 deletions(-)
diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs
index 1dfc6d4ed59..b32b09e8fc8 100644
--- a/Flow.Launcher.Core/Resource/Internationalization.cs
+++ b/Flow.Launcher.Core/Resource/Internationalization.cs
@@ -18,12 +18,15 @@ public class Internationalization
{
private static readonly string ClassName = nameof(Internationalization);
+ // We should not initialize API in static constructor because it will create another API instance
+ private static IPublicAPI api = null;
+ private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
+
private const string Folder = "Languages";
private const string DefaultLanguageCode = "en";
private const string DefaultFile = "en.xaml";
private const string Extension = ".xaml";
private readonly Settings _settings;
- private readonly IPublicAPI _api;
private readonly List _languageDirectories = new();
private readonly List _oldResources = new();
private readonly string SystemLanguageCode;
@@ -31,7 +34,6 @@ public class Internationalization
public Internationalization(Settings settings)
{
_settings = settings;
- _api = Ioc.Default.GetRequiredService();
AddFlowLauncherLanguageDirectory();
SystemLanguageCode = GetSystemLanguageCodeAtStartup();
}
@@ -83,7 +85,7 @@ private void AddPluginLanguageDirectories()
}
else
{
- _api.LogError(ClassName, $"Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
+ API.LogError(ClassName, $"Can't find plugin path <{location}> for <{plugin.Metadata.Name}>");
}
}
@@ -147,13 +149,13 @@ public void ChangeLanguage(string languageCode)
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
}
- private Language GetLanguageByLanguageCode(string languageCode)
+ private static Language GetLanguageByLanguageCode(string languageCode)
{
var lowercase = languageCode.ToLower();
var language = AvailableLanguages.GetAvailableLanguages().FirstOrDefault(o => o.LanguageCode.ToLower() == lowercase);
if (language == null)
{
- _api.LogError(ClassName, $"Language code can't be found <{languageCode}>");
+ API.LogError(ClassName, $"Language code can't be found <{languageCode}>");
return AvailableLanguages.English;
}
else
@@ -242,7 +244,7 @@ public List LoadAvailableLanguages()
return list;
}
- public string GetTranslation(string key)
+ public static string GetTranslation(string key)
{
var translation = Application.Current.TryFindResource(key);
if (translation is string)
@@ -251,7 +253,7 @@ public string GetTranslation(string key)
}
else
{
- _api.LogError(ClassName, $"No Translation for key {key}");
+ API.LogError(ClassName, $"No Translation for key {key}");
return $"No Translation for key {key}";
}
}
@@ -269,12 +271,12 @@ private void UpdatePluginMetadataTranslations()
}
catch (Exception e)
{
- _api.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
+ API.LogException(ClassName, $"Failed for <{p.Metadata.Name}>", e);
}
}
}
- private string LanguageFile(string folder, string language)
+ private static string LanguageFile(string folder, string language)
{
if (Directory.Exists(folder))
{
@@ -285,7 +287,7 @@ private string LanguageFile(string folder, string language)
}
else
{
- _api.LogError(ClassName, $"Language path can't be found <{path}>");
+ API.LogError(ClassName, $"Language path can't be found <{path}>");
var english = Path.Combine(folder, DefaultFile);
if (File.Exists(english))
{
@@ -293,7 +295,7 @@ private string LanguageFile(string folder, string language)
}
else
{
- _api.LogError(ClassName, $"Default English Language path can't be found <{path}>");
+ API.LogError(ClassName, $"Default English Language path can't be found <{path}>");
return string.Empty;
}
}
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index a9cd1a8b986..87677f58a67 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -148,8 +148,8 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
- Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------");
- Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}");
+ API.LogInfo(ClassName, "Begin Flow Launcher startup ----------------------------------------------------");
+ API.LogInfo(ClassName, "Runtime info:{ErrorReporting.RuntimeInfo()}");
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
@@ -176,7 +176,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
_mainWindow = new MainWindow();
- Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
+ API.LogInfo(ClassName, "Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = _mainWindow;
Current.MainWindow.Title = Constant.FlowLauncher;
@@ -192,7 +192,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
AutoUpdates();
API.SaveAppAllSettings();
- Log.Info("|App.OnStartup|End Flow Launcher startup ----------------------------------------------------");
+ API.LogInfo(ClassName, "End Flow Launcher startup ----------------------------------------------------");
});
}
@@ -250,19 +250,19 @@ private void RegisterExitEvents()
{
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
{
- Log.Info("|App.RegisterExitEvents|Process Exit");
+ API.LogInfo(ClassName, "Process Exit");
Dispose();
};
Current.Exit += (s, e) =>
{
- Log.Info("|App.RegisterExitEvents|Application Exit");
+ API.LogInfo(ClassName, "Application Exit");
Dispose();
};
Current.SessionEnding += (s, e) =>
{
- Log.Info("|App.RegisterExitEvents|Session Ending");
+ API.LogInfo(ClassName, "Session Ending");
Dispose();
};
}
@@ -326,7 +326,7 @@ protected virtual void Dispose(bool disposing)
API.StopwatchLogInfo(ClassName, "Dispose cost", () =>
{
- Log.Info("|App.Dispose|Begin Flow Launcher dispose ----------------------------------------------------");
+ API.LogInfo(ClassName, "Begin Flow Launcher dispose ----------------------------------------------------");
if (disposing)
{
@@ -336,7 +336,7 @@ protected virtual void Dispose(bool disposing)
_mainVM?.Dispose();
}
- Log.Info("|App.Dispose|End Flow Launcher dispose ----------------------------------------------------");
+ API.LogInfo(ClassName, "End Flow Launcher dispose ----------------------------------------------------");
});
}
diff --git a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
index 0d6f2e469aa..eb492e3344e 100644
--- a/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
+++ b/Flow.Launcher/Converters/QuerySuggestionBoxConverter.cs
@@ -4,13 +4,14 @@
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Converters;
public class QuerySuggestionBoxConverter : IMultiValueConverter
{
+ private static readonly string ClassName = nameof(QuerySuggestionBoxConverter);
+
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// values[0] is TextBox: The textbox displaying the autocomplete suggestion
@@ -64,7 +65,7 @@ values[2] is not string queryText ||
}
catch (Exception e)
{
- Log.Exception(nameof(QuerySuggestionBoxConverter), "fail to convert text for suggestion box", e);
+ App.API.LogException(ClassName, "fail to convert text for suggestion box", e);
return string.Empty;
}
}
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index c5e20504b7d..568ea794446 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -11,6 +11,8 @@ namespace Flow.Launcher.Helper;
public class AutoStartup
{
+ private static readonly string ClassName = nameof(AutoStartup);
+
private const string StartupPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
private const string LogonTaskName = $"{Constant.FlowLauncher} Startup";
private const string LogonTaskDesc = $"{Constant.FlowLauncher} Auto Startup";
@@ -34,7 +36,7 @@ public static bool IsEnabled
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Ignoring non-critical registry error (querying if enabled): {e}");
+ App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
}
return false;
@@ -61,7 +63,7 @@ private static bool CheckLogonTask()
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Failed to check logon task: {e}");
+ App.API.LogError(ClassName, $"Failed to check logon task: {e}");
}
}
@@ -112,7 +114,7 @@ private static void Disable(bool logonTask)
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Failed to disable auto-startup: {e}");
+ App.API.LogError(ClassName, $"Failed to disable auto-startup: {e}");
throw;
}
}
@@ -133,7 +135,7 @@ private static void Enable(bool logonTask)
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Failed to enable auto-startup: {e}");
+ App.API.LogError(ClassName, $"Failed to enable auto-startup: {e}");
throw;
}
}
@@ -161,7 +163,7 @@ private static bool ScheduleLogonTask()
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Failed to schedule logon task: {e}");
+ App.API.LogError(ClassName, $"Failed to schedule logon task: {e}");
return false;
}
}
@@ -176,7 +178,7 @@ private static bool UnscheduleLogonTask()
}
catch (Exception e)
{
- Log.Error("AutoStartup", $"Failed to unschedule logon task: {e}");
+ App.API.LogError(ClassName, $"Failed to unschedule logon task: {e}");
return false;
}
}
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 0771a60749a..1e83415cc46 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -12,6 +12,8 @@ namespace Flow.Launcher.Helper;
internal static class HotKeyMapper
{
+ private static readonly string ClassName = nameof(HotKeyMapper);
+
private static Settings _settings;
private static MainViewModel _mainViewModel;
@@ -51,7 +53,7 @@ private static void SetWithChefKeys(string hotkeyStr)
}
catch (Exception e)
{
- Log.Error(
+ App.API.LogError(ClassName,
string.Format("|HotkeyMapper.SetWithChefKeys|Error registering hotkey: {0} \nStackTrace:{1}",
e.Message,
e.StackTrace));
@@ -76,7 +78,7 @@ internal static void SetHotkey(HotkeyModel hotkey, EventHandler
}
catch (Exception e)
{
- Log.Error(
+ App.API.LogError(ClassName,
string.Format("|HotkeyMapper.SetHotkey|Error registering hotkey {2}: {0} \nStackTrace:{1}",
e.Message,
e.StackTrace,
@@ -102,7 +104,7 @@ internal static void RemoveHotkey(string hotkeyStr)
}
catch (Exception e)
{
- Log.Error(
+ App.API.LogError(ClassName,
string.Format("|HotkeyMapper.RemoveHotkey|Error removing hotkey: {0} \nStackTrace:{1}",
e.Message,
e.StackTrace));
diff --git a/Flow.Launcher/MessageBoxEx.xaml.cs b/Flow.Launcher/MessageBoxEx.xaml.cs
index 3d94769d002..a55aeb81118 100644
--- a/Flow.Launcher/MessageBoxEx.xaml.cs
+++ b/Flow.Launcher/MessageBoxEx.xaml.cs
@@ -4,13 +4,13 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Image;
-using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher
{
public partial class MessageBoxEx : Window
{
+ private static readonly string ClassName = nameof(MessageBoxEx);
+
private static MessageBoxEx msgBox;
private static MessageBoxResult _result = MessageBoxResult.None;
@@ -59,7 +59,7 @@ public static MessageBoxResult Show(
}
catch (Exception e)
{
- Log.Error($"|MessageBoxEx.Show|An error occurred: {e.Message}");
+ App.API.LogError(ClassName, $"An error occurred: {e.Message}");
msgBox = null;
return MessageBoxResult.None;
}
diff --git a/Flow.Launcher/Msg.xaml.cs b/Flow.Launcher/Msg.xaml.cs
index ff9accd62f2..110235cb5ac 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -5,7 +5,6 @@
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Image;
namespace Flow.Launcher
{
diff --git a/Flow.Launcher/Notification.cs b/Flow.Launcher/Notification.cs
index 30b3a067334..be81e6ec6ef 100644
--- a/Flow.Launcher/Notification.cs
+++ b/Flow.Launcher/Notification.cs
@@ -1,5 +1,4 @@
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Microsoft.Toolkit.Uwp.Notifications;
using System;
using System.IO;
@@ -9,6 +8,8 @@ namespace Flow.Launcher
{
internal static class Notification
{
+ private static readonly string ClassName = nameof(Notification);
+
internal static bool legacy = !Win32Helper.IsNotificationSupported();
internal static void Uninstall()
@@ -51,12 +52,12 @@ private static void ShowInternal(string title, string subTitle, string iconPath
{
// Temporary fix for the Windows 11 notification issue
// Possibly from 22621.1413 or 22621.1485, judging by post time of #2024
- Log.Exception("Flow.Launcher.Notification|Notification InvalidOperationException Error", e);
+ App.API.LogException(ClassName, "Notification InvalidOperationException Error", e);
LegacyShow(title, subTitle, iconPath);
}
catch (Exception e)
{
- Log.Exception("Flow.Launcher.Notification|Notification Error", e);
+ App.API.LogException(ClassName, "Notification Error", e);
LegacyShow(title, subTitle, iconPath);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 2395bdf3497..840c8bade87 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -2,12 +2,13 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
-using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher
{
public partial class ProgressBoxEx : Window
{
+ private static readonly string ClassName = nameof(ProgressBoxEx);
+
private readonly Action _cancelProgress;
private ProgressBoxEx(Action cancelProgress)
@@ -47,7 +48,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
}
catch (Exception e)
{
- Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
+ App.API.LogError(ClassName, $"An error occurred: {e.Message}");
await reportProgressAsync(null).ConfigureAwait(false);
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 5438eac7dac..3abc57b8a81 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -435,16 +435,16 @@ public Task UninstallPluginAsync(PluginMetadata pluginMetadata, bool removePlugi
PluginManager.UninstallPluginAsync(pluginMetadata, removePluginSettings);
public long StopwatchLogDebug(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
- Stopwatch.Debug($"|{className}.{methodName}|{message}", action);
+ Stopwatch.Debug(className, message, action, methodName);
public Task StopwatchLogDebugAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
- Stopwatch.DebugAsync($"|{className}.{methodName}|{message}", action);
+ Stopwatch.DebugAsync(className, message, action, methodName);
public long StopwatchLogInfo(string className, string message, Action action, [CallerMemberName] string methodName = "") =>
- Stopwatch.Normal($"|{className}.{methodName}|{message}", action);
+ Stopwatch.Info(className, message, action, methodName);
public Task StopwatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
- Stopwatch.NormalAsync($"|{className}.{methodName}|{message}", action);
+ Stopwatch.InfoAsync(className, message, action, methodName);
#endregion
diff --git a/Flow.Launcher/ReportWindow.xaml.cs b/Flow.Launcher/ReportWindow.xaml.cs
index 6fe90783ec9..0ab785a17b6 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -8,13 +8,15 @@
using System.Windows.Documents;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.SharedCommands;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
internal partial class ReportWindow
{
+ private static readonly string ClassName = nameof(ReportWindow);
+
public ReportWindow(Exception exception)
{
InitializeComponent();
@@ -38,7 +40,7 @@ private static string GetIssuesUrl(string website)
private void SetException(Exception exception)
{
- string path = Log.CurrentLogDirectory;
+ var path = DataLocation.VersionLogDirectory;
var directory = new DirectoryInfo(path);
var log = directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f6b9aa67c94..998fdb9068c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -16,7 +16,6 @@
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -30,6 +29,8 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
{
#region Private Fields
+ private static readonly string ClassName = nameof(MainViewModel);
+
private bool _isQueryRunning;
private Query _lastQuery;
private string _queryTextBeforeLeaveResults;
@@ -213,7 +214,7 @@ async Task UpdateActionAsync()
}
if (!_disposed)
- Log.Error("MainViewModel", "Unexpected ResultViewUpdate ends");
+ App.API.LogError(ClassName, "Unexpected ResultViewUpdate ends");
}
void continueAction(Task t)
@@ -257,7 +258,7 @@ public void RegisterResultsUpdatedEvent()
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
token)))
{
- Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
+ App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
};
}
@@ -1303,7 +1304,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect)))
{
- Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
+ App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
}
}
@@ -1347,8 +1348,8 @@ private Query ConstructQuery(string queryText, IEnumerable
}
catch (Exception e)
{
- Log.Exception(
- $"{nameof(MainViewModel)}.{nameof(ConstructQuery)}|Error when expanding shortcut {shortcut.Key}",
+ App.API.LogException(ClassName,
+ $"Error when expanding shortcut {shortcut.Key}",
e);
}
}
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index 8d7569dc1e7..ef7e24c3bd8 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Drawing.Text;
using System.IO;
@@ -7,7 +6,6 @@
using System.Windows;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.Image;
-using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@@ -15,6 +13,8 @@ namespace Flow.Launcher.ViewModel
{
public class ResultViewModel : BaseModel
{
+ private static readonly string ClassName = nameof(ResultsViewModel);
+
private static readonly PrivateFontCollection FontCollection = new();
private static readonly Dictionary Fonts = new();
@@ -232,8 +232,8 @@ private async Task LoadImageInternalAsync(string imagePath, Result.
}
catch (Exception e)
{
- Log.Exception(
- $"|ResultViewModel.LoadImageInternalAsync|IcoPath is empty and exception when calling IconDelegate for result <{Result.Title}> of plugin <{Result.PluginDirectory}>",
+ App.API.LogException(ClassName,
+ $"IcoPath is empty and exception when calling IconDelegate for result <{Result.Title}> of plugin <{Result.PluginDirectory}>",
e);
}
}
From 3f57f944f620e3198a8a590bfeb9ecf4b30e62b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:52:42 +0800
Subject: [PATCH 1040/1335] Remove useless debug
---
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index 16b6bcab203..d2884599467 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -109,7 +109,6 @@ public async Task> QueryAsync(Query query, CancellationToken token)
}
catch (OperationCanceledException)
{
- Context.API.LogDebug(ClassName, "Query operation cancelled");
return emptyResults;
}
finally
From 50130e4b009ae5a808b7b65d3238d0785c60b0df Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 17:59:39 +0800
Subject: [PATCH 1041/1335] Use class name instead
---
Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs | 4 +++-
Flow.Launcher/Helper/WallpaperPathRetrieval.cs | 10 ++++++----
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 4 +++-
Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 4 +++-
.../Search/DirectoryInfo/DirectoryInfoSearch.cs | 4 +++-
.../ProcessHelper.cs | 4 +++-
.../SuggestionSources/Baidu.cs | 6 ++++--
.../SuggestionSources/Bing.cs | 6 ++++--
.../SuggestionSources/DuckDuckGo.cs | 6 ++++--
.../SuggestionSources/Google.cs | 6 ++++--
Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs | 2 ++
11 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
index 44d3ef0ff7b..7ca91eaecde 100644
--- a/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
@@ -9,6 +9,8 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
public static class PluginsManifest
{
+ private static readonly string ClassName = nameof(PluginsManifest);
+
private static readonly CommunityPluginStore mainPluginStore =
new("https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json",
"https://fastly.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json",
@@ -44,7 +46,7 @@ public static async Task UpdateManifestAsync(bool usePrimaryUrlOnly = fals
}
catch (Exception e)
{
- Ioc.Default.GetRequiredService().LogException(nameof(PluginsManifest), "Http request failed", e);
+ Ioc.Default.GetRequiredService().LogException(ClassName, "Http request failed", e);
}
finally
{
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index 77bebe2d37d..93b9a8aaa23 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -12,6 +12,8 @@ namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
+ private static readonly string ClassName = nameof(WallpaperPathRetrieval);
+
private const int MaxCacheSize = 3;
private static readonly Dictionary<(string, DateTime), ImageBrush> WallpaperCache = new();
private static readonly object CacheLock = new();
@@ -29,7 +31,7 @@ public static Brush GetWallpaperBrush()
var wallpaperPath = Win32Helper.GetWallpaperPath();
if (string.IsNullOrEmpty(wallpaperPath) || !File.Exists(wallpaperPath))
{
- App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Wallpaper path is invalid: {wallpaperPath}");
+ App.API.LogInfo(ClassName, $"Wallpaper path is invalid: {wallpaperPath}");
var wallpaperColor = GetWallpaperColor();
return new SolidColorBrush(wallpaperColor);
}
@@ -54,7 +56,7 @@ public static Brush GetWallpaperBrush()
if (originalWidth == 0 || originalHeight == 0)
{
- App.API.LogInfo(nameof(WallpaperPathRetrieval), $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}");
+ App.API.LogInfo(ClassName, $"Failed to load bitmap: Width={originalWidth}, Height={originalHeight}");
return new SolidColorBrush(Colors.Transparent);
}
@@ -95,7 +97,7 @@ public static Brush GetWallpaperBrush()
}
catch (Exception ex)
{
- App.API.LogException(nameof(WallpaperPathRetrieval), "Error retrieving wallpaper", ex);
+ App.API.LogException(ClassName, "Error retrieving wallpaper", ex);
return new SolidColorBrush(Colors.Transparent);
}
}
@@ -113,7 +115,7 @@ private static Color GetWallpaperColor()
}
catch (Exception ex)
{
- App.API.LogException(nameof(WallpaperPathRetrieval), "Error parsing wallpaper color", ex);
+ App.API.LogException(ClassName, "Error parsing wallpaper color", ex);
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 3bee49bf20a..9ad31ad1401 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -15,6 +15,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark;
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable
{
+ private static readonly string ClassName = nameof(Main);
+
internal static string _faviconCacheDir;
internal static PluginInitContext _context;
@@ -221,7 +223,7 @@ public List LoadContextMenus(Result selectedResult)
catch (Exception e)
{
var message = "Failed to set url in clipboard";
- _context.API.LogException(nameof(Main), message, e);
+ _context.API.LogException(ClassName, message, e);
_context.API.ShowMsg(message);
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index f479078242e..633af7b6ba2 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -15,6 +15,8 @@ namespace Flow.Launcher.Plugin.Explorer
{
internal class ContextMenu : IContextMenu
{
+ private static readonly string ClassName = nameof(ContextMenu);
+
private PluginInitContext Context { get; set; }
private Settings Settings { get; set; }
@@ -469,7 +471,7 @@ private Result CreateOpenWithMenu(SearchResult record)
private void LogException(string message, Exception e)
{
- Context.API.LogException(nameof(ContextMenu), message, e);
+ Context.API.LogException(ClassName, message, e);
}
private static bool CanRunAsDifferentUser(string path)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
index 1a0d3bd15d4..63174425282 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs
@@ -9,6 +9,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
{
public static class DirectoryInfoSearch
{
+ private static readonly string ClassName = nameof(DirectoryInfoSearch);
+
internal static IEnumerable TopLevelDirectorySearch(Query query, string search, CancellationToken token)
{
var criteria = ConstructSearchCriteria(search);
@@ -75,7 +77,7 @@ private static IEnumerable DirectorySearch(EnumerationOptions enum
}
catch (Exception e)
{
- Main.Context.API.LogException(nameof(DirectoryInfoSearch), "Error occurred while searching path", e);
+ Main.Context.API.LogException(ClassName, "Error occurred while searching path", e);
throw;
}
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index 4c07341ec2a..d7f44ccce51 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -12,6 +12,8 @@ namespace Flow.Launcher.Plugin.ProcessKiller
{
internal class ProcessHelper
{
+ private static readonly string ClassName = nameof(ProcessHelper);
+
private readonly HashSet _systemProcessList = new()
{
"conhost",
@@ -131,7 +133,7 @@ public void TryKill(PluginInitContext context, Process p)
}
catch (Exception e)
{
- context.API.LogException($"{nameof(ProcessHelper)}", $"Failed to kill process {p.ProcessName}", e);
+ context.API.LogException(ClassName, $"Failed to kill process {p.ProcessName}", e);
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
index 65be06b53ee..681c8b64967 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs
@@ -11,6 +11,8 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
public class Baidu : SuggestionSource
{
+ private static readonly string ClassName = nameof(Baidu);
+
private readonly Regex _reg = new Regex("window.baidu.sug\\((.*)\\)");
public override async Task> SuggestionsAsync(string query, CancellationToken token)
@@ -24,7 +26,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Main._context.API.LogException(nameof(Baidu), "Can't get suggestion from Baidu", e);
+ Main._context.API.LogException(ClassName, "Can't get suggestion from Baidu", e);
return null;
}
@@ -39,7 +41,7 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (JsonException e)
{
- Main._context.API.LogException(nameof(Baidu), "Can't parse suggestions", e);
+ Main._context.API.LogException(ClassName, "Can't parse suggestions", e);
return new List();
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
index 9efc36263c2..ccfa5dcc8a3 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs
@@ -10,6 +10,8 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
public class Bing : SuggestionSource
{
+ private static readonly string ClassName = nameof(Bing);
+
public override async Task> SuggestionsAsync(string query, CancellationToken token)
{
try
@@ -33,12 +35,12 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or { InnerException: TimeoutException })
{
- Main._context.API.LogException(nameof(Bing), "Can't get suggestion from Bing", e);
+ Main._context.API.LogException(ClassName, "Can't get suggestion from Bing", e);
return null;
}
catch (JsonException e)
{
- Main._context.API.LogException(nameof(Bing), "Can't parse suggestions", e);
+ Main._context.API.LogException(ClassName, "Can't parse suggestions", e);
return new List();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
index 1d248caf37a..0627f722099 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/DuckDuckGo.cs
@@ -10,6 +10,8 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
public class DuckDuckGo : SuggestionSource
{
+ private static readonly string ClassName = nameof(DuckDuckGo);
+
public override async Task> SuggestionsAsync(string query, CancellationToken token)
{
// When the search query is empty, DuckDuckGo returns `[]`. When it's not empty, it returns data
@@ -34,12 +36,12 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Main._context.API.LogException(nameof(DuckDuckGo), "Can't get suggestion from DuckDuckGo", e);
+ Main._context.API.LogException(ClassName, "Can't get suggestion from DuckDuckGo", e);
return null;
}
catch (JsonException e)
{
- Main._context.API.LogException(nameof(DuckDuckGo), "Can't parse suggestions", e);
+ Main._context.API.LogException(ClassName, "Can't parse suggestions", e);
return new List();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
index ad8fb508f09..f28212524ae 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs
@@ -10,6 +10,8 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
public class Google : SuggestionSource
{
+ private static readonly string ClassName = nameof(Google);
+
public override async Task> SuggestionsAsync(string query, CancellationToken token)
{
try
@@ -27,12 +29,12 @@ public override async Task> SuggestionsAsync(string query, Cancella
}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
- Main._context.API.LogException(nameof(Google), "Can't get suggestion from Google", e);
+ Main._context.API.LogException(ClassName, "Can't get suggestion from Google", e);
return null;
}
catch (JsonException e)
{
- Main._context.API.LogException(nameof(Google), "Can't parse suggestions", e);
+ Main._context.API.LogException(ClassName, "Can't parse suggestions", e);
return new List();
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs
index 257b0fa8b8d..c72230f2bfc 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Log.cs
@@ -11,10 +11,12 @@ public static void Init(IPublicAPI api)
{
_api = api;
}
+
public static void Exception(string message, Exception exception, Type type, [CallerMemberName] string methodName = "")
{
_api?.LogException(type.FullName, message, exception, methodName);
}
+
public static void Warn(string message, Type type, [CallerMemberName] string methodName = "")
{
_api?.LogWarn(type.FullName, message, methodName);
From 20d266138047225f5bf02d1d4041955422789789 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 18:04:50 +0800
Subject: [PATCH 1042/1335] Code quality
---
.../Environments/JavaScriptEnvironment.cs | 1 -
.../Environments/JavaScriptV2Environment.cs | 1 -
.../Environments/PythonEnvironment.cs | 5 ++++-
.../Environments/TypeScriptEnvironment.cs | 5 ++++-
.../Environments/TypeScriptV2Environment.cs | 5 ++++-
Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs | 14 +++++---------
6 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs
index b67059b1b6b..62d2d3e9181 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptEnvironment.cs
@@ -4,7 +4,6 @@
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
-
internal class JavaScriptEnvironment : TypeScriptEnvironment
{
internal override string Language => AllowedLanguage.JavaScript;
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs
index 6c8c5aa57c8..726bc4cd4e2 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/JavaScriptV2Environment.cs
@@ -4,7 +4,6 @@
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
-
internal class JavaScriptV2Environment : TypeScriptV2Environment
{
internal override string Language => AllowedLanguage.JavaScriptV2;
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
index fab5738de3b..455ee096da6 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/PythonEnvironment.cs
@@ -5,6 +5,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
+using Microsoft.VisualStudio.Threading;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -30,13 +31,15 @@ internal override string PluginsSettingsFilePath
internal PythonEnvironment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
+ private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
+
internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
- DroplexPackage.Drop(App.python_3_11_4_embeddable, InstallPath).Wait();
+ JTF.Run(() => DroplexPackage.Drop(App.python_3_11_4_embeddable, InstallPath));
PluginsSettingsFilePath = ExecutablePath;
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
index 8a4f527ba83..12965286f47 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptEnvironment.cs
@@ -5,6 +5,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
+using Microsoft.VisualStudio.Threading;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -27,11 +28,13 @@ internal override string PluginsSettingsFilePath
internal TypeScriptEnvironment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
+ private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
+
internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
- DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
+ JTF.Run(() => DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath));
PluginsSettingsFilePath = ExecutablePath;
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
index 61fd2837677..6960b79c9a7 100644
--- a/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/Environments/TypeScriptV2Environment.cs
@@ -5,6 +5,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
+using Microsoft.VisualStudio.Threading;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
@@ -27,11 +28,13 @@ internal override string PluginsSettingsFilePath
internal TypeScriptV2Environment(List pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
+ private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
+
internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));
- DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
+ JTF.Run(() => DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath));
PluginsSettingsFilePath = ExecutablePath;
}
diff --git a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
index bae2631573d..7a6bf07e2e3 100644
--- a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
+++ b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
@@ -1,21 +1,19 @@
-#nullable enable
-
-using System;
-using System.Collections.Generic;
+using System;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Meziantou.Framework.Win32;
-using Microsoft.VisualBasic.ApplicationServices;
using Nerdbank.Streams;
+#nullable enable
+
namespace Flow.Launcher.Core.Plugin
{
internal abstract class ProcessStreamPluginV2 : JsonRPCPluginV2
{
- private static JobObject _jobObject = new JobObject();
+ private static readonly JobObject _jobObject = new();
static ProcessStreamPluginV2()
{
@@ -66,11 +64,10 @@ private void SetupPipe(Process process)
ClientPipe = new DuplexPipe(reader, writer);
}
-
public override async Task ReloadDataAsync()
{
var oldProcess = ClientProcess;
- ClientProcess = Process.Start(StartInfo);
+ ClientProcess = Process.Start(StartInfo)!;
ArgumentNullException.ThrowIfNull(ClientProcess);
SetupPipe(ClientProcess);
await base.ReloadDataAsync();
@@ -79,7 +76,6 @@ public override async Task ReloadDataAsync()
oldProcess.Dispose();
}
-
public override async ValueTask DisposeAsync()
{
await base.DisposeAsync();
From 43dbf1a0ee013bcfda2bd9d43a1c22863a72e9b9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 18:13:55 +0800
Subject: [PATCH 1043/1335] Remove useless functions & Fix debug issue
---
Flow.Launcher.Core/Plugin/PluginsLoader.cs | 8 +--
Flow.Launcher.Infrastructure/Logger/Log.cs | 64 +---------------------
Flow.Launcher/ViewModel/MainViewModel.cs | 4 +-
3 files changed, 7 insertions(+), 69 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
index 1010d9f083b..256c36065a9 100644
--- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs
+++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs
@@ -89,19 +89,19 @@ private static IEnumerable DotNetPlugins(List source
#else
catch (Exception e) when (assembly == null)
{
- Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e);
+ Log.Exception(ClassName, $"Couldn't load assembly for the plugin: {metadata.Name}", e);
}
catch (InvalidOperationException e)
{
- Log.Exception($"|PluginsLoader.DotNetPlugins|Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e);
+ Log.Exception(ClassName, $"Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e);
}
catch (ReflectionTypeLoadException e)
{
- Log.Exception($"|PluginsLoader.DotNetPlugins|The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e);
+ Log.Exception(ClassName, $"The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e);
}
catch (Exception e)
{
- Log.Exception($"|PluginsLoader.DotNetPlugins|The following plugin has errored and can not be loaded: <{metadata.Name}>", e);
+ Log.Exception(ClassName, $"The following plugin has errored and can not be loaded: <{metadata.Name}>", e);
}
#endif
diff --git a/Flow.Launcher.Infrastructure/Logger/Log.cs b/Flow.Launcher.Infrastructure/Logger/Log.cs
index 25cfbbd3d91..09eb98f46be 100644
--- a/Flow.Launcher.Infrastructure/Logger/Log.cs
+++ b/Flow.Launcher.Infrastructure/Logger/Log.cs
@@ -94,13 +94,6 @@ private static void LogFaultyFormat(string message)
logger.Fatal(message);
}
- private static bool FormatValid(string message)
- {
- var parts = message.Split('|');
- var valid = parts.Length == 3 && !string.IsNullOrWhiteSpace(parts[1]) && !string.IsNullOrWhiteSpace(parts[2]);
- return valid;
- }
-
public static void Exception(string className, string message, System.Exception exception, [CallerMemberName] string methodName = "")
{
exception = exception.Demystify();
@@ -135,57 +128,14 @@ private static string CheckClassAndMessageAndReturnFullClassWithMethod(string cl
return className;
}
+#if !DEBUG
private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
{
var logger = LogManager.GetLogger(classAndMethod);
logger.Error(e, message);
}
-
- private static void LogInternal(string message, LogLevel level)
- {
- if (FormatValid(message))
- {
- var parts = message.Split('|');
- var prefix = parts[1];
- var unprefixed = parts[2];
- var logger = LogManager.GetLogger(prefix);
- logger.Log(level, unprefixed);
- }
- else
- {
- LogFaultyFormat(message);
- }
- }
-
- /// Example: "|ClassName.MethodName|Message"
- /// Example: "|ClassName.MethodName|Message"
- /// Exception
- public static void Exception(string message, System.Exception e)
- {
- e = e.Demystify();
-#if DEBUG
- ExceptionDispatchInfo.Capture(e).Throw();
-#else
- if (FormatValid(message))
- {
- var parts = message.Split('|');
- var prefix = parts[1];
- var unprefixed = parts[2];
- ExceptionInternal(prefix, unprefixed, e);
- }
- else
- {
- LogFaultyFormat(message);
- }
#endif
- }
-
- /// Example: "|ClassName.MethodName|Message"
- public static void Error(string message)
- {
- LogInternal(message, LogLevel.Error);
- }
public static void Error(string className, string message, [CallerMemberName] string methodName = "")
{
@@ -206,23 +156,11 @@ public static void Debug(string className, string message, [CallerMemberName] st
LogInternal(LogLevel.Debug, className, message, methodName);
}
- /// Example: "|ClassName.MethodName|Message""
- public static void Debug(string message)
- {
- LogInternal(message, LogLevel.Debug);
- }
-
public static void Info(string className, string message, [CallerMemberName] string methodName = "")
{
LogInternal(LogLevel.Info, className, message, methodName);
}
- /// Example: "|ClassName.MethodName|Message"
- public static void Info(string message)
- {
- LogInternal(message, LogLevel.Info);
- }
-
public static void Warn(string className, string message, [CallerMemberName] string methodName = "")
{
LogInternal(LogLevel.Warn, className, message, methodName);
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 998fdb9068c..00675149b41 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -222,7 +222,7 @@ void continueAction(Task t)
#if DEBUG
throw t.Exception;
#else
- Log.Error($"Error happen in task dealing with viewupdate for results. {t.Exception}");
+ App.API.LogError(ClassName, $"Error happen in task dealing with viewupdate for results. {t.Exception}");
_resultsViewUpdateTask =
Task.Run(UpdateActionAsync).ContinueWith(continueAction, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
#endif
@@ -892,7 +892,7 @@ public bool InternalPreviewVisible
#if DEBUG
throw new NotImplementedException("ResultAreaColumn should match ResultAreaColumnPreviewShown/ResultAreaColumnPreviewHidden value");
#else
- Log.Error("MainViewModel", "ResultAreaColumnPreviewHidden/ResultAreaColumnPreviewShown int value not implemented", "InternalPreviewVisible");
+ App.API.LogError(ClassName, "ResultAreaColumnPreviewHidden/ResultAreaColumnPreviewShown int value not implemented", "InternalPreviewVisible");
return false;
#endif
}
From 3fab9da633f5d7a13b28b379f43ac93bf170858a Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sun, 13 Apr 2025 18:14:39 +0800
Subject: [PATCH 1044/1335] Fix incorrect class name reference
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
Flow.Launcher/ViewModel/ResultViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index ef7e24c3bd8..648ac49bbf2 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -13,7 +13,7 @@ namespace Flow.Launcher.ViewModel
{
public class ResultViewModel : BaseModel
{
- private static readonly string ClassName = nameof(ResultsViewModel);
+ private static readonly string ClassName = nameof(ResultViewModel);
private static readonly PrivateFontCollection FontCollection = new();
private static readonly Dictionary Fonts = new();
From eec6145e1aca49f36be49a8b36099e8865ab97cf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 13 Apr 2025 20:35:27 +0800
Subject: [PATCH 1045/1335] Fix possible win32 exception
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 54604a27118..6be0243899a 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -376,7 +376,8 @@ public static unsafe void SwitchToEnglishKeyboardLayout(bool backupPrevious)
if (!IsForegroundWindow(hwnd))
{
var result = PInvoke.SetForegroundWindow(hwnd);
- if (!result) throw new Win32Exception(Marshal.GetLastWin32Error());
+ // If we cannot set the foreground window, we can use the foreground window and switch the layout
+ if (!result) hwnd = PInvoke.GetForegroundWindow();
}
// Get the current foreground window thread ID
From 0bdfaac6a9d2c73bce84ec9b4c5b2715da4c9a3f Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Mon, 14 Apr 2025 21:37:15 +1000
Subject: [PATCH 1046/1335] Add sponsor
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index cbb553bd129..d8ecfa67115 100644
--- a/README.md
+++ b/README.md
@@ -351,6 +351,7 @@ Or download the [early access version](https://github.com/Flow-Launcher/Prerelea
+
From f8396892940ca99bb1e2c471408b1b4f18277969 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 15 Apr 2025 05:54:46 +0900
Subject: [PATCH 1047/1335] Add Content Dialog owner
---
Flow.Launcher/HotkeyControl.xaml.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index 8762a934bbb..9af3b71aafa 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -243,6 +243,9 @@ private async Task OpenHotkeyDialogAsync()
}
var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle);
+
+ dialog.Owner = Window.GetWindow(this);
+
await dialog.ShowAsync();
switch (dialog.ResultType)
{
From 9035aa6fab026722ef5ca71ebc3d55b0cfcfea69 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 08:41:20 +0800
Subject: [PATCH 1048/1335] Fix dialog owner for all content dialog
---
Flow.Launcher/HotkeyControl.xaml.cs | 13 +++++++------
.../ViewModels/SettingsPanePluginsViewModel.cs | 3 +--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs
index 9af3b71aafa..26272712757 100644
--- a/Flow.Launcher/HotkeyControl.xaml.cs
+++ b/Flow.Launcher/HotkeyControl.xaml.cs
@@ -1,6 +1,4 @@
-#nullable enable
-
-using System.Collections.ObjectModel;
+using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
@@ -9,6 +7,8 @@
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
+#nullable enable
+
namespace Flow.Launcher
{
public partial class HotkeyControl
@@ -242,9 +242,10 @@ private async Task OpenHotkeyDialogAsync()
HotKeyMapper.RemoveHotkey(Hotkey);
}
- var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle);
-
- dialog.Owner = Window.GetWindow(this);
+ var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle)
+ {
+ Owner = Window.GetWindow(this)
+ };
await dialog.ShowAsync();
switch (dialog.ResultType)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index b89e970e99b..916fd1ecee8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -5,7 +5,6 @@
using System.Windows;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
@@ -116,6 +115,7 @@ private async Task OpenHelperAsync()
{
var helpDialog = new ContentDialog()
{
+ Owner = Application.Current.MainWindow,
Content = new StackPanel
{
Children =
@@ -146,7 +146,6 @@ private async Task OpenHelperAsync()
}
}
},
-
PrimaryButtonText = (string)Application.Current.Resources["commonOK"],
CornerRadius = new CornerRadius(8),
Style = (Style)Application.Current.Resources["ContentDialog"]
From 28c7538fc3b00bc88a62336bba79d04a0b841fc3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 09:06:31 +0800
Subject: [PATCH 1049/1335] Fix possible Win32Exception
---
Flow.Launcher.Infrastructure/Win32Helper.cs | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 6be0243899a..798501ae3fd 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -365,21 +365,10 @@ public static unsafe void SwitchToEnglishKeyboardLayout(bool backupPrevious)
// No installed English layout found
if (enHKL == HKL.Null) return;
- // When application is exiting, the Application.Current will be null
- if (Application.Current == null) return;
-
- // Get the FL main window
- var hwnd = GetWindowHandle(Application.Current.MainWindow, true);
+ // Get the foreground window
+ var hwnd = PInvoke.GetForegroundWindow();
if (hwnd == HWND.Null) return;
- // Check if the FL main window is the current foreground window
- if (!IsForegroundWindow(hwnd))
- {
- var result = PInvoke.SetForegroundWindow(hwnd);
- // If we cannot set the foreground window, we can use the foreground window and switch the layout
- if (!result) hwnd = PInvoke.GetForegroundWindow();
- }
-
// Get the current foreground window thread ID
var threadId = PInvoke.GetWindowThreadProcessId(hwnd);
if (threadId == 0) throw new Win32Exception(Marshal.GetLastWin32Error());
From d21ffce47af56b25bbf14e36d7b475ce3e7f4689 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 12:21:56 +0800
Subject: [PATCH 1050/1335] Use get window to get owner
---
.../SettingPages/ViewModels/SettingsPanePluginsViewModel.cs | 4 ++--
Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index 916fd1ecee8..de7cf15c399 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -111,11 +111,11 @@ public SettingsPanePluginsViewModel(Settings settings)
.ToList();
[RelayCommand]
- private async Task OpenHelperAsync()
+ private async Task OpenHelperAsync(Button button)
{
var helpDialog = new ContentDialog()
{
- Owner = Application.Current.MainWindow,
+ Owner = Window.GetWindow(button),
Content = new StackPanel
{
Children =
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index f9f7083147b..f3d63030625 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -57,6 +57,7 @@
Height="34"
Margin="0 0 20 0"
Command="{Binding OpenHelperCommand}"
+ CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content=""
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="14" />
From c382732f974d99211b4d739340f6fcd7fa3cedc9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 12:49:09 +0800
Subject: [PATCH 1051/1335] Improve windows exiting
---
Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 043eb7a190a..39bf4965494 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -362,6 +362,7 @@ private List Commands()
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe89f"),
Action = c =>
{
+ _context.API.HideMainWindow();
Application.Current.MainWindow.Close();
return true;
}
From 8e51096ba9ded910e3c2c2906404e5bc5f247701 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 12:51:38 +0800
Subject: [PATCH 1052/1335] Improve log messages
---
Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
index a49385a02b1..86df01a3015 100644
--- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs
@@ -171,8 +171,8 @@ private static async ValueTask LoadInternalAsync(string path, bool
}
catch (System.Exception e2)
{
- Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
- Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
+ Log.Exception(ClassName, $"Failed to get thumbnail for {path} on first try", e);
+ Log.Exception(ClassName, $"Failed to get thumbnail for {path} on second try", e2);
ImageSource image = ImageCache[Constant.MissingImgIcon, false];
ImageCache[path, false] = image;
From a1b5941039da7370ee3c69d2c90ec61d7859ce35 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 12:52:09 +0800
Subject: [PATCH 1053/1335] Improve WindowsThumbnailProvider
---
.../Image/ThumbnailReader.cs | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index b98ea50fe48..fe389a33134 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -12,7 +12,7 @@
namespace Flow.Launcher.Infrastructure.Image
{
///
- /// Subclass of
+ /// Subclass of
///
[Flags]
public enum ThumbnailOptions
@@ -33,6 +33,8 @@ public class WindowsThumbnailProvider
private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
+ private static readonly HRESULT S_PATHNOTFOUND = (HRESULT)0x8004B205;
+
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
@@ -79,9 +81,10 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
- catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
+ catch (COMException ex) when (options == ThumbnailOptions.ThumbnailOnly &&
+ (ex.HResult == S_PATHNOTFOUND || ex.HResult == S_ExtractionFailed))
{
- // Fallback to IconOnly if ThumbnailOnly fails
+ // Fallback to IconOnly if extraction fails or files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
catch (FileNotFoundException) when (options == ThumbnailOptions.ThumbnailOnly)
@@ -89,6 +92,11 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
// Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
+ catch (System.Exception ex)
+ {
+ // Handle other exceptions
+ throw new InvalidOperationException("Failed to get thumbnail", ex);
+ }
}
finally
{
From 83fa654e2733ef28af1bef3d4f85ac607b1000b9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 12:59:58 +0800
Subject: [PATCH 1054/1335] Improve constant name
---
Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
index fe389a33134..4ce0df0260d 100644
--- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
+++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs
@@ -31,7 +31,7 @@ public class WindowsThumbnailProvider
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
- private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
+ private static readonly HRESULT S_EXTRACTIONFAILED = (HRESULT)0x8004B200;
private static readonly HRESULT S_PATHNOTFOUND = (HRESULT)0x8004B205;
@@ -82,7 +82,7 @@ private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height,
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
catch (COMException ex) when (options == ThumbnailOptions.ThumbnailOnly &&
- (ex.HResult == S_PATHNOTFOUND || ex.HResult == S_ExtractionFailed))
+ (ex.HResult == S_PATHNOTFOUND || ex.HResult == S_EXTRACTIONFAILED))
{
// Fallback to IconOnly if extraction fails or files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
From 81007f79aee6ca7671880afaa8e329e99bacb9f4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:18:06 +0800
Subject: [PATCH 1055/1335] Remove mvvm command for code quality
---
Flow.Launcher/ViewModel/RelayCommand.cs | 29 ----------
.../Flow.Launcher.Plugin.Explorer.csproj | 1 +
.../ViewModels/RelayCommand.cs | 27 ---------
.../ViewModels/SettingsViewModel.cs | 55 +++++++------------
.../Views/ExplorerSettings.xaml | 6 +-
5 files changed, 24 insertions(+), 94 deletions(-)
delete mode 100644 Flow.Launcher/ViewModel/RelayCommand.cs
delete mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/RelayCommand.cs
diff --git a/Flow.Launcher/ViewModel/RelayCommand.cs b/Flow.Launcher/ViewModel/RelayCommand.cs
deleted file mode 100644
index e8d4af8b526..00000000000
--- a/Flow.Launcher/ViewModel/RelayCommand.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Windows.Input;
-
-namespace Flow.Launcher.ViewModel
-{
- public class RelayCommand : ICommand
- {
- private readonly Action _action;
-
- public RelayCommand(Action action)
- {
- _action = action;
- }
-
- public virtual bool CanExecute(object parameter)
- {
- return true;
- }
-
-#pragma warning disable CS0067 // the event is never used
- public event EventHandler CanExecuteChanged;
-#pragma warning restore CS0067
-
- public virtual void Execute(object parameter)
- {
- _action?.Invoke(parameter);
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index 54921702730..f13460d3f54 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -46,6 +46,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/RelayCommand.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/RelayCommand.cs
deleted file mode 100644
index ff704b67979..00000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/RelayCommand.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Windows.Input;
-
-namespace Flow.Launcher.Plugin.Explorer.ViewModels
-{
- internal class RelayCommand : ICommand
- {
- private Action _action;
-
- public RelayCommand(Action action)
- {
- _action = action;
- }
-
- public virtual bool CanExecute(object parameter)
- {
- return true;
- }
-
- public event EventHandler CanExecuteChanged;
-
- public virtual void Execute(object parameter)
- {
- _action?.Invoke(parameter);
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 4073009249b..cf9ebd33fee 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -1,9 +1,4 @@
#nullable enable
-using Flow.Launcher.Plugin.Explorer.Search;
-using Flow.Launcher.Plugin.Explorer.Search.Everything;
-using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
-using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using Flow.Launcher.Plugin.Explorer.Views;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -13,11 +8,16 @@
using System.Linq;
using System.Windows;
using System.Windows.Forms;
-using System.Windows.Input;
+using CommunityToolkit.Mvvm.Input;
+using Flow.Launcher.Plugin.Explorer.Search;
+using Flow.Launcher.Plugin.Explorer.Search.Everything;
+using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
+using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
+using Flow.Launcher.Plugin.Explorer.Views;
namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
- public class SettingsViewModel : BaseModel
+ public partial class SettingsViewModel : BaseModel
{
public Settings Settings { get; set; }
@@ -36,7 +36,6 @@ public SettingsViewModel(PluginInitContext context, Settings settings)
InitializeActionKeywordModels();
}
-
public void Save()
{
Context.API.SaveSettingJsonStorage();
@@ -48,7 +47,6 @@ public void Save()
private EnumBindingModel _selectedContentSearchEngine;
private EnumBindingModel _selectedPathEnumerationEngine;
-
public EnumBindingModel SelectedIndexSearchEngine
{
get => _selectedIndexSearchEngine;
@@ -261,8 +259,7 @@ private void InitializeActionKeywordModels()
public ActionKeywordModel? SelectedActionKeyword { get; set; }
- public ICommand EditActionKeywordCommand => new RelayCommand(EditActionKeyword);
-
+ [RelayCommand]
private void EditActionKeyword(object obj)
{
if (SelectedActionKeyword is not { } actionKeyword)
@@ -307,12 +304,6 @@ private void EditActionKeyword(object obj)
public AccessLink? SelectedQuickAccessLink { get; set; }
public AccessLink? SelectedIndexSearchExcludedPath { get; set; }
-
-
- public ICommand RemoveLinkCommand => new RelayCommand(RemoveLink);
- public ICommand EditLinkCommand => new RelayCommand(EditLink);
- public ICommand AddLinkCommand => new RelayCommand(AddLink);
-
public void AppendLink(string containerName, AccessLink link)
{
var container = containerName switch
@@ -324,6 +315,7 @@ public void AppendLink(string containerName, AccessLink link)
container.Add(link);
}
+ [RelayCommand]
private void EditLink(object commandParameter)
{
var (selectedLink, collection) = commandParameter switch
@@ -360,7 +352,7 @@ private void ShowUnselectedMessage()
Context.API.ShowMsgBox(warning);
}
-
+ [RelayCommand]
private void AddLink(object commandParameter)
{
var container = commandParameter switch
@@ -385,6 +377,7 @@ private void AddLink(object commandParameter)
container.Add(newAccessLink);
}
+ [RelayCommand]
private void RemoveLink(object obj)
{
if (obj is not string container) return;
@@ -435,7 +428,6 @@ private void RemoveLink(object obj)
return path;
}
-
internal static void OpenWindowsIndexingOptions()
{
var psi = new ProcessStartInfo
@@ -448,39 +440,35 @@ internal static void OpenWindowsIndexingOptions()
Process.Start(psi);
}
- private ICommand? _openFileEditorPathCommand;
-
- public ICommand OpenFileEditorPath => _openFileEditorPathCommand ??= new RelayCommand(_ =>
+ [RelayCommand]
+ private void OpenFileEditorPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
FileEditorPath = path;
- });
-
- private ICommand? _openFolderEditorPathCommand;
+ }
- public ICommand OpenFolderEditorPath => _openFolderEditorPathCommand ??= new RelayCommand(_ =>
+ [RelayCommand]
+ private void OpenFolderEditorPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.FolderEditorPath != null ? Path.GetDirectoryName(Settings.FolderEditorPath) : null);
if (path is null)
return;
FolderEditorPath = path;
- });
-
- private ICommand? _openShellPathCommand;
+ }
- public ICommand OpenShellPath => _openShellPathCommand ??= new RelayCommand(_ =>
+ [RelayCommand]
+ private void OpenShellPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
ShellPath = path;
- });
-
+ }
public string FileEditorPath
{
@@ -537,7 +525,6 @@ public int MaxResult
}
}
-
#region Everything FastSortWarning
public Visibility FastSortWarningVisibility
@@ -593,7 +580,5 @@ public string EverythingInstalledPath
}
#endregion
-
-
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 6ca7be84db6..e5999da4166 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -245,7 +245,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
- Command="{Binding OpenFileEditorPath}"
+ Command="{Binding OpenFileEditorPathCommand}"
Content="{DynamicResource select}" />
@@ -272,7 +272,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
- Command="{Binding OpenFolderEditorPath}"
+ Command="{Binding OpenFolderEditorPathCommand}"
Content="{DynamicResource select}" />
@@ -299,7 +299,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
- Command="{Binding OpenShellPath}"
+ Command="{Binding OpenShellPathCommand}"
Content="{DynamicResource select}" />
From 1e603ea20f800704b939ccf1941a8d14d8274f73 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:21:00 +0800
Subject: [PATCH 1056/1335] Code quality
---
.../Helper/SortOptionTranslationHelper.cs | 2 +-
.../Views/ActionKeywordSetting.xaml.cs | 3 +++
.../Views/ExplorerSettings.xaml.cs | 12 +++---------
3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/SortOptionTranslationHelper.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/SortOptionTranslationHelper.cs
index 0a3a2ae43eb..72f58f5b60c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/SortOptionTranslationHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/SortOptionTranslationHelper.cs
@@ -16,7 +16,7 @@ public static string GetTranslatedName(this SortOption sortOption)
ArgumentNullException.ThrowIfNull(API);
var enumName = Enum.GetName(sortOption);
- var splited = enumName.Split('_');
+ var splited = enumName!.Split('_');
var name = string.Join('_', splited[..^1]);
var direction = splited[^1];
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
index 73c35b1c845..000b2558d14 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
@@ -85,6 +85,7 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
DialogResult = false;
Close();
}
+
private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
@@ -94,11 +95,13 @@ private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
e.Handled = true;
}
}
+
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+
private bool SetField(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value))
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
index b7f5efc3cc7..9203ece9ae5 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
@@ -1,11 +1,10 @@
-using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using Flow.Launcher.Plugin.Explorer.ViewModels;
-using System.Collections.Generic;
-using System.ComponentModel;
+using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
+using Flow.Launcher.Plugin.Explorer.ViewModels;
using DataFormats = System.Windows.DataFormats;
using DragDropEffects = System.Windows.DragDropEffects;
using DragEventArgs = System.Windows.DragEventArgs;
@@ -19,9 +18,6 @@ public partial class ExplorerSettings
{
private readonly SettingsViewModel viewModel;
- private List actionKeywordsListView;
-
-
public ExplorerSettings(SettingsViewModel viewModel)
{
DataContext = viewModel;
@@ -39,8 +35,6 @@ public ExplorerSettings(SettingsViewModel viewModel)
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
}
-
-
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
From 1d16b30b64924af0b51dedf4d6f7f9186e9d1984 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:22:22 +0800
Subject: [PATCH 1057/1335] Suppress async void
---
Flow.Launcher/Msg.xaml.cs | 1 +
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs | 4 ++++
.../SearchSourceSetting.xaml.cs | 2 ++
3 files changed, 7 insertions(+)
diff --git a/Flow.Launcher/Msg.xaml.cs b/Flow.Launcher/Msg.xaml.cs
index 110235cb5ac..923c3692f8e 100644
--- a/Flow.Launcher/Msg.xaml.cs
+++ b/Flow.Launcher/Msg.xaml.cs
@@ -59,6 +59,7 @@ private void fadeOutStoryboard_Completed(object sender, EventArgs e)
Close();
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
public async void Show(string title, string subTitle, string iconPath)
{
tbTitle.Text = title;
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index c42bd4f305d..deb110698b3 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -146,6 +146,7 @@ private void ViewRefresh()
programSourceView.Items.Refresh();
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void ReIndexing()
{
ViewRefresh();
@@ -183,6 +184,7 @@ private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
EditProgramSource(selectedProgramSource);
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void EditProgramSource(ProgramSource selectedProgramSource)
{
if (selectedProgramSource == null)
@@ -277,6 +279,7 @@ private void programSourceView_Drop(object sender, DragEventArgs e)
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArgs e)
{
await ProgramSettingDisplay.DisplayAllProgramsAsync();
@@ -284,6 +287,7 @@ private async void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArg
ViewRefresh();
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
{
var selectedItems = programSourceView
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
index 58577dbc18a..b44f130e47b 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs
@@ -28,6 +28,7 @@ public SearchSourceSettingWindow(IList sources, PluginInitContext
Initialize(sources, context, Action.Add);
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void Initialize(IList sources, PluginInitContext context, Action action)
{
InitializeComponent();
@@ -124,6 +125,7 @@ private void EditSearchSource()
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
private async void OnSelectIconClick(object sender, RoutedEventArgs e)
{
const string filter = "Image files (*.jpg, *.jpeg, *.gif, *.png, *.bmp) |*.jpg; *.jpeg; *.gif; *.png; *.bmp";
From abee9ba01550f3371c2018b5d50e97a9d8f5f3a7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:24:25 +0800
Subject: [PATCH 1058/1335] Fix nullable warning
---
.../ViewModels/ActionKeywordModel.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
index 2f614ead80d..d4cd1348e9b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/ActionKeywordModel.cs
@@ -1,13 +1,15 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
+#nullable enable
+
namespace Flow.Launcher.Plugin.Explorer.Views
{
public class ActionKeywordModel : INotifyPropertyChanged
{
- private static Settings _settings;
+ private static Settings _settings = null!;
- public event PropertyChangedEventHandler PropertyChanged;
+ public event PropertyChangedEventHandler? PropertyChanged;
public static void Init(Settings settings)
{
@@ -54,4 +56,4 @@ public bool Enabled
}
}
}
-}
\ No newline at end of file
+}
From 113bc589bda874eeba207d867032d0465cd12e43 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:24:41 +0800
Subject: [PATCH 1059/1335] Remove unused variable
---
Flow.Launcher/ReportWindow.xaml.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher/ReportWindow.xaml.cs b/Flow.Launcher/ReportWindow.xaml.cs
index 0ab785a17b6..24801cf52f3 100644
--- a/Flow.Launcher/ReportWindow.xaml.cs
+++ b/Flow.Launcher/ReportWindow.xaml.cs
@@ -15,8 +15,6 @@ namespace Flow.Launcher
{
internal partial class ReportWindow
{
- private static readonly string ClassName = nameof(ReportWindow);
-
public ReportWindow(Exception exception)
{
InitializeComponent();
From 5df56334eee4b0647803755d5713042a1e1c1ba7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:28:47 +0800
Subject: [PATCH 1060/1335] Code quality
---
.../Helper/ShellContextMenu.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs
index abb76580d32..58b4e86f9f9 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenu.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
@@ -341,7 +341,7 @@ protected IntPtr[] GetPIDLs(DirectoryInfo[] arrFI)
return null;
}
- IShellFolder oParentFolder = GetParentFolder(arrFI[0].Parent.FullName);
+ IShellFolder oParentFolder = GetParentFolder(arrFI[0].Parent!.FullName);
if (null == oParentFolder)
{
return null;
@@ -1535,7 +1535,7 @@ public void Install()
m_hookType,
m_filterFunc,
IntPtr.Zero,
- (int)AppDomain.GetCurrentThreadId());
+ Environment.CurrentManagedThreadId);
}
// ************************************************************************
From 222ef41c8f755fc76109f9c9f040863f583ec1ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:29:26 +0800
Subject: [PATCH 1061/1335] Fix nullabl warnings
---
.../Search/EnvironmentVariables.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs
index e526fb85a1f..6c4e6a3ed8f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs
@@ -47,7 +47,7 @@ private static void LoadEnvironmentStringPaths()
foreach (DictionaryEntry special in Environment.GetEnvironmentVariables())
{
- var path = special.Value.ToString();
+ var path = special.Value!.ToString();
// we add a trailing slash to the path to make sure drive paths become valid absolute paths.
// for example, if %systemdrive% is C: we turn it to C:\
path = path.EnsureTrailingSlash();
@@ -61,7 +61,7 @@ private static void LoadEnvironmentStringPaths()
{
// Variables are returned with a mixture of all upper/lower case.
// Call ToUpper() to make the results look consistent
- _envStringPaths.Add(special.Key.ToString().ToUpper(), path);
+ _envStringPaths.Add(special.Key.ToString()!.ToUpper(), path);
}
}
}
From a3daac66ecc997020e13e4924c2a9318acdd080e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:30:46 +0800
Subject: [PATCH 1062/1335] Code quality
---
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index 22de4fcc082..f4c103ade01 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -1,8 +1,8 @@
-using System.Windows.Navigation;
+using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
-using Page = ModernWpf.Controls.Page;
using Flow.Launcher.Infrastructure.UserSettings;
+using Page = ModernWpf.Controls.Page;
namespace Flow.Launcher.SettingPages.Views;
From 476829045d8eb9cbec9faae7fa4f298f65c3cfa8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 13:36:32 +0800
Subject: [PATCH 1063/1335] Adjust code comments
---
.../Flow.Launcher.Plugin.Explorer.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index f13460d3f54..98164f48971 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -45,8 +45,8 @@
-
+
From f5830412c4acd994b875c4ed3b6c185bc41621db Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 20:45:00 +0800
Subject: [PATCH 1064/1335] Revert delegate to fields
---
Flow.Launcher.Plugin/Result.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index f561fcb1dcf..f0fcd48ffc0 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -128,12 +128,12 @@ public string BadgeIcoPath
///
/// Delegate to load an icon for this result.
///
- public IconDelegate Icon { get; set; }
+ public IconDelegate Icon = null;
///
/// Delegate to load an icon for the badge of this result.
///
- public IconDelegate BadgeIcon { get; set; }
+ public IconDelegate BadgeIcon = null;
///
/// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons)
From 652e3bde86f67ad5cdd58a7000d1e77a5526f8c9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 21:21:27 +0800
Subject: [PATCH 1065/1335] Improve process killer performance
---
.../ProcessHelper.cs | 43 ++++++++++++++-----
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
index d7f44ccce51..3867829058f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ProcessHelper.cs
@@ -1,9 +1,11 @@
-using Microsoft.Win32.SafeHandles;
-using System;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Win32.SafeHandles;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Threading;
@@ -72,8 +74,21 @@ public List GetMatchingProcesses()
///
public static unsafe Dictionary GetProcessesWithNonEmptyWindowTitle()
{
- var processDict = new Dictionary();
+ // Collect all window handles
+ var windowHandles = new List();
PInvoke.EnumWindows((hWnd, _) =>
+ {
+ if (PInvoke.IsWindowVisible(hWnd))
+ {
+ windowHandles.Add(hWnd);
+ }
+ return true;
+ }, IntPtr.Zero);
+
+ // Concurrently process each window handle
+ var processDict = new ConcurrentDictionary();
+ var processedProcessIds = new ConcurrentDictionary();
+ Parallel.ForEach(windowHandles, hWnd =>
{
var windowTitle = GetWindowTitle(hWnd);
if (!string.IsNullOrWhiteSpace(windowTitle) && PInvoke.IsWindowVisible(hWnd))
@@ -82,20 +97,26 @@ public static unsafe Dictionary GetProcessesWithNonEmptyWindowTitle
var result = PInvoke.GetWindowThreadProcessId(hWnd, &processId);
if (result == 0u || processId == 0u)
{
- return false;
+ return;
}
- var process = Process.GetProcessById((int)processId);
- if (!processDict.ContainsKey((int)processId))
+ // Ensure each process ID is processed only once
+ if (processedProcessIds.TryAdd((int)processId, 0))
{
- processDict.Add((int)processId, windowTitle);
+ try
+ {
+ var process = Process.GetProcessById((int)processId);
+ processDict.TryAdd((int)processId, windowTitle);
+ }
+ catch
+ {
+ // Handle exceptions (e.g., process exited)
+ }
}
}
+ });
- return true;
- }, IntPtr.Zero);
-
- return processDict;
+ return new Dictionary(processDict);
}
private static unsafe string GetWindowTitle(HWND hwnd)
From 814afc75dd7ba9254c8cdfeaa6c567204223229e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 21:21:47 +0800
Subject: [PATCH 1066/1335] Add option to let process killer show window title
---
.../Flow.Launcher.Plugin.ProcessKiller/Languages/en.xaml | 1 +
Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs | 4 +++-
Plugins/Flow.Launcher.Plugin.ProcessKiller/Settings.cs | 2 ++
.../ViewModels/SettingsViewModel.cs | 6 ++++++
.../Views/SettingsControl.xaml | 6 ++++++
5 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/en.xaml
index ea6e54fef7a..ddabd31f8fd 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/en.xaml
@@ -10,6 +10,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
index 4f5d1becdd9..3f505139a1e 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -81,7 +81,9 @@ private List CreateResultsFromQuery(Query query)
// Filter processes based on search term
var searchTerm = query.Search;
var processlist = new List();
- var processWindowTitle = ProcessHelper.GetProcessesWithNonEmptyWindowTitle();
+ var processWindowTitle = Settings.ShowWindowTitle ?
+ ProcessHelper.GetProcessesWithNonEmptyWindowTitle() :
+ new Dictionary();
if (string.IsNullOrWhiteSpace(searchTerm))
{
foreach (var p in allPocessList)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Settings.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Settings.cs
index 916bc6a3979..57cd2ab8697 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Settings.cs
@@ -2,6 +2,8 @@
{
public class Settings
{
+ public bool ShowWindowTitle { get; set; } = true;
+
public bool PutVisibleWindowProcessesTop { get; set; } = false;
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs
index bacf1ba08c9..0728d9c0fb5 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/ViewModels/SettingsViewModel.cs
@@ -9,6 +9,12 @@ public SettingsViewModel(Settings settings)
Settings = settings;
}
+ public bool ShowWindowTitle
+ {
+ get => Settings.ShowWindowTitle;
+ set => Settings.ShowWindowTitle = value;
+ }
+
public bool PutVisibleWindowProcessesTop
{
get => Settings.PutVisibleWindowProcessesTop;
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Views/SettingsControl.xaml
index d15d6c3e084..b969be4e877 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Views/SettingsControl.xaml
@@ -12,10 +12,16 @@
+
+
From 0cbd7ba1e2f422ee98960ea4bf2e0ff35633bde0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 15 Apr 2025 23:42:08 +0800
Subject: [PATCH 1067/1335] Improve option logic
---
.../Main.cs | 36 ++++++++++++++-----
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
index 3f505139a1e..8f5ba4bd237 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Main.cs
@@ -81,7 +81,8 @@ private List CreateResultsFromQuery(Query query)
// Filter processes based on search term
var searchTerm = query.Search;
var processlist = new List();
- var processWindowTitle = Settings.ShowWindowTitle ?
+ var processWindowTitle =
+ Settings.ShowWindowTitle || Settings.PutVisibleWindowProcessesTop ?
ProcessHelper.GetProcessesWithNonEmptyWindowTitle() :
new Dictionary();
if (string.IsNullOrWhiteSpace(searchTerm))
@@ -93,12 +94,22 @@ private List CreateResultsFromQuery(Query query)
if (processWindowTitle.TryGetValue(p.Id, out var windowTitle))
{
// Add score to prioritize processes with visible windows
- // And use window title for those processes
- processlist.Add(new ProcessResult(p, Settings.PutVisibleWindowProcessesTop ? 200 : 0, windowTitle, null, progressNameIdTitle));
+ // Use window title for those processes if enabled
+ processlist.Add(new ProcessResult(
+ p,
+ Settings.PutVisibleWindowProcessesTop ? 200 : 0,
+ Settings.ShowWindowTitle ? windowTitle : progressNameIdTitle,
+ null,
+ progressNameIdTitle));
}
else
{
- processlist.Add(new ProcessResult(p, 0, progressNameIdTitle, null, progressNameIdTitle));
+ processlist.Add(new ProcessResult(
+ p,
+ 0,
+ progressNameIdTitle,
+ null,
+ progressNameIdTitle));
}
}
}
@@ -117,13 +128,17 @@ private List CreateResultsFromQuery(Query query)
if (score > 0)
{
// Add score to prioritize processes with visible windows
- // And use window title for those processes
+ // Use window title for those processes
if (Settings.PutVisibleWindowProcessesTop)
{
score += 200;
}
- processlist.Add(new ProcessResult(p, score, windowTitle,
- score == windowTitleMatch.Score ? windowTitleMatch : null, progressNameIdTitle));
+ processlist.Add(new ProcessResult(
+ p,
+ score,
+ Settings.ShowWindowTitle ? windowTitle : progressNameIdTitle,
+ score == windowTitleMatch.Score ? windowTitleMatch : null,
+ progressNameIdTitle));
}
}
else
@@ -132,7 +147,12 @@ private List CreateResultsFromQuery(Query query)
var score = processNameIdMatch.Score;
if (score > 0)
{
- processlist.Add(new ProcessResult(p, score, progressNameIdTitle, processNameIdMatch, progressNameIdTitle));
+ processlist.Add(new ProcessResult(
+ p,
+ score,
+ progressNameIdTitle,
+ processNameIdMatch,
+ progressNameIdTitle));
}
}
}
From a28ee701b8a562c6974a4b6139055854881bc45c Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 17 Apr 2025 18:45:31 +0900
Subject: [PATCH 1068/1335] Add settingwindowfont config and menu
---
.../UserSettings/Settings.cs | 21 ++++----
.../ViewModels/SettingsPaneAboutViewModel.cs | 49 +++++++++++++++++++
.../SettingPages/Views/SettingsPaneAbout.xaml | 46 ++++++++++++++---
.../Views/SettingsPaneAbout.xaml.cs | 22 ++++++++-
Flow.Launcher/SettingWindow.xaml | 1 +
Flow.Launcher/SettingWindow.xaml.cs | 1 +
.../ViewModel/SettingWindowViewModel.cs | 26 +++++++++-
7 files changed, 147 insertions(+), 19 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0bd1a809b7a..d91574bdc7a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -65,19 +65,21 @@ public void Save()
{ "pt", "Noto Sans" }
};
- public static string GetSystemDefaultFont()
+ public static string GetSystemDefaultFont(bool? useNoto = null)
{
try
{
- var culture = CultureInfo.CurrentCulture;
- var language = culture.Name; // e.g., "zh-TW"
- var langPrefix = language.Split('-')[0]; // e.g., "zh"
-
- // First, try to find by full name, and if not found, fallback to prefix
- if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
+ if (useNoto != false)
{
- if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
- return notoFont;
+ var culture = CultureInfo.CurrentCulture;
+ var language = culture.Name; // e.g., "zh-TW"
+ var langPrefix = language.Split('-')[0]; // e.g., "zh"
+
+ if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
+ {
+ if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
+ return notoFont;
+ }
}
var font = SystemFonts.MessageFontFamily;
@@ -162,6 +164,7 @@ public string Theme
public string ResultSubFontStyle { get; set; }
public string ResultSubFontWeight { get; set; }
public string ResultSubFontStretch { get; set; }
+ public string SettingWindowFont { get; set; } = GetSystemDefaultFont(false);
public bool UseGlyphIcons { get; set; } = true;
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 6cfb9830656..abc7a2d16f2 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Media;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure;
@@ -268,4 +270,51 @@ private static string BytesToReadableString(long bytes)
return "0 B";
}
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ private string _settingWindowFont;
+
+ public string SettingWindowFont
+ {
+ get => _settings.SettingWindowFont;
+ set
+ {
+ if (_settings.SettingWindowFont != value)
+ {
+ _settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+
+ [RelayCommand]
+ private void ResetSettingWindowFont()
+ {
+ string defaultFont = GetSystemDefaultFont();
+ _settings.SettingWindowFont = defaultFont;
+ }
+
+ public static string GetSystemDefaultFont()
+ {
+ try
+ {
+ var font = SystemFonts.MessageFontFamily;
+ if (font.FamilyNames.TryGetValue(System.Windows.Markup.XmlLanguage.GetLanguage("en-US"), out var englishName))
+ {
+ return englishName;
+ }
+
+ return font.Source ?? "Segoe UI";
+ }
+ catch
+ {
+ return "Segoe UI";
+ }
+ }
+
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index f7deee7cfdc..b3991743d4f 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -12,6 +12,11 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
_settings.SettingWindowLeft;
set => _settings.SettingWindowLeft = value;
}
+
+ public string SettingWindowFont
+ {
+ get => _settings.SettingWindowFont;
+ set
+ {
+ if (_settings.SettingWindowFont != value)
+ {
+ _settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
}
From e869b0c682e5a3b0c1d8f970f5a047592ff924a6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 17 Apr 2025 22:47:58 +0800
Subject: [PATCH 1069/1335] Add remarks for AddActionKeyword function
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index a73ead81423..61711d6965d 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -228,6 +228,10 @@ public interface IPublicAPI
///
/// ID for plugin that needs to add action keyword
/// The actionkeyword that is supposed to be added
+ ///
+ /// If new action keyword contains any whitespace, FL will still add it but it will not work for users.
+ /// So plugin should check the whitespace before calling this function.
+ ///
void AddActionKeyword(string pluginId, string newActionKeyword);
///
From 7797527dc7bec6521d03b0b7717fa390eccb4feb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 17 Apr 2025 22:48:38 +0800
Subject: [PATCH 1070/1335] Improve API documents
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 61711d6965d..31580fbe80a 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -223,7 +223,7 @@ public interface IPublicAPI
Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action reportProgress = null, CancellationToken token = default);
///
- /// Add ActionKeyword and update action keyword metadata for specific plugin
+ /// Add ActionKeyword and update action keyword metadata for specific plugin.
/// Before adding, please check if action keyword is already assigned by
///
/// ID for plugin that needs to add action keyword
@@ -284,9 +284,10 @@ public interface IPublicAPI
T LoadSettingJsonStorage() where T : new();
///
- /// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.Launcher
+ /// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.
/// This method will save the original instance loaded with LoadJsonStorage.
- /// This API call is for manually Save. Flow will automatically save all setting type that has called LoadSettingJsonStorage or SaveSettingJsonStorage previously.
+ /// This API call is for manually Save.
+ /// Flow will automatically save all setting type that has called or previously.
///
/// Type for Serialization
///
@@ -428,9 +429,10 @@ public interface IPublicAPI
Task LoadCacheBinaryStorageAsync(string cacheName, string cacheDirectory, T defaultData) where T : new();
///
- /// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.Launcher
+ /// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.
/// This method will save the original instance loaded with LoadCacheBinaryStorageAsync.
- /// This API call is for manually Save. Flow will automatically save all cache type that has called LoadCacheBinaryStorageAsync or SaveCacheBinaryStorageAsync previously.
+ /// This API call is for manually Save.
+ /// Flow will automatically save all cache type that has called or previously.
///
/// Type for Serialization
/// Cache file name
From 3eb9493bdd23c6a3bf686d097c19a8ff481e93ab Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 17 Apr 2025 23:01:45 +0800
Subject: [PATCH 1071/1335] Remove unused usings
---
Flow.Launcher/Helper/AutoStartup.cs | 1 -
Flow.Launcher/Helper/HotKeyMapper.cs | 1 -
2 files changed, 2 deletions(-)
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 568ea794446..81568875e85 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -3,7 +3,6 @@
using System.Linq;
using System.Security.Principal;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Logger;
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
diff --git a/Flow.Launcher/Helper/HotKeyMapper.cs b/Flow.Launcher/Helper/HotKeyMapper.cs
index 1e83415cc46..e5fabb3a89f 100644
--- a/Flow.Launcher/Helper/HotKeyMapper.cs
+++ b/Flow.Launcher/Helper/HotKeyMapper.cs
@@ -5,7 +5,6 @@
using NHotkey.Wpf;
using Flow.Launcher.ViewModel;
using ChefKeys;
-using Flow.Launcher.Infrastructure.Logger;
using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Helper;
From 1b0c11425504bc024919af2f9b9132e8076c4e10 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 17 Apr 2025 23:14:41 +0800
Subject: [PATCH 1072/1335] Fix possible window show issue during startup
---
Flow.Launcher/App.xaml.cs | 11 +---
Flow.Launcher/Helper/AutoStartup.cs | 62 ++++++++++++-------
.../SettingsPaneGeneralViewModel.cs | 4 +-
3 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 87677f58a67..87698a54571 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -202,18 +202,11 @@ private void AutoStartup()
{
// we try to enable auto-startup on first launch, or reenable if it was removed
// but the user still has the setting set
- if (_settings.StartFlowLauncherOnSystemStartup && !Helper.AutoStartup.IsEnabled)
+ if (_settings.StartFlowLauncherOnSystemStartup)
{
try
{
- if (_settings.UseLogonTaskForStartup)
- {
- Helper.AutoStartup.EnableViaLogonTask();
- }
- else
- {
- Helper.AutoStartup.EnableViaRegistry();
- }
+ Helper.AutoStartup.CheckIsEnabled(_settings.UseLogonTaskForStartup);
}
catch (Exception e)
{
diff --git a/Flow.Launcher/Helper/AutoStartup.cs b/Flow.Launcher/Helper/AutoStartup.cs
index 81568875e85..b83bb594894 100644
--- a/Flow.Launcher/Helper/AutoStartup.cs
+++ b/Flow.Launcher/Helper/AutoStartup.cs
@@ -16,29 +16,37 @@ public class AutoStartup
private const string LogonTaskName = $"{Constant.FlowLauncher} Startup";
private const string LogonTaskDesc = $"{Constant.FlowLauncher} Auto Startup";
- public static bool IsEnabled
+ public static void CheckIsEnabled(bool useLogonTaskForStartup)
{
- get
+ // We need to check both because if both of them are enabled,
+ // Hide Flow Launcher on startup will not work since the later one will trigger main window show event
+ var logonTaskEnabled = CheckLogonTask();
+ var registryEnabled = CheckRegistry();
+ if (useLogonTaskForStartup)
{
- // Check if logon task is enabled
- if (CheckLogonTask())
+ // Enable logon task
+ if (!logonTaskEnabled)
{
- return true;
+ Enable(true);
}
-
- // Check if registry is enabled
- try
+ // Disable registry
+ if (registryEnabled)
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- var path = key?.GetValue(Constant.FlowLauncher) as string;
- return path == Constant.ExecutablePath;
+ Disable(false);
}
- catch (Exception e)
+ }
+ else
+ {
+ // Enable registry
+ if (!registryEnabled)
{
- App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
+ Enable(false);
+ }
+ // Disable logon task
+ if (logonTaskEnabled)
+ {
+ Disable(true);
}
-
- return false;
}
}
@@ -69,20 +77,26 @@ private static bool CheckLogonTask()
return false;
}
- public static void DisableViaLogonTaskAndRegistry()
+ private static bool CheckRegistry()
{
- Disable(true);
- Disable(false);
- }
+ try
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
+ var path = key?.GetValue(Constant.FlowLauncher) as string;
+ return path == Constant.ExecutablePath;
+ }
+ catch (Exception e)
+ {
+ App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
+ }
- public static void EnableViaLogonTask()
- {
- Enable(true);
+ return false;
}
- public static void EnableViaRegistry()
+ public static void DisableViaLogonTaskAndRegistry()
{
- Enable(false);
+ Disable(true);
+ Disable(false);
}
public static void ChangeToViaLogonTask()
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 021c9d7fe61..6b56caf5e74 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -48,11 +48,11 @@ public bool StartFlowLauncherOnSystemStartup
{
if (UseLogonTaskForStartup)
{
- AutoStartup.EnableViaLogonTask();
+ AutoStartup.ChangeToViaLogonTask();
}
else
{
- AutoStartup.EnableViaRegistry();
+ AutoStartup.ChangeToViaRegistry();
}
}
else
From dd61ab43cb5cc47d54edf21df77452d76b1ad1c3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 18 Apr 2025 07:17:33 +0800
Subject: [PATCH 1073/1335] Use null as flag to report community source error
---
.../ExternalPlugins/CommunityPluginSource.cs | 8 ++++----
.../ExternalPlugins/CommunityPluginStore.cs | 12 ++++++++----
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
index ac27c523c7e..6f3b23e1120 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
@@ -16,12 +16,12 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
public record CommunityPluginSource(string ManifestFileUrl)
{
+ private static readonly string ClassName = nameof(CommunityPluginSource);
+
// We should not initialize API in static constructor because it will create another API instance
private static IPublicAPI api = null;
private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService();
- private static readonly string ClassName = nameof(CommunityPluginSource);
-
private string latestEtag = "";
private List plugins = new();
@@ -70,7 +70,7 @@ public async Task> FetchAsync(CancellationToken token)
else
{
API.LogWarn(ClassName, $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
- return plugins;
+ return null;
}
}
catch (Exception e)
@@ -83,7 +83,7 @@ public async Task> FetchAsync(CancellationToken token)
{
API.LogException(ClassName, "Error Occurred", e);
}
- return plugins;
+ return null;
}
}
}
diff --git a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
index 1f23c2f6619..bdc1ad3dd8f 100644
--- a/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
+++ b/Flow.Launcher.Core/ExternalPlugins/CommunityPluginStore.cs
@@ -40,10 +40,14 @@ public async Task> FetchAsync(CancellationToken token, bool onl
var completedTask = await Task.WhenAny(tasks);
if (completedTask.IsCompletedSuccessfully)
{
- // one of the requests completed successfully; keep its results
- // and cancel the remaining http requests.
- pluginResults = await completedTask;
- cts.Cancel();
+ var result = await completedTask;
+ if (result != null)
+ {
+ // one of the requests completed successfully; keep its results
+ // and cancel the remaining http requests.
+ pluginResults = result;
+ cts.Cancel();
+ }
}
tasks.Remove(completedTask);
}
From 1cd699887083e1cd0a3de7b72bb02996e93d090f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 18 Apr 2025 07:39:02 +0800
Subject: [PATCH 1074/1335] Cleanup codes
---
.../UserSettings/Settings.cs | 85 ++-----------------
Flow.Launcher.Infrastructure/Win32Helper.cs | 72 ++++++++++++++++
.../ViewModels/SettingsPaneThemeViewModel.cs | 5 +-
3 files changed, 83 insertions(+), 79 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0bd1a809b7a..8500e7aa444 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -1,12 +1,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Drawing;
-using System.Globalization;
-using System.Linq;
using System.Text.Json.Serialization;
using System.Windows;
-using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Logger;
@@ -14,7 +9,6 @@
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
-using SystemFonts = System.Windows.SystemFonts;
namespace Flow.Launcher.Infrastructure.UserSettings
{
@@ -37,67 +31,6 @@ public void Save()
{
_storage.Save();
}
-
- private string language = Constant.SystemLanguageCode;
- private static readonly Dictionary LanguageToNotoSans = new()
- {
- { "ko", "Noto Sans KR" },
- { "ja", "Noto Sans JP" },
- { "zh-CN", "Noto Sans SC" },
- { "zh-SG", "Noto Sans SC" },
- { "zh-Hans", "Noto Sans SC" },
- { "zh-TW", "Noto Sans TC" },
- { "zh-HK", "Noto Sans TC" },
- { "zh-MO", "Noto Sans TC" },
- { "zh-Hant", "Noto Sans TC" },
- { "th", "Noto Sans Thai" },
- { "ar", "Noto Sans Arabic" },
- { "he", "Noto Sans Hebrew" },
- { "hi", "Noto Sans Devanagari" },
- { "bn", "Noto Sans Bengali" },
- { "ta", "Noto Sans Tamil" },
- { "el", "Noto Sans Greek" },
- { "ru", "Noto Sans" },
- { "en", "Noto Sans" },
- { "fr", "Noto Sans" },
- { "de", "Noto Sans" },
- { "es", "Noto Sans" },
- { "pt", "Noto Sans" }
- };
-
- public static string GetSystemDefaultFont()
- {
- try
- {
- var culture = CultureInfo.CurrentCulture;
- var language = culture.Name; // e.g., "zh-TW"
- var langPrefix = language.Split('-')[0]; // e.g., "zh"
-
- // First, try to find by full name, and if not found, fallback to prefix
- if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
- {
- if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
- return notoFont;
- }
-
- var font = SystemFonts.MessageFontFamily;
- if (font.FamilyNames.TryGetValue(System.Windows.Markup.XmlLanguage.GetLanguage("en-US"), out var englishName))
- {
- return englishName;
- }
-
- return font.Source ?? "Segoe UI";
- }
- catch
- {
- return "Segoe UI";
- }
- }
-
- private static bool TryGetNotoFont(string langKey, out string notoFont)
- {
- return LanguageToNotoSans.TryGetValue(langKey, out notoFont);
- }
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
@@ -119,12 +52,13 @@ private static bool TryGetNotoFont(string langKey, out string notoFont)
public string CycleHistoryUpHotkey { get; set; } = $"{KeyConstant.Alt} + Up";
public string CycleHistoryDownHotkey { get; set; } = $"{KeyConstant.Alt} + Down";
+ private string _language = Constant.SystemLanguageCode;
public string Language
{
- get => language;
+ get => _language;
set
{
- language = value;
+ _language = value;
OnPropertyChanged();
}
}
@@ -150,15 +84,15 @@ public string Theme
public double QueryBoxFontSize { get; set; } = 16;
public double ResultItemFontSize { get; set; } = 16;
public double ResultSubItemFontSize { get; set; } = 13;
- public string QueryBoxFont { get; set; } = GetSystemDefaultFont();
+ public string QueryBoxFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string QueryBoxFontStyle { get; set; }
public string QueryBoxFontWeight { get; set; }
public string QueryBoxFontStretch { get; set; }
- public string ResultFont { get; set; } = GetSystemDefaultFont();
+ public string ResultFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string ResultFontStyle { get; set; }
public string ResultFontWeight { get; set; }
public string ResultFontStretch { get; set; }
- public string ResultSubFont { get; set; } = GetSystemDefaultFont();
+ public string ResultSubFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string ResultSubFontStyle { get; set; }
public string ResultSubFontWeight { get; set; }
public string ResultSubFontStretch { get; set; }
@@ -181,7 +115,7 @@ public string Theme
public double? SettingWindowLeft { get; set; } = null;
public WindowState SettingWindowState { get; set; } = WindowState.Normal;
- bool _showPlaceholder { get; set; } = true;
+ private bool _showPlaceholder { get; set; } = true;
public bool ShowPlaceholder
{
get => _showPlaceholder;
@@ -194,7 +128,7 @@ public bool ShowPlaceholder
}
}
}
- string _placeholderText { get; set; } = string.Empty;
+ private string _placeholderText { get; set; } = string.Empty;
public string PlaceholderText
{
get => _placeholderText;
@@ -373,7 +307,7 @@ public bool KeepMaxResults
public bool StartFlowLauncherOnSystemStartup { get; set; } = false;
public bool UseLogonTaskForStartup { get; set; } = false;
public bool HideOnStartup { get; set; } = true;
- bool _hideNotifyIcon { get; set; }
+ private bool _hideNotifyIcon;
public bool HideNotifyIcon
{
get => _hideNotifyIcon;
@@ -551,5 +485,4 @@ public enum BackdropTypes
Mica,
MicaAlt
}
-
}
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 798501ae3fd..6a5af41df28 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -1,10 +1,13 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
+using System.Windows.Markup;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
@@ -14,6 +17,7 @@
using Windows.Win32.UI.Input.KeyboardAndMouse;
using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
+using SystemFonts = System.Windows.SystemFonts;
namespace Flow.Launcher.Infrastructure
{
@@ -595,5 +599,73 @@ public static void OpenImeSettings()
}
#endregion
+
+ #region System Font
+
+ private static readonly Dictionary _languageToNotoSans = new()
+ {
+ { "ko", "Noto Sans KR" },
+ { "ja", "Noto Sans JP" },
+ { "zh-CN", "Noto Sans SC" },
+ { "zh-SG", "Noto Sans SC" },
+ { "zh-Hans", "Noto Sans SC" },
+ { "zh-TW", "Noto Sans TC" },
+ { "zh-HK", "Noto Sans TC" },
+ { "zh-MO", "Noto Sans TC" },
+ { "zh-Hant", "Noto Sans TC" },
+ { "th", "Noto Sans Thai" },
+ { "ar", "Noto Sans Arabic" },
+ { "he", "Noto Sans Hebrew" },
+ { "hi", "Noto Sans Devanagari" },
+ { "bn", "Noto Sans Bengali" },
+ { "ta", "Noto Sans Tamil" },
+ { "el", "Noto Sans Greek" },
+ { "ru", "Noto Sans" },
+ { "en", "Noto Sans" },
+ { "fr", "Noto Sans" },
+ { "de", "Noto Sans" },
+ { "es", "Noto Sans" },
+ { "pt", "Noto Sans" }
+ };
+
+ public static string GetSystemDefaultFont()
+ {
+ try
+ {
+ var culture = CultureInfo.CurrentCulture;
+ var language = culture.Name; // e.g., "zh-TW"
+ var langPrefix = language.Split('-')[0]; // e.g., "zh"
+
+ // First, try to find by full name, and if not found, fallback to prefix
+ if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
+ {
+ // If the font is installed, return it
+ if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
+ {
+ return notoFont;
+ }
+ }
+
+ // If Noto font is not found, fallback to the system default font
+ var font = SystemFonts.MessageFontFamily;
+ if (font.FamilyNames.TryGetValue(XmlLanguage.GetLanguage("en-US"), out var englishName))
+ {
+ return englishName;
+ }
+
+ return font.Source ?? "Segoe UI";
+ }
+ catch
+ {
+ return "Segoe UI";
+ }
+ }
+
+ private static bool TryGetNotoFont(string langKey, out string notoFont)
+ {
+ return _languageToNotoSans.TryGetValue(langKey, out notoFont);
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index d62fd906b35..1138b286975 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Windows;
+using System.Windows.Controls;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -17,13 +17,12 @@
using Flow.Launcher.ViewModel;
using ModernWpf;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
-using System.Windows.Controls;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneThemeViewModel : BaseModel
{
- private string DefaultFont = Settings.GetSystemDefaultFont();
+ private readonly string DefaultFont = Win32Helper.GetSystemDefaultFont();
public string BackdropSubText => !Win32Helper.IsBackdropSupported() ? App.API.GetTranslation("BackdropTypeDisabledToolTip") : "";
public Settings Settings { get; }
private readonly Theme _theme = Ioc.Default.GetRequiredService();
From e70ce114726b5f22717496efba47aa746d805182 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sat, 19 Apr 2025 09:39:02 +0900
Subject: [PATCH 1075/1335] Change Search Window Position to Location
---
Flow.Launcher/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 5a6fd3d74bf..caa9a712910 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -58,7 +58,7 @@
Error setting launch on startup
Hide Flow Launcher when focus is lost
Do not show new version notifications
- Search Window Position
+ Search Window Location
Remember Last Position
Monitor with Mouse Cursor
Monitor with Focused Window
From e60e117cf924d0cf559c9fe1c94c535f4de6d8d9 Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 19 Apr 2025 10:20:59 +0900
Subject: [PATCH 1076/1335] Fix Color
---
Flow.Launcher/Resources/Light.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml
index 4d765d161fe..112815ed0f1 100644
--- a/Flow.Launcher/Resources/Light.xaml
+++ b/Flow.Launcher/Resources/Light.xaml
@@ -22,7 +22,7 @@
-
+
From 8674fca082dd74cb503e0a9a4b238a4cb05aa59a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 19 Apr 2025 11:20:08 +0800
Subject: [PATCH 1077/1335] Resolve conflicts
---
.../UserSettings/Settings.cs | 2 +-
Flow.Launcher.Infrastructure/Win32Helper.cs | 32 +++++++++++++------
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 17792c0c13c..52bc63ec61a 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -96,7 +96,7 @@ public string Theme
public string ResultSubFontStyle { get; set; }
public string ResultSubFontWeight { get; set; }
public string ResultSubFontStretch { get; set; }
- public string SettingWindowFont { get; set; } = GetSystemDefaultFont(false);
+ public string SettingWindowFont { get; set; } = Win32Helper.GetSystemDefaultFont(false);
public bool UseGlyphIcons { get; set; } = true;
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 6a5af41df28..2788060eb4c 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -628,21 +628,33 @@ public static void OpenImeSettings()
{ "pt", "Noto Sans" }
};
- public static string GetSystemDefaultFont()
+ ///
+ /// Gets the system default font.
+ ///
+ ///
+ /// If true, it will try to find the Noto font for the current culture.
+ ///
+ ///
+ /// The name of the system default font.
+ ///
+ public static string GetSystemDefaultFont(bool useNoto = true)
{
try
{
- var culture = CultureInfo.CurrentCulture;
- var language = culture.Name; // e.g., "zh-TW"
- var langPrefix = language.Split('-')[0]; // e.g., "zh"
-
- // First, try to find by full name, and if not found, fallback to prefix
- if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
+ if (useNoto)
{
- // If the font is installed, return it
- if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
+ var culture = CultureInfo.CurrentCulture;
+ var language = culture.Name; // e.g., "zh-TW"
+ var langPrefix = language.Split('-')[0]; // e.g., "zh"
+
+ // First, try to find by full name, and if not found, fallback to prefix
+ if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
{
- return notoFont;
+ // If the font is installed, return it
+ if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
+ {
+ return notoFont;
+ }
}
}
From a15b789eb03f8cc7e0174c201b91e53b1a66290c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 19 Apr 2025 11:25:39 +0800
Subject: [PATCH 1078/1335] Cleanup codes
---
.../ViewModels/SettingsPaneAboutViewModel.cs | 33 ++-----------------
1 file changed, 2 insertions(+), 31 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index abc7a2d16f2..ee0865f9d93 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Media;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure;
@@ -271,14 +269,6 @@ private static string BytesToReadableString(long bytes)
return "0 B";
}
- public event PropertyChangedEventHandler PropertyChanged;
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
- private string _settingWindowFont;
-
public string SettingWindowFont
{
get => _settings.SettingWindowFont;
@@ -287,7 +277,7 @@ public string SettingWindowFont
if (_settings.SettingWindowFont != value)
{
_settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
+ OnPropertyChanged();
}
}
}
@@ -295,26 +285,7 @@ public string SettingWindowFont
[RelayCommand]
private void ResetSettingWindowFont()
{
- string defaultFont = GetSystemDefaultFont();
+ string defaultFont = Win32Helper.GetSystemDefaultFont(false);
_settings.SettingWindowFont = defaultFont;
}
-
- public static string GetSystemDefaultFont()
- {
- try
- {
- var font = SystemFonts.MessageFontFamily;
- if (font.FamilyNames.TryGetValue(System.Windows.Markup.XmlLanguage.GetLanguage("en-US"), out var englishName))
- {
- return englishName;
- }
-
- return font.Source ?? "Segoe UI";
- }
- catch
- {
- return "Segoe UI";
- }
- }
-
}
From 3f5e69be7f385cec24097a2479025b5ba569c071 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sat, 19 Apr 2025 11:27:43 +0800
Subject: [PATCH 1079/1335] Fix possible property change issue
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index ee0865f9d93..55d6b0a1c88 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -286,6 +286,6 @@ public string SettingWindowFont
private void ResetSettingWindowFont()
{
string defaultFont = Win32Helper.GetSystemDefaultFont(false);
- _settings.SettingWindowFont = defaultFont;
+ SettingWindowFont = defaultFont;
}
}
From 647f2bb0a16fd7c5d142469c3365701376fa32dc Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 19 Apr 2025 15:05:15 +0900
Subject: [PATCH 1080/1335] Add String
---
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index caa9a712910..b66b2ba03cd 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -356,6 +356,7 @@
Log Level
Debug
Info
+ Setting Window Font
Select File Manager
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index b3991743d4f..44a0490ca19 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -148,7 +148,7 @@
SelectedValuePath="Value" />
From 942b29061edfbd9102f63c7d3f14316408cd6954 Mon Sep 17 00:00:00 2001
From: DB P
Date: Sat, 19 Apr 2025 15:40:11 +0900
Subject: [PATCH 1081/1335] Add FontFamily Style
---
Flow.Launcher/CustomQueryHotkeySetting.xaml | 1 +
.../CustomQueryHotkeySetting.xaml.cs | 21 +++++++-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 23 ++++++++-
Flow.Launcher/SelectBrowserWindow.xaml | 51 +++++++++----------
Flow.Launcher/SelectBrowserWindow.xaml.cs | 17 ++++++-
Flow.Launcher/SelectFileManagerWindow.xaml | 1 +
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 16 ++++++
7 files changed, 101 insertions(+), 29 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index 0171e6d79c3..a460ffae023 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
+ FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
Title="{DynamicResource customeQueryHotkeyTitle}"
Width="530"
Background="{DynamicResource PopuBGColor}"
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 8b193fa1dee..c377fb2502b 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -1,6 +1,7 @@
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.UserSettings;
using System.Collections.ObjectModel;
+using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
@@ -13,7 +14,25 @@ public partial class CustomQueryHotkeySetting : Window
private readonly Settings _settings;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
-
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public string SettingWindowFont
+ {
+ get => _settings.SettingWindowFont;
+ set
+ {
+ if (_settings.SettingWindowFont != value)
+ {
+ _settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
public CustomQueryHotkeySetting(Settings settings)
{
_settings = settings;
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index ecbdea60627..dcfa572f4c1 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -1,6 +1,8 @@
using System;
+using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher
@@ -13,7 +15,26 @@ public partial class CustomShortcutSetting : Window
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
-
+ private readonly Settings _settings;
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public string SettingWindowFont
+ {
+ get => _settings.SettingWindowFont;
+ set
+ {
+ if (_settings.SettingWindowFont != value)
+ {
+ _settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
{
_hotkeyVm = vm;
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml
index c12879a04bb..b16de277048 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml
+++ b/Flow.Launcher/SelectBrowserWindow.xaml
@@ -10,6 +10,7 @@
Width="550"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
+ FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
@@ -54,11 +55,11 @@
-
-
+
+
-
+
@@ -108,10 +109,10 @@
@@ -129,7 +130,7 @@
-
-
+
+
@@ -239,18 +238,18 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
- BorderThickness="0,1,0,0">
+ BorderThickness="0 1 0 0">
Settings.SettingWindowFont;
+ set
+ {
+ if (Settings.SettingWindowFont != value)
+ {
+ Settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
public int SelectedCustomBrowserIndex
{
get => selectedCustomBrowserIndex; set
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index 0287af9b03a..bfe6914e504 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -10,6 +10,7 @@
Width="600"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
+ FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index b7bda45654a..80c0cf1f664 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -17,6 +17,22 @@ public partial class SelectFileManagerWindow : Window, INotifyPropertyChanged
public Settings Settings { get; }
+ public string SettingWindowFont
+ {
+ get => Settings.SettingWindowFont;
+ set
+ {
+ if (Settings.SettingWindowFont != value)
+ {
+ Settings.SettingWindowFont = value;
+ OnPropertyChanged(nameof(SettingWindowFont));
+ }
+ }
+ }
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
public int SelectedCustomExplorerIndex
{
get => selectedCustomExplorerIndex; set
From 4c54294074f9b0f8912c8fbd1cd7011b803b45de Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 19 Apr 2025 21:22:43 +1000
Subject: [PATCH 1082/1335] deploy website on release
---
.github/workflows/website_deploy.yml | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 .github/workflows/website_deploy.yml
diff --git a/.github/workflows/website_deploy.yml b/.github/workflows/website_deploy.yml
new file mode 100644
index 00000000000..0cb6231740f
--- /dev/null
+++ b/.github/workflows/website_deploy.yml
@@ -0,0 +1,21 @@
+---
+
+name: Deploy Website On Release
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+jobs:
+ dispatch:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Dispatch event
+ run: |
+ http_status=$(curl -L -f -s -o /dev/null -w "%{http_code}" \
+ -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${{ secrets.DEPLOY_WEBSITE }}" \
+ https://api.github.com/repos/Flow-Launcher/flow-launcher.github.io/dispatches \
+ -d '{"event_type":"deploy"}')
+ if [ "$http_status" -ne 204 ]; then echo "Error: Deploy trigger failed, HTTP status code is $http_status"; exit 1; fi
From 827c7520f9d011583ab135ce1e65fb086d94925d Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 19 Apr 2025 21:27:24 +1000
Subject: [PATCH 1083/1335] update token name
---
.github/workflows/website_deploy.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/website_deploy.yml b/.github/workflows/website_deploy.yml
index 0cb6231740f..2d44e4a2c78 100644
--- a/.github/workflows/website_deploy.yml
+++ b/.github/workflows/website_deploy.yml
@@ -15,7 +15,7 @@ jobs:
http_status=$(curl -L -f -s -o /dev/null -w "%{http_code}" \
-X POST \
-H "Accept: application/vnd.github+json" \
- -H "Authorization: Bearer ${{ secrets.DEPLOY_WEBSITE }}" \
+ -H "Authorization: Bearer ${{ secrets.DEPLOY_FLOW_WEBSITE }}" \
https://api.github.com/repos/Flow-Launcher/flow-launcher.github.io/dispatches \
-d '{"event_type":"deploy"}')
if [ "$http_status" -ne 204 ]; then echo "Error: Deploy trigger failed, HTTP status code is $http_status"; exit 1; fi
From 908d1b74bf0fdcf1ebbb50e499efaae957c295b3 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 20 Apr 2025 08:12:31 +0900
Subject: [PATCH 1084/1335] Fix typo
---
Flow.Launcher/Languages/en.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index caa9a712910..8501f083bbc 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -142,8 +142,8 @@
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
Advanced Settings:
Enabled
Priority
From d5f48da3f70f2b73dda8e618e7b38a6c890b2929 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 20 Apr 2025 08:12:31 +0900
Subject: [PATCH 1085/1335] Fix typo
---
Flow.Launcher/Languages/en.xaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index caa9a712910..8501f083bbc 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -142,8 +142,8 @@
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
Advanced Settings:
Enabled
Priority
From 5765baa5026334791f144a54fabf6bbbf12041c1 Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 20 Apr 2025 08:15:35 +0900
Subject: [PATCH 1086/1335] Fix Typo
---
Flow.Launcher/Languages/en.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 8501f083bbc..554e5ed9de3 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -235,7 +235,7 @@
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
From f9a201a33c8c2492b2fbac91b4f2f6a5f673a68f Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 20 Apr 2025 08:15:35 +0900
Subject: [PATCH 1087/1335] "disable from displaying" to "Hide"
---
Flow.Launcher/Languages/en.xaml | 2 +-
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 8501f083bbc..554e5ed9de3 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -235,7 +235,7 @@
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 790c9d2c621..ee6b4379d12 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -76,7 +76,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
From 31f286607dd9dc50f7f53ddb864b22eed7b2d85b Mon Sep 17 00:00:00 2001
From: DB p
Date: Sun, 20 Apr 2025 10:31:35 +0900
Subject: [PATCH 1088/1335] Adjust Badge Text and remove subtitle
---
Flow.Launcher/Languages/en.xaml | 3 +--
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml | 5 +----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 554e5ed9de3..f1b41eb3c9b 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -303,9 +303,8 @@
Use Segoe Fluent Icons for query results where supported
Press Key
Show Result Badges
- Show badges for query results where supported
+ For supported plugins, badges are displayed to help distinguish them more easily.
Show Result Badges for Global Query Only
- Show badges for global query results only
HTTP Proxy
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 0b5de1280dc..f7853515a38 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -740,10 +740,7 @@
OffContent="{DynamicResource disable}"
OnContent="{DynamicResource enable}" />
-
+
Date: Mon, 21 Apr 2025 22:07:23 +0000
Subject: [PATCH 1089/1335] Bump vers-one/dotnet-project-version-updater from
1.5 to 1.7
Bumps [vers-one/dotnet-project-version-updater](https://github.com/vers-one/dotnet-project-version-updater) from 1.5 to 1.7.
- [Release notes](https://github.com/vers-one/dotnet-project-version-updater/releases)
- [Commits](https://github.com/vers-one/dotnet-project-version-updater/compare/v1.5...v1.7)
---
updated-dependencies:
- dependency-name: vers-one/dotnet-project-version-updater
dependency-version: '1.7'
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
.github/workflows/dotnet.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 718a28dbdf5..7498262deba 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set Flow.Launcher.csproj version
id: update
- uses: vers-one/dotnet-project-version-updater@v1.5
+ uses: vers-one/dotnet-project-version-updater@v1.7
with:
file: |
"**/SolutionAssemblyInfo.cs"
From 0a41072f33a7196402db93e2266a8f9d52ca2b13 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 22 Apr 2025 11:21:11 +0900
Subject: [PATCH 1090/1335] Add animation option when showing the main window
---
Flow.Launcher/MainWindow.xaml.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index bf7a45b1d25..ee84dfeb46c 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -138,8 +138,12 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
else
{
_viewModel.Show();
+ if (_settings.UseAnimation)
+ {
+ WindowAnimation();
+ }
}
-
+
// Show notify icon when flowlauncher is hidden
InitializeNotifyIcon();
From 9b52cb6a1029329d23f0964b13a0494d8849b71f Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 23 Apr 2025 11:53:54 +0900
Subject: [PATCH 1091/1335] Remove unused PropertyChanged event and
OnPropertyChanged method from SettingWindowViewModel
---
Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index b6fd9555b17..4468b7865dc 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -58,11 +58,5 @@ public string SettingWindowFont
}
}
}
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
+
}
From 284fe2b922e6145bbb14dc3960890338d6232f9c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 23 Apr 2025 11:42:16 +0800
Subject: [PATCH 1092/1335] Cleanup codes
---
Flow.Launcher/SettingWindow.xaml.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 70b5a22ede9..b4a3ae47a92 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -3,7 +3,6 @@
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
-using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
From 83e5654a5ce2a4651cdfb38f234d4b49bea2ccae Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 23 Apr 2025 11:42:55 +0800
Subject: [PATCH 1093/1335] Fix possible null exception
---
Flow.Launcher/CustomShortcutSetting.xaml.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index dcfa572f4c1..ba326fb9ee4 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -9,13 +9,14 @@ namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
+ private static readonly Settings _settings = Ioc.Default.GetRequiredService();
+
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
public string Key { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- private readonly Settings _settings;
public event PropertyChangedEventHandler PropertyChanged;
public string SettingWindowFont
From cdbe45d4dcf5e37e9810c755407560516a18e9f9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 23 Apr 2025 11:48:11 +0800
Subject: [PATCH 1094/1335] Cleanup codes
---
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 55d6b0a1c88..acffe1e85af 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -285,7 +285,6 @@ public string SettingWindowFont
[RelayCommand]
private void ResetSettingWindowFont()
{
- string defaultFont = Win32Helper.GetSystemDefaultFont(false);
- SettingWindowFont = defaultFont;
+ SettingWindowFont = Win32Helper.GetSystemDefaultFont(false);
}
}
From c3509c3b20bcc4bc914d5ac39b678f0aef91f052 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 23 Apr 2025 12:43:34 +0800
Subject: [PATCH 1095/1335] Use property change event for settings & Use
INotifyPropertyChanged instead
---
.../UserSettings/Settings.cs | 15 ++++++-
Flow.Launcher/CustomQueryHotkeySetting.xaml | 2 +-
.../CustomQueryHotkeySetting.xaml.cs | 38 +++++-------------
Flow.Launcher/CustomShortcutSetting.xaml | 27 +++++++------
Flow.Launcher/CustomShortcutSetting.xaml.cs | 31 +++-----------
Flow.Launcher/SelectBrowserWindow.xaml | 2 +-
Flow.Launcher/SelectBrowserWindow.xaml.cs | 36 +++++------------
Flow.Launcher/SelectFileManagerWindow.xaml | 2 +-
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 38 +++++-------------
.../SettingPages/Views/SettingsPaneAbout.xaml | 3 +-
.../Views/SettingsPaneAbout.xaml.cs | 22 +---------
Flow.Launcher/SettingWindow.xaml | 2 +-
.../ViewModel/SettingWindowViewModel.cs | 40 ++++++-------------
13 files changed, 81 insertions(+), 177 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 52bc63ec61a..0f878151e72 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -96,7 +96,6 @@ public string Theme
public string ResultSubFontStyle { get; set; }
public string ResultSubFontWeight { get; set; }
public string ResultSubFontStretch { get; set; }
- public string SettingWindowFont { get; set; } = Win32Helper.GetSystemDefaultFont(false);
public bool UseGlyphIcons { get; set; } = true;
public bool UseAnimation { get; set; } = true;
public bool UseSound { get; set; } = true;
@@ -104,6 +103,20 @@ public string Theme
public bool ShowBadges { get; set; } = false;
public bool ShowBadgesGlobalOnly { get; set; } = false;
+ private string _settingWindowFont { get; set; } = Win32Helper.GetSystemDefaultFont(false);
+ public string SettingWindowFont
+ {
+ get => _settingWindowFont;
+ set
+ {
+ if (_settingWindowFont != value)
+ {
+ _settingWindowFont = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public bool UseClock { get; set; } = true;
public bool UseDate { get; set; } = false;
public string TimeFormat { get; set; } = "hh:mm tt";
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index a460ffae023..d3c31c6da5c 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -4,11 +4,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
- FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
Title="{DynamicResource customeQueryHotkeyTitle}"
Width="530"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
Icon="Images\app.png"
MouseDown="window_MouseDown"
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index c377fb2502b..3c501d41a73 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -1,41 +1,23 @@
-using Flow.Launcher.Helper;
-using Flow.Launcher.Infrastructure.UserSettings;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
+using Flow.Launcher.Helper;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- private readonly Settings _settings;
+ public Settings Settings { get; set; }
+
private bool update;
private CustomPluginHotkey updateCustomHotkey;
- public event PropertyChangedEventHandler PropertyChanged;
-
- public string SettingWindowFont
- {
- get => _settings.SettingWindowFont;
- set
- {
- if (_settings.SettingWindowFont != value)
- {
- _settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
- }
- }
- }
-
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
+
public CustomQueryHotkeySetting(Settings settings)
{
- _settings = settings;
+ Settings = settings;
InitializeComponent();
}
@@ -48,13 +30,13 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
if (!update)
{
- _settings.CustomPluginHotkeys ??= new ObservableCollection();
+ Settings.CustomPluginHotkeys ??= new ObservableCollection();
var pluginHotkey = new CustomPluginHotkey
{
Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
};
- _settings.CustomPluginHotkeys.Add(pluginHotkey);
+ Settings.CustomPluginHotkeys.Add(pluginHotkey);
HotKeyMapper.SetCustomQueryHotkey(pluginHotkey);
}
@@ -73,7 +55,7 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
public void UpdateItem(CustomPluginHotkey item)
{
- updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
+ updateCustomHotkey = Settings.CustomPluginHotkeys.FirstOrDefault(o =>
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml b/Flow.Launcher/CustomShortcutSetting.xaml
index 9256a2c5299..cbdcecea6a9 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml
+++ b/Flow.Launcher/CustomShortcutSetting.xaml
@@ -7,6 +7,7 @@
Width="530"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
Icon="Images\app.png"
ResizeMode="NoResize"
@@ -56,11 +57,11 @@
-
-
+
+
-
+
@@ -124,14 +125,14 @@
LastChildFill="True">
@@ -142,21 +143,21 @@
+ BorderThickness="0 1 0 0">
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index ba326fb9ee4..183cc3a7ff6 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -1,7 +1,6 @@
-using System;
-using System.ComponentModel;
-using System.Windows;
+using System.Windows;
using System.Windows.Input;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
@@ -9,33 +8,15 @@ namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
- private static readonly Settings _settings = Ioc.Default.GetRequiredService();
+ public Settings Settings { get; set; } = Ioc.Default.GetRequiredService();
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
- public string Key { get; set; } = String.Empty;
- public string Value { get; set; } = String.Empty;
+ public string Key { get; set; } = string.Empty;
+ public string Value { get; set; } = string.Empty;
private string originalKey { get; } = null;
private string originalValue { get; } = null;
private bool update { get; } = false;
- public event PropertyChangedEventHandler PropertyChanged;
-
- public string SettingWindowFont
- {
- get => _settings.SettingWindowFont;
- set
- {
- if (_settings.SettingWindowFont != value)
- {
- _settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
- }
- }
- }
-
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
+
public CustomShortcutSetting(SettingsPaneHotkeyViewModel vm)
{
_hotkeyVm = vm;
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml
index b16de277048..4fc5a91c5da 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml
+++ b/Flow.Launcher/SelectBrowserWindow.xaml
@@ -10,7 +10,7 @@
Width="550"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index e8365819bd6..849056ab104 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml.cs
+++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs
@@ -1,42 +1,25 @@
-using Flow.Launcher.Infrastructure.UserSettings;
-using System;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
- public partial class SelectBrowserWindow : Window, INotifyPropertyChanged
+ [INotifyPropertyChanged]
+ public partial class SelectBrowserWindow : Window
{
- private int selectedCustomBrowserIndex;
+ public Settings Settings { get; }
- public event PropertyChangedEventHandler PropertyChanged;
+ private int selectedCustomBrowserIndex;
- public Settings Settings { get; }
- public string SettingWindowFont
- {
- get => Settings.SettingWindowFont;
- set
- {
- if (Settings.SettingWindowFont != value)
- {
- Settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
- }
- }
- }
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
public int SelectedCustomBrowserIndex
{
get => selectedCustomBrowserIndex; set
{
selectedCustomBrowserIndex = value;
- PropertyChanged?.Invoke(this, new(nameof(CustomBrowser)));
+ OnPropertyChanged(nameof(CustomBrowser));
}
}
public ObservableCollection CustomBrowsers { get; set; }
@@ -79,8 +62,7 @@ private void btnDelete_Click(object sender, RoutedEventArgs e)
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
- Nullable result = dlg.ShowDialog();
-
+ var result = dlg.ShowDialog();
if (result == true)
{
TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index bfe6914e504..7d1fe0f567f 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -10,7 +10,7 @@
Width="600"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 80c0cf1f664..946052e320b 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -1,44 +1,27 @@
-using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.ViewModel;
-using System;
-using System.Collections.ObjectModel;
+using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher
{
- public partial class SelectFileManagerWindow : Window, INotifyPropertyChanged
+ [INotifyPropertyChanged]
+ public partial class SelectFileManagerWindow : Window
{
- private int selectedCustomExplorerIndex;
-
- public event PropertyChangedEventHandler PropertyChanged;
-
public Settings Settings { get; }
- public string SettingWindowFont
- {
- get => Settings.SettingWindowFont;
- set
- {
- if (Settings.SettingWindowFont != value)
- {
- Settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
- }
- }
- }
- protected virtual void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
+ private int selectedCustomExplorerIndex;
+
public int SelectedCustomExplorerIndex
{
get => selectedCustomExplorerIndex; set
{
selectedCustomExplorerIndex = value;
- PropertyChanged?.Invoke(this, new(nameof(CustomExplorer)));
+ OnPropertyChanged(nameof(CustomExplorer));
}
}
public ObservableCollection CustomExplorers { get; set; }
@@ -81,8 +64,7 @@ private void btnDelete_Click(object sender, RoutedEventArgs e)
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
- Nullable result = dlg.ShowDialog();
-
+ var result = dlg.ShowDialog();
if (result == true)
{
TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index 44a0490ca19..4bf5df227e5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -160,8 +160,7 @@
DisplayMemberPath="Source"
ItemsSource="{Binding Source={StaticResource SortedFonts}}"
SelectedValue="{Binding SettingWindowFont, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
- SelectedValuePath="Source"
- SelectionChanged="SettingWindowFontComboBox_SelectionChanged" />
+ SelectedValuePath="Source" />
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index cedc196333d..1ecc02aa6b3 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -1,7 +1,4 @@
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Navigation;
+using System.Windows.Navigation;
using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -31,21 +28,4 @@ private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
App.API.OpenUrl(e.Uri.AbsoluteUri);
e.Handled = true;
}
-
- private void SettingWindowFontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (sender is ComboBox comboBox && comboBox.SelectedItem is FontFamily selectedFont)
- {
- if (DataContext is SettingsPaneAboutViewModel viewModel)
- {
- viewModel.SettingWindowFont = selectedFont.Source;
-
- // 설정 창 글꼴 즉시 업데이트
- if (Window.GetWindow(this) is SettingWindow settingWindow)
- {
- settingWindow.FontFamily = selectedFont;
- }
- }
- }
- }
}
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index f2cf9fab23f..a34777d3020 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -13,7 +13,7 @@
MinHeight="600"
d:DataContext="{d:DesignInstance vm:SettingWindowViewModel}"
Closed="OnClosed"
- FontFamily="{Binding SettingWindowFont, Mode=TwoWay}"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 4468b7865dc..19edba4d942 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,17 +1,15 @@
-using System.ComponentModel;
-using System.Windows.Media;
-using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
- private readonly Settings _settings;
+ public Settings Settings { get; set; }
public SettingWindowViewModel(Settings settings)
{
- _settings = settings;
+ Settings = settings;
}
///
@@ -19,44 +17,30 @@ public SettingWindowViewModel(Settings settings)
///
public void Save()
{
- _settings.Save();
+ Settings.Save();
}
public double SettingWindowWidth
{
- get => _settings.SettingWindowWidth;
- set => _settings.SettingWindowWidth = value;
+ get => Settings.SettingWindowWidth;
+ set => Settings.SettingWindowWidth = value;
}
public double SettingWindowHeight
{
- get => _settings.SettingWindowHeight;
- set => _settings.SettingWindowHeight = value;
+ get => Settings.SettingWindowHeight;
+ set => Settings.SettingWindowHeight = value;
}
public double? SettingWindowTop
{
- get => _settings.SettingWindowTop;
- set => _settings.SettingWindowTop = value;
+ get => Settings.SettingWindowTop;
+ set => Settings.SettingWindowTop = value;
}
public double? SettingWindowLeft
{
- get => _settings.SettingWindowLeft;
- set => _settings.SettingWindowLeft = value;
+ get => Settings.SettingWindowLeft;
+ set => Settings.SettingWindowLeft = value;
}
-
- public string SettingWindowFont
- {
- get => _settings.SettingWindowFont;
- set
- {
- if (_settings.SettingWindowFont != value)
- {
- _settings.SettingWindowFont = value;
- OnPropertyChanged(nameof(SettingWindowFont));
- }
- }
- }
-
}
From f4f8e9af5247c2004e6771236784ebe2e5e13b61 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 23 Apr 2025 12:49:36 +0800
Subject: [PATCH 1096/1335] Make settings readonly
---
Flow.Launcher/CustomQueryHotkeySetting.xaml.cs | 2 +-
Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 +-
Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index 3c501d41a73..cc07caaa21e 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -10,7 +10,7 @@ namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- public Settings Settings { get; set; }
+ public Settings Settings { get; }
private bool update;
private CustomPluginHotkey updateCustomHotkey;
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index 183cc3a7ff6..fcee0c96196 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -8,7 +8,7 @@ namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
- public Settings Settings { get; set; } = Ioc.Default.GetRequiredService();
+ public Settings Settings { get; } = Ioc.Default.GetRequiredService();
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
public string Key { get; set; } = string.Empty;
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 19edba4d942..f05893cf476 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -5,7 +5,7 @@ namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
- public Settings Settings { get; set; }
+ public Settings Settings { get; }
public SettingWindowViewModel(Settings settings)
{
From f79ef493b8eab23ce66cb7f25e68c76836ddd149 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 23 Apr 2025 13:58:01 +0900
Subject: [PATCH 1097/1335] Remove background setter for disabled state and add
placeholder color for NumberBox
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 1 -
Flow.Launcher/Resources/Dark.xaml | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index ef85e8724b7..251d74c147b 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -2802,7 +2802,6 @@
-
diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml
index 1ec01f8d143..3fd66d62337 100644
--- a/Flow.Launcher/Resources/Dark.xaml
+++ b/Flow.Launcher/Resources/Dark.xaml
@@ -107,6 +107,7 @@
#f5f5f5
#464646
#ffffff
+
#272727
From f50f2ff27c1aedd064e2b213adee24d4b485df30 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 24 Apr 2025 10:18:38 +0900
Subject: [PATCH 1098/1335] Implement dynamic font settings for the setting
window
---
.../UserSettings/Settings.cs | 2 ++
Flow.Launcher/CustomQueryHotkeySetting.xaml | 1 -
Flow.Launcher/CustomShortcutSetting.xaml | 1 -
Flow.Launcher/Languages/en.xaml | 2 +-
Flow.Launcher/Resources/CustomControlTemplate.xaml | 14 ++++++++++++++
Flow.Launcher/Resources/SettingWindowStyle.xaml | 1 +
Flow.Launcher/SelectBrowserWindow.xaml | 1 -
Flow.Launcher/SelectFileManagerWindow.xaml | 1 -
.../SettingPages/Views/SettingsPaneAbout.xaml | 8 +++-----
.../SettingPages/Views/SettingsPanePlugins.xaml | 6 +++---
Flow.Launcher/SettingWindow.xaml | 1 -
Flow.Launcher/WelcomeWindow.xaml | 14 ++++++--------
12 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 0f878151e72..ca015fd70ca 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
using System.Windows;
+using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Logger;
@@ -113,6 +114,7 @@ public string SettingWindowFont
{
_settingWindowFont = value;
OnPropertyChanged();
+ Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
}
}
}
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml
index d3c31c6da5c..0171e6d79c3 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml
@@ -8,7 +8,6 @@
Width="530"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
Icon="Images\app.png"
MouseDown="window_MouseDown"
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml b/Flow.Launcher/CustomShortcutSetting.xaml
index cbdcecea6a9..d8623753f63 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml
+++ b/Flow.Launcher/CustomShortcutSetting.xaml
@@ -7,7 +7,6 @@
Width="530"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
Icon="Images\app.png"
ResizeMode="NoResize"
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 04a26f09c86..72897521b6d 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -355,7 +355,7 @@
Log Level
Debug
Info
- Setting Window Font
+ Setting Window Font
Select File Manager
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index ef85e8724b7..be68fc1b1c6 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -4,6 +4,20 @@
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019">
+
+
+
+
+
+
diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml
index fc9246aa33d..c59baeaea4b 100644
--- a/Flow.Launcher/Resources/SettingWindowStyle.xaml
+++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml
@@ -7,6 +7,7 @@
+ Segoe UI
F1 M512,512z M0,0z M448,256C448,150,362,64,256,64L256,448C362,448,448,362,448,256z M0,256A256,256,0,1,1,512,256A256,256,0,1,1,0,256z
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml
index 4fc5a91c5da..4a0928dc2e6 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml
+++ b/Flow.Launcher/SelectBrowserWindow.xaml
@@ -10,7 +10,6 @@
Width="550"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml b/Flow.Launcher/SelectFileManagerWindow.xaml
index 7d1fe0f567f..0287af9b03a 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml
@@ -10,7 +10,6 @@
Width="600"
Background="{DynamicResource PopuBGColor}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
- FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Height"
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
index 4bf5df227e5..1a92ad0c24a 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml
@@ -103,10 +103,8 @@
Margin="0 0 12 0"
Command="{Binding AskClearLogFolderConfirmationCommand}"
Content="{Binding LogFolderSize, Mode=OneWay}" />
-
+
+
@@ -148,7 +146,7 @@
SelectedValuePath="Value" />
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index f3d63030625..bb742f800e0 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -58,9 +58,9 @@
Margin="0 0 20 0"
Command="{Binding OpenHelperCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
- Content=""
- FontFamily="{DynamicResource SymbolThemeFontFamily}"
- FontSize="14" />
+ FontSize="14">
+
+
+ IsEnabled="{Binding NextEnabled, Mode=OneWay}">
+
+
+ IsEnabled="{Binding BackEnabled, Mode=OneWay}">
+
+
From 25f39f6934921cc52a4f59243f7adef430b2ed0e Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 24 Apr 2025 11:08:02 +0900
Subject: [PATCH 1099/1335] Add dynamic font support for the setting window
---
Flow.Launcher/App.xaml.cs | 2 ++
Flow.Launcher/SettingWindow.xaml | 1 +
2 files changed, 3 insertions(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 87698a54571..606536dad84 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
@@ -175,6 +176,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
await imageLoadertask;
_mainWindow = new MainWindow();
+ Current.Resources["SettingWindowFont"] = new FontFamily(_settings.SettingWindowFont);
API.LogInfo(ClassName, "Dependencies Info:{ErrorReporting.DependenciesInfo()}");
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index ab27b235a2c..a34777d3020 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -13,6 +13,7 @@
MinHeight="600"
d:DataContext="{d:DesignInstance vm:SettingWindowViewModel}"
Closed="OnClosed"
+ FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
From 8432fa3b40ceb87916676fc5021e7e72dac54078 Mon Sep 17 00:00:00 2001
From: DB p
Date: Thu, 24 Apr 2025 11:25:21 +0900
Subject: [PATCH 1100/1335] Add SettingWindowFont definition to
CustomControlTemplate
---
Flow.Launcher/Resources/CustomControlTemplate.xaml | 1 +
Flow.Launcher/Resources/SettingWindowStyle.xaml | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml
index be68fc1b1c6..4e94da526f7 100644
--- a/Flow.Launcher/Resources/CustomControlTemplate.xaml
+++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml
@@ -5,6 +5,7 @@
xmlns:ui="http://schemas.modernwpf.com/2019">
+ Segoe UI
diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml
index c59baeaea4b..60655fa7c32 100644
--- a/Flow.Launcher/Resources/SettingWindowStyle.xaml
+++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml
@@ -7,8 +7,6 @@
- Segoe UI
-
F1 M512,512z M0,0z M448,256C448,150,362,64,256,64L256,448C362,448,448,362,448,256z M0,256A256,256,0,1,1,512,256A256,256,0,1,1,0,256z
+
+ {DynamicResource SettingWindowFont}
+
@@ -1360,7 +1363,6 @@
-
@@ -1584,6 +1586,7 @@
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
index 32fdb62fc71..b6a99d9e993 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml
@@ -127,7 +127,7 @@
Style="{DynamicResource StyleImageFadeIn}" />
-
-
+
+
@@ -89,29 +89,29 @@
-
+
@@ -81,26 +81,26 @@
Canvas.Left="0"
Width="450"
Height="280"
- Margin="0,0,0,0"
+ Margin="0 0 0 0"
Source="../../images/page_img01.png"
Style="{DynamicResource StyleImageFadeIn}" />
-
+
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
index 3df4b506ed2..7495231aece 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml
@@ -79,18 +79,18 @@
-
+
-
+
-
+
+ Padding="5 18 0 0">
+ Margin="5 24 0 0">
@@ -97,8 +97,8 @@
@@ -71,9 +71,9 @@
+ IsEnabled="{Binding Settings.Proxy.Enabled}" />
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml
index f5017ced5d8..80b004ff993 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/CustomBrowserSetting.xaml
@@ -60,17 +60,17 @@
-
-
+
+
-
+
@@ -86,23 +86,23 @@
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
- Margin="5,0,0,20">
+ Margin="5 0 0 20">
@@ -180,18 +180,18 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
- BorderThickness="0,1,0,0">
+ BorderThickness="0 1 0 0">
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
index 37a7ccb8d5b..ae0f91d93a8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
@@ -57,20 +57,20 @@
-
-
+
+
-
+
-
+
+ BorderThickness="0 1 0 0">
diff --git a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml
index 9848f51cfe0..26efc681322 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/AddProgramSource.xaml
@@ -5,21 +5,21 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Flow.Launcher.Plugin.Program.ViewModels"
- mc:Ignorable="d"
Title="{DynamicResource flowlauncher_plugin_program_directory}"
- d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}"
Width="Auto"
Height="276"
+ d:DataContext="{d:DesignInstance vm:AddProgramSourceViewModel}"
Background="{DynamicResource PopuBGColor}"
Foreground="{DynamicResource PopupTextColor}"
ResizeMode="NoResize"
SizeToContent="Width"
- WindowStartupLocation="CenterScreen">
+ WindowStartupLocation="CenterScreen"
+ mc:Ignorable="d">
-
+
@@ -59,11 +59,11 @@
-
-
+
+
-
+
@@ -104,16 +104,16 @@
HorizontalAlignment="Stretch"
Click="BrowseButton_Click"
Content="{DynamicResource flowlauncher_plugin_program_browse}"
- Visibility="{Binding IsCustomSource, Converter={StaticResource BooleanToVisibilityConverter}}"
- DockPanel.Dock="Right" />
+ DockPanel.Dock="Right"
+ Visibility="{Binding IsCustomSource, Converter={StaticResource BooleanToVisibilityConverter}}" />
+ VerticalAlignment="Center"
+ IsReadOnly="{Binding IsNotCustomSource}"
+ Text="{Binding Location, Mode=TwoWay}" />
+ Margin="10 0"
+ VerticalAlignment="Center"
+ IsChecked="{Binding Enabled, Mode=TwoWay}" />
+ BorderThickness="0 1 0 0">
diff --git a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml
index 71bc12a8678..53baa79a316 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/ProgramSuffixes.xaml
@@ -46,8 +46,8 @@
-
-
+
+
@@ -65,8 +65,8 @@
-
-
+
+
@@ -120,20 +120,20 @@
-
+
-
+
@@ -151,82 +151,82 @@
TextWrapping="Wrap" />
-
+
-
+
appref-ms
exe
lnk
+ BorderThickness="1 0 0 0">
@@ -237,27 +237,27 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
- BorderThickness="0,1,0,0">
+ BorderThickness="0 1 0 0">
Date: Thu, 24 Apr 2025 19:48:42 +0800
Subject: [PATCH 1105/1335] Improve code quality
---
.../CustomQueryHotkeySetting.xaml.cs | 10 +--
Flow.Launcher/CustomShortcutSetting.xaml.cs | 4 --
.../Resources/Controls/HotkeyDisplay.xaml.cs | 9 +--
.../Resources/Pages/WelcomePage1.xaml.cs | 20 ++++--
.../Resources/Pages/WelcomePage2.xaml.cs | 24 ++++---
.../Resources/Pages/WelcomePage3.xaml.cs | 16 +++--
.../Resources/Pages/WelcomePage4.xaml.cs | 20 ++++--
.../Resources/Pages/WelcomePage5.xaml.cs | 65 ++++++++++++-------
Flow.Launcher/SelectBrowserWindow.xaml.cs | 15 +++--
Flow.Launcher/SelectFileManagerWindow.xaml.cs | 15 +++--
.../SettingsPaneGeneralViewModel.cs | 3 +-
.../SettingsPanePluginStoreViewModel.cs | 1 -
12 files changed, 120 insertions(+), 82 deletions(-)
diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
index cc07caaa21e..77febde9d5b 100644
--- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
+++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs
@@ -10,14 +10,14 @@ namespace Flow.Launcher
{
public partial class CustomQueryHotkeySetting : Window
{
- public Settings Settings { get; }
+ private readonly Settings _settings;
private bool update;
private CustomPluginHotkey updateCustomHotkey;
public CustomQueryHotkeySetting(Settings settings)
{
- Settings = settings;
+ _settings = settings;
InitializeComponent();
}
@@ -30,13 +30,13 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
if (!update)
{
- Settings.CustomPluginHotkeys ??= new ObservableCollection();
+ _settings.CustomPluginHotkeys ??= new ObservableCollection();
var pluginHotkey = new CustomPluginHotkey
{
Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
};
- Settings.CustomPluginHotkeys.Add(pluginHotkey);
+ _settings.CustomPluginHotkeys.Add(pluginHotkey);
HotKeyMapper.SetCustomQueryHotkey(pluginHotkey);
}
@@ -55,7 +55,7 @@ private void btnAdd_OnClick(object sender, RoutedEventArgs e)
public void UpdateItem(CustomPluginHotkey item)
{
- updateCustomHotkey = Settings.CustomPluginHotkeys.FirstOrDefault(o =>
+ updateCustomHotkey = _settings.CustomPluginHotkeys.FirstOrDefault(o =>
o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
if (updateCustomHotkey == null)
{
diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs
index fcee0c96196..e180f657024 100644
--- a/Flow.Launcher/CustomShortcutSetting.xaml.cs
+++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs
@@ -1,15 +1,11 @@
using System.Windows;
using System.Windows.Input;
-using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher
{
public partial class CustomShortcutSetting : Window
{
- public Settings Settings { get; } = Ioc.Default.GetRequiredService();
-
private readonly SettingsPaneHotkeyViewModel _hotkeyVm;
public string Key { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
diff --git a/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs b/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs
index 9b19ffd8626..bc167184b73 100644
--- a/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs
+++ b/Flow.Launcher/Resources/Controls/HotkeyDisplay.xaml.cs
@@ -42,14 +42,11 @@ public DisplayType Type
private static void keyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- var control = d as UserControl;
- if (null == control) return; // This should not be possible
+ if (d is not UserControl) return; // This should not be possible
- var newValue = e.NewValue as string;
- if (null == newValue) return;
+ if (e.NewValue is not string newValue) return;
- if (d is not HotkeyDisplay hotkeyDisplay)
- return;
+ if (d is not HotkeyDisplay hotkeyDisplay) return;
hotkeyDisplay.Values.Clear();
foreach (var key in newValue.Split('+'))
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 64f52edffe3..a3b008206d6 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -1,29 +1,35 @@
using System.Collections.Generic;
using System.Windows.Navigation;
-using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage1
{
+ public Settings Settings { get; private set; }
+ private WelcomeViewModel _viewModel;
+
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- Settings = Ioc.Default.GetRequiredService();
+ if (!IsInitialized)
+ {
+ Settings = Ioc.Default.GetRequiredService();
+ _viewModel = Ioc.Default.GetRequiredService();
+ InitializeComponent();
+ }
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
- Ioc.Default.GetRequiredService().PageNum = 1;
- InitializeComponent();
+ _viewModel.PageNum = 1;
+ base.OnNavigatedTo(e);
}
private readonly Internationalization _translater = Ioc.Default.GetRequiredService();
public List Languages => _translater.LoadAvailableLanguages();
- public Settings Settings { get; set; }
-
public string CustomLanguage
{
get
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 786b4d5063d..a63edbcda7c 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -1,25 +1,31 @@
-using Flow.Launcher.Helper;
-using Flow.Launcher.Infrastructure.Hotkey;
-using Flow.Launcher.Infrastructure.UserSettings;
+using System.Windows.Media;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.ViewModel;
-using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Helper;
+using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage2
{
- public Settings Settings { get; set; }
+ public Settings Settings { get; private set; }
+ private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- Settings = Ioc.Default.GetRequiredService();
+ if (!IsInitialized)
+ {
+ Settings = Ioc.Default.GetRequiredService();
+ _viewModel = Ioc.Default.GetRequiredService();
+ InitializeComponent();
+ }
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
- Ioc.Default.GetRequiredService().PageNum = 2;
- InitializeComponent();
+ _viewModel.PageNum = 2;
+ base.OnNavigatedTo(e);
}
[RelayCommand]
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index f59b65c1c4c..4a6610e6173 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -7,15 +7,21 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage3
{
+ public Settings Settings { get; private set; }
+ private WelcomeViewModel _viewModel;
+
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- Settings = Ioc.Default.GetRequiredService();
+ if (!IsInitialized)
+ {
+ Settings = Ioc.Default.GetRequiredService();
+ _viewModel = Ioc.Default.GetRequiredService();
+ InitializeComponent();
+ }
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
- Ioc.Default.GetRequiredService().PageNum = 3;
- InitializeComponent();
+ _viewModel.PageNum = 3;
+ base.OnNavigatedTo(e);
}
-
- public Settings Settings { get; set; }
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index 4c83f3a83e0..1ee3284d22e 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -1,21 +1,27 @@
-using CommunityToolkit.Mvvm.DependencyInjection;
+using System.Windows.Navigation;
+using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
-using System.Windows.Navigation;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage4
{
+ public Settings Settings { get; private set; }
+ private WelcomeViewModel _viewModel;
+
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- Settings = Ioc.Default.GetRequiredService();
+ if (!IsInitialized)
+ {
+ Settings = Ioc.Default.GetRequiredService();
+ _viewModel = Ioc.Default.GetRequiredService();
+ InitializeComponent();
+ }
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
- Ioc.Default.GetRequiredService().PageNum = 4;
- InitializeComponent();
+ _viewModel.PageNum = 4;
+ base.OnNavigatedTo(e);
}
-
- public Settings Settings { get; set; }
}
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index 95d7ff1a0d2..6328c991449 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -1,54 +1,74 @@
-using System.Windows;
+using System;
+using System.Windows;
using System.Windows.Navigation;
-using Flow.Launcher.Infrastructure.UserSettings;
-using Microsoft.Win32;
-using Flow.Launcher.Infrastructure;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Helper;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage5
{
- private const string StartupPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
- public Settings Settings { get; set; }
- public bool HideOnStartup { get; set; }
+ public Settings Settings { get; private set; }
+ private WelcomeViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- Settings = Ioc.Default.GetRequiredService();
+ if (!IsInitialized)
+ {
+ Settings = Ioc.Default.GetRequiredService();
+ _viewModel = Ioc.Default.GetRequiredService();
+ InitializeComponent();
+ }
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
- Ioc.Default.GetRequiredService().PageNum = 5;
- InitializeComponent();
+ _viewModel.PageNum = 5;
+ base.OnNavigatedTo(e);
}
private void OnAutoStartupChecked(object sender, RoutedEventArgs e)
{
- SetStartup();
+ ChangeAutoStartup(true);
}
+
private void OnAutoStartupUncheck(object sender, RoutedEventArgs e)
{
- RemoveStartup();
+ ChangeAutoStartup(false);
}
- private void RemoveStartup()
+ private void ChangeAutoStartup(bool value)
{
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.DeleteValue(Constant.FlowLauncher, false);
- Settings.StartFlowLauncherOnSystemStartup = false;
- }
- private void SetStartup()
- {
- using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
- key?.SetValue(Constant.FlowLauncher, Constant.ExecutablePath);
- Settings.StartFlowLauncherOnSystemStartup = true;
+ Settings.StartFlowLauncherOnSystemStartup = value;
+ try
+ {
+ if (value)
+ {
+ if (Settings.UseLogonTaskForStartup)
+ {
+ AutoStartup.ChangeToViaLogonTask();
+ }
+ else
+ {
+ AutoStartup.ChangeToViaRegistry();
+ }
+ }
+ else
+ {
+ AutoStartup.DisableViaLogonTaskAndRegistry();
+ }
+ }
+ catch (Exception e)
+ {
+ App.API.ShowMsg(App.API.GetTranslation("setAutoStartFailed"), e.Message);
+ }
}
private void OnHideOnStartupChecked(object sender, RoutedEventArgs e)
{
Settings.HideOnStartup = true;
}
+
private void OnHideOnStartupUnchecked(object sender, RoutedEventArgs e)
{
Settings.HideOnStartup = false;
@@ -59,6 +79,5 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
var window = Window.GetWindow(this);
window.Close();
}
-
}
}
diff --git a/Flow.Launcher/SelectBrowserWindow.xaml.cs b/Flow.Launcher/SelectBrowserWindow.xaml.cs
index 849056ab104..bea5b4352ac 100644
--- a/Flow.Launcher/SelectBrowserWindow.xaml.cs
+++ b/Flow.Launcher/SelectBrowserWindow.xaml.cs
@@ -10,13 +10,14 @@ namespace Flow.Launcher
[INotifyPropertyChanged]
public partial class SelectBrowserWindow : Window
{
- public Settings Settings { get; }
+ private readonly Settings _settings;
private int selectedCustomBrowserIndex;
public int SelectedCustomBrowserIndex
{
- get => selectedCustomBrowserIndex; set
+ get => selectedCustomBrowserIndex;
+ set
{
selectedCustomBrowserIndex = value;
OnPropertyChanged(nameof(CustomBrowser));
@@ -27,9 +28,9 @@ public int SelectedCustomBrowserIndex
public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
public SelectBrowserWindow(Settings settings)
{
- Settings = settings;
- CustomBrowsers = new ObservableCollection(Settings.CustomBrowserList.Select(x => x.Copy()));
- SelectedCustomBrowserIndex = Settings.CustomBrowserIndex;
+ _settings = settings;
+ CustomBrowsers = new ObservableCollection(_settings.CustomBrowserList.Select(x => x.Copy()));
+ SelectedCustomBrowserIndex = _settings.CustomBrowserIndex;
InitializeComponent();
}
@@ -40,8 +41,8 @@ private void btnCancel_Click(object sender, RoutedEventArgs e)
private void btnDone_Click(object sender, RoutedEventArgs e)
{
- Settings.CustomBrowserList = CustomBrowsers.ToList();
- Settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
+ _settings.CustomBrowserList = CustomBrowsers.ToList();
+ _settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
Close();
}
diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
index 946052e320b..bf94ddacb01 100644
--- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs
+++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs
@@ -12,13 +12,14 @@ namespace Flow.Launcher
[INotifyPropertyChanged]
public partial class SelectFileManagerWindow : Window
{
- public Settings Settings { get; }
+ private readonly Settings _settings;
private int selectedCustomExplorerIndex;
public int SelectedCustomExplorerIndex
{
- get => selectedCustomExplorerIndex; set
+ get => selectedCustomExplorerIndex;
+ set
{
selectedCustomExplorerIndex = value;
OnPropertyChanged(nameof(CustomExplorer));
@@ -29,9 +30,9 @@ public int SelectedCustomExplorerIndex
public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex];
public SelectFileManagerWindow(Settings settings)
{
- Settings = settings;
- CustomExplorers = new ObservableCollection(Settings.CustomExplorerList.Select(x => x.Copy()));
- SelectedCustomExplorerIndex = Settings.CustomExplorerIndex;
+ _settings = settings;
+ CustomExplorers = new ObservableCollection(_settings.CustomExplorerList.Select(x => x.Copy()));
+ SelectedCustomExplorerIndex = _settings.CustomExplorerIndex;
InitializeComponent();
}
@@ -42,8 +43,8 @@ private void btnCancel_Click(object sender, RoutedEventArgs e)
private void btnDone_Click(object sender, RoutedEventArgs e)
{
- Settings.CustomExplorerList = CustomExplorers.ToList();
- Settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
+ _settings.CustomExplorerList = CustomExplorers.ToList();
+ _settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
Close();
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 6b56caf5e74..c8b83c730b6 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -17,6 +17,7 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneGeneralViewModel : BaseModel
{
public Settings Settings { get; }
+
private readonly Updater _updater;
private readonly IPortable _portable;
private readonly Internationalization _translater;
@@ -78,7 +79,7 @@ public bool UseLogonTaskForStartup
{
try
{
- if (UseLogonTaskForStartup)
+ if (value)
{
AutoStartup.ChangeToViaLogonTask();
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index fd2c8e09fa1..68c69f8411b 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -2,7 +2,6 @@
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
-using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
From 94ff72c8f27d48201bc195ef32bdf801ddeb4d13 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 19:49:03 +0800
Subject: [PATCH 1106/1335] Check startup only for Release
---
Flow.Launcher/App.xaml.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 6a7b892be3d..ba0f4e5ed86 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -201,6 +201,10 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
#pragma warning restore VSTHRD100 // Avoid async void methods
+ ///
+ /// Check startup only for Release
+ ///
+ [Conditional("RELEASE")]
private void AutoStartup()
{
// we try to enable auto-startup on first launch, or reenable if it was removed
From 4df9c04702062a177a517bd1328ff547eb03a06b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 19:49:34 +0800
Subject: [PATCH 1107/1335] Update dynamic resource earilier
---
Flow.Launcher/App.xaml.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index ba0f4e5ed86..e91676b7bb9 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -147,6 +147,10 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
Log.SetLogLevel(_settings.LogLevel);
+ // Update dynamic resources base on settings
+ Current.Resources["SettingWindowFont"] = new FontFamily(_settings.SettingWindowFont);
+ Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(_settings.SettingWindowFont);
+
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
API.LogInfo(ClassName, "Begin Flow Launcher startup ----------------------------------------------------");
@@ -176,8 +180,6 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
await imageLoadertask;
_mainWindow = new MainWindow();
- Current.Resources["SettingWindowFont"] = new FontFamily(_settings.SettingWindowFont);
- Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(_settings.SettingWindowFont);
API.LogInfo(ClassName, "Dependencies Info:{ErrorReporting.DependenciesInfo()}");
From 71ab7a69328a904b7cf4d97f5bd526f098e1ad22 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 19:49:58 +0800
Subject: [PATCH 1108/1335] Fix log message & Improve code comments
---
Flow.Launcher/App.xaml.cs | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index e91676b7bb9..ac134fb5fa9 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -154,7 +154,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate();
API.LogInfo(ClassName, "Begin Flow Launcher startup ----------------------------------------------------");
- API.LogInfo(ClassName, "Runtime info:{ErrorReporting.RuntimeInfo()}");
+ API.LogInfo(ClassName, $"Runtime info:{ErrorReporting.RuntimeInfo()}");
RegisterAppDomainExceptions();
RegisterDispatcherUnhandledException();
@@ -174,19 +174,16 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
await PluginManager.InitializePluginsAsync();
// Change language after all plugins are initialized because we need to update plugin title based on their api
- // TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
await Ioc.Default.GetRequiredService().InitializeLanguageAsync();
await imageLoadertask;
_mainWindow = new MainWindow();
- API.LogInfo(ClassName, "Dependencies Info:{ErrorReporting.DependenciesInfo()}");
-
Current.MainWindow = _mainWindow;
Current.MainWindow.Title = Constant.FlowLauncher;
- // main windows needs initialized before theme change because of blur settings
+ // Main windows needs initialized before theme change because of blur settings
Ioc.Default.GetRequiredService().ChangeTheme();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@@ -270,7 +267,7 @@ private void RegisterExitEvents()
}
///
- /// let exception throw as normal is better for Debug
+ /// Let exception throw as normal is better for Debug
///
[Conditional("RELEASE")]
private void RegisterDispatcherUnhandledException()
@@ -279,7 +276,7 @@ private void RegisterDispatcherUnhandledException()
}
///
- /// let exception throw as normal is better for Debug
+ /// Let exception throw as normal is better for Debug
///
[Conditional("RELEASE")]
private static void RegisterAppDomainExceptions()
@@ -288,7 +285,7 @@ private static void RegisterAppDomainExceptions()
}
///
- /// let exception throw as normal is better for Debug
+ /// Let exception throw as normal is better for Debug
///
[Conditional("RELEASE")]
private static void RegisterTaskSchedulerUnhandledException()
From 89127895d0541d8bab36dc57a1e6b2183980e7b0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 19:50:20 +0800
Subject: [PATCH 1109/1335] Use http client for code quality
---
.../ViewModels/SettingsPaneProxyViewModel.cs | 38 +++++++++----------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
index 38a6ef31eaa..6cddee8d88e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneProxyViewModel.cs
@@ -1,4 +1,6 @@
using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure.UserSettings;
@@ -8,49 +10,43 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneProxyViewModel : BaseModel
{
- private readonly Updater _updater;
public Settings Settings { get; }
+ private readonly Updater _updater;
+
public SettingsPaneProxyViewModel(Settings settings, Updater updater)
{
- _updater = updater;
Settings = settings;
+ _updater = updater;
}
[RelayCommand]
- private void OnTestProxyClicked()
+ private async Task OnTestProxyClickedAsync()
{
- var message = TestProxy();
+ var message = await TestProxyAsync();
App.API.ShowMsgBox(App.API.GetTranslation(message));
}
- private string TestProxy()
+ private async Task TestProxyAsync()
{
if (string.IsNullOrEmpty(Settings.Proxy.Server)) return "serverCantBeEmpty";
if (Settings.Proxy.Port <= 0) return "portCantBeEmpty";
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_updater.GitHubRepository);
-
- if (string.IsNullOrEmpty(Settings.Proxy.UserName) || string.IsNullOrEmpty(Settings.Proxy.Password))
+ var handler = new HttpClientHandler
{
- request.Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port);
- }
- else
+ Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port)
+ };
+
+ if (!string.IsNullOrEmpty(Settings.Proxy.UserName) && !string.IsNullOrEmpty(Settings.Proxy.Password))
{
- request.Proxy = new WebProxy(Settings.Proxy.Server, Settings.Proxy.Port)
- {
- Credentials = new NetworkCredential(Settings.Proxy.UserName, Settings.Proxy.Password)
- };
+ handler.Proxy.Credentials = new NetworkCredential(Settings.Proxy.UserName, Settings.Proxy.Password);
}
+ using var client = new HttpClient(handler);
try
{
- var response = (HttpWebResponse)request.GetResponse();
- return response.StatusCode switch
- {
- HttpStatusCode.OK => "proxyIsCorrect",
- _ => "proxyConnectFailed"
- };
+ var response = await client.GetAsync(_updater.GitHubRepository);
+ return response.IsSuccessStatusCode ? "proxyIsCorrect" : "proxyConnectFailed";
}
catch
{
From 8463304bd4811ed70a13d75b916153b12dd9fed0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 19:56:31 +0800
Subject: [PATCH 1110/1335] Fix clock panel font issue & Improve preview
performance & Improve code quality
---
.../ViewModels/SettingsPaneThemeViewModel.cs | 104 +++++++++---------
.../SettingPages/Views/SettingsPaneTheme.xaml | 4 +-
.../Views/SettingsPaneTheme.xaml.cs | 6 +-
3 files changed, 59 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 1138b286975..d542eb019f9 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -6,7 +6,6 @@
using System.IO;
using System.Linq;
using System.Windows.Media;
-using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@@ -22,10 +21,12 @@ namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneThemeViewModel : BaseModel
{
+ public Settings Settings { get; }
+
+ private readonly Theme _theme;
+
private readonly string DefaultFont = Win32Helper.GetSystemDefaultFont();
public string BackdropSubText => !Win32Helper.IsBackdropSupported() ? App.API.GetTranslation("BackdropTypeDisabledToolTip") : "";
- public Settings Settings { get; }
- private readonly Theme _theme = Ioc.Default.GetRequiredService();
public static string LinkHowToCreateTheme => @"https://www.flowlauncher.com/theme-builder/";
public static string LinkThemeGallery => "https://github.com/Flow-Launcher/Flow.Launcher/discussions/1438";
@@ -289,59 +290,14 @@ public bool UseDate
set => Settings.UseDate = value;
}
+ public FontFamily ClockPanelFont { get; }
+
public Brush PreviewBackground
{
get => WallpaperPathRetrieval.GetWallpaperBrush();
}
- public ResultsViewModel PreviewResults
- {
- get
- {
- var results = new List
- {
- new()
- {
- Title = App.API.GetTranslation("SampleTitleExplorer"),
- SubTitle = App.API.GetTranslation("SampleSubTitleExplorer"),
- IcoPath = Path.Combine(
- Constant.ProgramDirectory,
- @"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png"
- )
- },
- new()
- {
- Title = App.API.GetTranslation("SampleTitleWebSearch"),
- SubTitle = App.API.GetTranslation("SampleSubTitleWebSearch"),
- IcoPath = Path.Combine(
- Constant.ProgramDirectory,
- @"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png"
- )
- },
- new()
- {
- Title = App.API.GetTranslation("SampleTitleProgram"),
- SubTitle = App.API.GetTranslation("SampleSubTitleProgram"),
- IcoPath = Path.Combine(
- Constant.ProgramDirectory,
- @"Plugins\Flow.Launcher.Plugin.Program\Images\program.png"
- )
- },
- new()
- {
- Title = App.API.GetTranslation("SampleTitleProcessKiller"),
- SubTitle = App.API.GetTranslation("SampleSubTitleProcessKiller"),
- IcoPath = Path.Combine(
- Constant.ProgramDirectory,
- @"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png"
- )
- }
- };
- var vm = new ResultsViewModel(Settings);
- vm.AddResults(results, "PREVIEW");
- return vm;
- }
- }
+ public ResultsViewModel PreviewResults { get; }
public FontFamily SelectedQueryBoxFont
{
@@ -479,9 +435,53 @@ public FamilyTypeface SelectedResultSubFontFaces
public string ThemeImage => Constant.QueryTextBoxIconImagePath;
- public SettingsPaneThemeViewModel(Settings settings)
+ public SettingsPaneThemeViewModel(Settings settings, Theme theme)
{
Settings = settings;
+ _theme = theme;
+ ClockPanelFont = new FontFamily(DefaultFont);
+ var results = new List
+ {
+ new()
+ {
+ Title = App.API.GetTranslation("SampleTitleExplorer"),
+ SubTitle = App.API.GetTranslation("SampleSubTitleExplorer"),
+ IcoPath = Path.Combine(
+ Constant.ProgramDirectory,
+ @"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png"
+ )
+ },
+ new()
+ {
+ Title = App.API.GetTranslation("SampleTitleWebSearch"),
+ SubTitle = App.API.GetTranslation("SampleSubTitleWebSearch"),
+ IcoPath = Path.Combine(
+ Constant.ProgramDirectory,
+ @"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png"
+ )
+ },
+ new()
+ {
+ Title = App.API.GetTranslation("SampleTitleProgram"),
+ SubTitle = App.API.GetTranslation("SampleSubTitleProgram"),
+ IcoPath = Path.Combine(
+ Constant.ProgramDirectory,
+ @"Plugins\Flow.Launcher.Plugin.Program\Images\program.png"
+ )
+ },
+ new()
+ {
+ Title = App.API.GetTranslation("SampleTitleProcessKiller"),
+ SubTitle = App.API.GetTranslation("SampleSubTitleProcessKiller"),
+ IcoPath = Path.Combine(
+ Constant.ProgramDirectory,
+ @"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png"
+ )
+ }
+ };
+ var vm = new ResultsViewModel(Settings);
+ vm.AddResults(results, "PREVIEW");
+ PreviewResults = vm;
}
[RelayCommand]
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index f7853515a38..4640165f6e2 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -331,20 +331,22 @@
IsReadOnly="True"
Style="{DynamicResource QueryBoxStyle}"
Text="{DynamicResource hiThere}" />
-
+
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index f4c103ade01..a1a0231a526 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -1,7 +1,8 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.SettingPages.ViewModels;
using Page = ModernWpf.Controls.Page;
namespace Flow.Launcher.SettingPages.Views;
@@ -15,7 +16,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
if (!IsInitialized)
{
var settings = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneThemeViewModel(settings);
+ var theme = Ioc.Default.GetRequiredService();
+ _viewModel = new SettingsPaneThemeViewModel(settings, theme);
DataContext = _viewModel;
InitializeComponent();
}
From 82d97fd05af3014eb9acb18092dd86d359b44fdc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 20:24:02 +0800
Subject: [PATCH 1111/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index e0a21725135..32ee3c04333 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -113,7 +113,7 @@ public void UpdateSettings(IReadOnlyDictionary settings)
// If can parse the default value to bool, use it, otherwise use false
: value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString)
&& boolValueFromString;
- checkBox.Dispatcher.Invoke(() =>checkBox.IsChecked = isChecked);
+ checkBox.Dispatcher.Invoke(() => checkBox.IsChecked = isChecked);
break;
}
}
@@ -154,8 +154,7 @@ public bool NeedCreateSettingPanel()
public Control CreateSettingPanel()
{
- // No need to check if NeedCreateSettingPanel is true because CreateSettingPanel will only be called if it's true
- // if (!NeedCreateSettingPanel()) return null;
+ if (!NeedCreateSettingPanel()) return null;
// Create main grid with two columns (Column 1: Auto, Column 2: *)
var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
From 686d106a0c099b94c066ea180b33298cb708b6d9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 20:52:24 +0800
Subject: [PATCH 1112/1335] Add todo
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 1cccc38d938..c7a973b2f03 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -116,6 +116,7 @@ public string SettingWindowFont
OnPropertyChanged();
Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
+ // TODO: Context Menu Font
}
}
}
From 192e2efca1c65a5d0b6c9fa26ab8e8635e48e4c0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 21:40:31 +0800
Subject: [PATCH 1113/1335] Remove property change
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index c7a973b2f03..e623ba400fa 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,7 +113,6 @@ public string SettingWindowFont
if (_settingWindowFont != value)
{
_settingWindowFont = value;
- OnPropertyChanged();
Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
// TODO: Context Menu Font
From 22fb5b1b65f48184364991cbb75ca6f054150e2e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 21:40:40 +0800
Subject: [PATCH 1114/1335] Remove unused binding
---
Flow.Launcher/SettingWindow.xaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index a34777d3020..ab27b235a2c 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -13,7 +13,6 @@
MinHeight="600"
d:DataContext="{d:DesignInstance vm:SettingWindowViewModel}"
Closed="OnClosed"
- FontFamily="{Binding Settings.SettingWindowFont, Mode=TwoWay}"
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
From cbcebad4d0aecbd879c01bdf34f25fcb881d76eb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 21:49:50 +0800
Subject: [PATCH 1115/1335] Improve code quality
---
Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
index 32ee3c04333..003e72a5d86 100644
--- a/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
+++ b/Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
@@ -154,7 +154,7 @@ public bool NeedCreateSettingPanel()
public Control CreateSettingPanel()
{
- if (!NeedCreateSettingPanel()) return null;
+ if (!NeedCreateSettingPanel()) return null!;
// Create main grid with two columns (Column 1: Auto, Column 2: *)
var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
From 84b0393fd0fd4ef457bce71b457568ca9473d238 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 21:51:14 +0800
Subject: [PATCH 1116/1335] Use dependency injection for setting page view
models
---
Flow.Launcher/App.xaml.cs | 12 +++++++++-
.../SettingsPaneGeneralViewModel.cs | 4 ++--
.../Views/SettingsPaneAbout.xaml.cs | 8 ++-----
.../Views/SettingsPaneGeneral.xaml.cs | 10 +--------
.../Views/SettingsPaneHotkey.xaml.cs | 4 +---
.../Views/SettingsPanePluginStore.xaml.cs | 4 +---
.../Views/SettingsPanePlugins.xaml.cs | 4 +---
.../Views/SettingsPaneProxy.xaml.cs | 7 +-----
.../Views/SettingsPaneTheme.xaml.cs | 10 ++-------
.../ViewModel/SettingWindowViewModel.cs | 22 +++++++++----------
Flow.Launcher/ViewModel/WelcomeViewModel.cs | 2 +-
11 files changed, 34 insertions(+), 53 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index ac134fb5fa9..20dd506683d 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -19,6 +19,7 @@
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -74,14 +75,23 @@ public App()
.AddSingleton(_ => _settings)
.AddSingleton(sp => new Updater(sp.GetRequiredService(), Launcher.Properties.Settings.Default.GithubRepo))
.AddSingleton()
- .AddSingleton()
.AddSingleton()
.AddSingleton()
.AddSingleton()
.AddSingleton()
.AddSingleton()
.AddSingleton()
+ // Welcome view model & setting window view model is very simple so we just use one instance
+ .AddSingleton()
.AddSingleton()
+ // Setting page view models are complex so we use transient instance
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
).Build();
Ioc.Default.ConfigureServices(host.Services);
}
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index c8b83c730b6..1a887c4b7f3 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -19,10 +19,10 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
public Settings Settings { get; }
private readonly Updater _updater;
- private readonly IPortable _portable;
+ private readonly Portable _portable;
private readonly Internationalization _translater;
- public SettingsPaneGeneralViewModel(Settings settings, Updater updater, IPortable portable, Internationalization translater)
+ public SettingsPaneGeneralViewModel(Settings settings, Updater updater, Portable portable, Internationalization translater)
{
Settings = settings;
_updater = updater;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index 1ecc02aa6b3..e57cba6d409 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -1,8 +1,6 @@
using System.Windows.Navigation;
-using Flow.Launcher.Core;
-using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.Infrastructure.UserSettings;
using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher.SettingPages.Views;
@@ -14,9 +12,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- var updater = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneAboutViewModel(settings, updater);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index 569d489d2c6..31653962dfd 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -1,9 +1,5 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
-using Flow.Launcher.Core.Configuration;
-using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
namespace Flow.Launcher.SettingPages.Views;
@@ -16,11 +12,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- var updater = Ioc.Default.GetRequiredService();
- var portable = Ioc.Default.GetRequiredService();
- var translater = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable, translater);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index eb100da0ca8..8b757bd60a5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -1,7 +1,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -13,8 +12,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneHotkeyViewModel(settings);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index 3bd24bc1323..131dfab6d29 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -5,7 +5,6 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
-using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -17,8 +16,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPanePluginStoreViewModel();
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index f6b4351864e..97574b3ce48 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -2,7 +2,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -14,8 +13,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPanePluginsViewModel(settings);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
index 26350b8bbd5..258f2a4adbf 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
@@ -1,8 +1,6 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
-using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@@ -14,13 +12,10 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- var updater = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneProxyViewModel(settings, updater);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
-
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index a1a0231a526..cee8e4ae468 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -1,13 +1,10 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
-using Page = ModernWpf.Controls.Page;
namespace Flow.Launcher.SettingPages.Views;
-public partial class SettingsPaneTheme : Page
+public partial class SettingsPaneTheme
{
private SettingsPaneThemeViewModel _viewModel = null!;
@@ -15,13 +12,10 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!IsInitialized)
{
- var settings = Ioc.Default.GetRequiredService();
- var theme = Ioc.Default.GetRequiredService();
- _viewModel = new SettingsPaneThemeViewModel(settings, theme);
+ _viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
-
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index f05893cf476..0fe4557a702 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -5,11 +5,11 @@ namespace Flow.Launcher.ViewModel;
public partial class SettingWindowViewModel : BaseModel
{
- public Settings Settings { get; }
+ private readonly Settings _settings;
public SettingWindowViewModel(Settings settings)
{
- Settings = settings;
+ _settings = settings;
}
///
@@ -17,30 +17,30 @@ public SettingWindowViewModel(Settings settings)
///
public void Save()
{
- Settings.Save();
+ _settings.Save();
}
public double SettingWindowWidth
{
- get => Settings.SettingWindowWidth;
- set => Settings.SettingWindowWidth = value;
+ get => _settings.SettingWindowWidth;
+ set => _settings.SettingWindowWidth = value;
}
public double SettingWindowHeight
{
- get => Settings.SettingWindowHeight;
- set => Settings.SettingWindowHeight = value;
+ get => _settings.SettingWindowHeight;
+ set => _settings.SettingWindowHeight = value;
}
public double? SettingWindowTop
{
- get => Settings.SettingWindowTop;
- set => Settings.SettingWindowTop = value;
+ get => _settings.SettingWindowTop;
+ set => _settings.SettingWindowTop = value;
}
public double? SettingWindowLeft
{
- get => Settings.SettingWindowLeft;
- set => Settings.SettingWindowLeft = value;
+ get => _settings.SettingWindowLeft;
+ set => _settings.SettingWindowLeft = value;
}
}
diff --git a/Flow.Launcher/ViewModel/WelcomeViewModel.cs b/Flow.Launcher/ViewModel/WelcomeViewModel.cs
index 5eecabfde85..82d19273f0b 100644
--- a/Flow.Launcher/ViewModel/WelcomeViewModel.cs
+++ b/Flow.Launcher/ViewModel/WelcomeViewModel.cs
@@ -18,6 +18,7 @@ public int PageNum
{
_pageNum = value;
OnPropertyChanged();
+ OnPropertyChanged(nameof(PageDisplay));
UpdateView();
}
}
@@ -47,7 +48,6 @@ public bool NextEnabled
private void UpdateView()
{
- OnPropertyChanged(nameof(PageDisplay));
if (PageNum == 1)
{
BackEnabled = false;
From 79452921282887aac22de6d5891067aaae382e48 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 22:01:38 +0800
Subject: [PATCH 1117/1335] Update context menu font when setting is changed
---
.../UserSettings/Settings.cs | 1 -
Flow.Launcher/MainWindow.xaml.cs | 76 +++++++++++--------
2 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index e623ba400fa..cf194b3663e 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -115,7 +115,6 @@ public string SettingWindowFont
_settingWindowFont = value;
Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
- // TODO: Context Menu Font
}
}
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index bf7a45b1d25..ae05d11243b 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -140,7 +140,8 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
_viewModel.Show();
}
- // Show notify icon when flowlauncher is hidden
+ // Initialize context menu & notify icon
+ InitializeContextMenu();
InitializeNotifyIcon();
// Initialize color scheme
@@ -270,6 +271,9 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
+ case nameof(Settings.SettingWindowFont):
+ InitializeContextMenu();
+ break;
}
};
@@ -563,6 +567,44 @@ private void InitializeNotifyIcon()
Icon = Constant.Version == "1.0.0" ? Properties.Resources.dev : Properties.Resources.app,
Visible = !_settings.HideNotifyIcon
};
+
+ _notifyIcon.MouseClick += (o, e) =>
+ {
+ switch (e.Button)
+ {
+ case MouseButtons.Left:
+ _viewModel.ToggleFlowLauncher();
+ break;
+ case MouseButtons.Right:
+
+ _contextMenu.IsOpen = true;
+ // Get context menu handle and bring it to the foreground
+ if (PresentationSource.FromVisual(_contextMenu) is HwndSource hwndSource)
+ {
+ Win32Helper.SetForegroundWindow(hwndSource.Handle);
+ }
+
+ _contextMenu.Focus();
+ break;
+ }
+ };
+ }
+
+ private void UpdateNotifyIconText()
+ {
+ var menu = _contextMenu;
+ ((MenuItem)menu.Items[0]).Header = App.API.GetTranslation("iconTrayOpen") +
+ " (" + _settings.Hotkey + ")";
+ ((MenuItem)menu.Items[1]).Header = App.API.GetTranslation("GameMode");
+ ((MenuItem)menu.Items[2]).Header = App.API.GetTranslation("PositionReset");
+ ((MenuItem)menu.Items[3]).Header = App.API.GetTranslation("iconTraySettings");
+ ((MenuItem)menu.Items[4]).Header = App.API.GetTranslation("iconTrayExit");
+ }
+
+ private void InitializeContextMenu()
+ {
+ var menu = _contextMenu;
+ menu.Items.Clear();
var openIcon = new FontIcon { Glyph = "\ue71e" };
var open = new MenuItem
{
@@ -608,38 +650,6 @@ private void InitializeNotifyIcon()
_contextMenu.Items.Add(positionreset);
_contextMenu.Items.Add(settings);
_contextMenu.Items.Add(exit);
-
- _notifyIcon.MouseClick += (o, e) =>
- {
- switch (e.Button)
- {
- case MouseButtons.Left:
- _viewModel.ToggleFlowLauncher();
- break;
- case MouseButtons.Right:
-
- _contextMenu.IsOpen = true;
- // Get context menu handle and bring it to the foreground
- if (PresentationSource.FromVisual(_contextMenu) is HwndSource hwndSource)
- {
- Win32Helper.SetForegroundWindow(hwndSource.Handle);
- }
-
- _contextMenu.Focus();
- break;
- }
- };
- }
-
- private void UpdateNotifyIconText()
- {
- var menu = _contextMenu;
- ((MenuItem)menu.Items[0]).Header = App.API.GetTranslation("iconTrayOpen") +
- " (" + _settings.Hotkey + ")";
- ((MenuItem)menu.Items[1]).Header = App.API.GetTranslation("GameMode");
- ((MenuItem)menu.Items[2]).Header = App.API.GetTranslation("PositionReset");
- ((MenuItem)menu.Items[3]).Header = App.API.GetTranslation("iconTraySettings");
- ((MenuItem)menu.Items[4]).Header = App.API.GetTranslation("iconTrayExit");
}
#endregion
From 5665758ee6dd3c70d0e35f4923e698053643316b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 24 Apr 2025 22:04:48 +0800
Subject: [PATCH 1118/1335] Add property change back
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index cf194b3663e..1cccc38d938 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -113,6 +113,7 @@ public string SettingWindowFont
if (_settingWindowFont != value)
{
_settingWindowFont = value;
+ OnPropertyChanged();
Application.Current.Resources["SettingWindowFont"] = new FontFamily(value);
Application.Current.Resources["ContentControlThemeFontFamily"] = new FontFamily(value);
}
From 197e9c45ce91738edea1e2170de4fbe4a21856f9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 25 Apr 2025 08:19:03 +0800
Subject: [PATCH 1119/1335] Improve code comments
---
Flow.Launcher/App.xaml.cs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 20dd506683d..b1ff136b38a 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -79,12 +79,16 @@ public App()
.AddSingleton()
.AddSingleton()
.AddSingleton()
- .AddSingleton()
.AddSingleton()
- // Welcome view model & setting window view model is very simple so we just use one instance
- .AddSingleton()
+ // Use one instance for main window view model because we only have one main window
+ .AddSingleton()
+ // Use one instance for welcome window view model & setting window view model because
+ // pages in welcome window & setting window need to share the same instance and
+ // these two view models do not need to be reset when creating new windows
.AddSingleton()
- // Setting page view models are complex so we use transient instance
+ .AddSingleton()
+ // Use transient instance for setting window page view models because
+ // pages in setting window need to be recreated when setting window is closed
.AddTransient()
.AddTransient()
.AddTransient()
From e3573f32d52b3e1e007516d4c818da5851a1cae0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 25 Apr 2025 08:42:41 +0800
Subject: [PATCH 1120/1335] Improve code quality
---
Flow.Launcher/SettingWindow.xaml.cs | 39 ++++++++++++++-----
.../ViewModel/SettingWindowViewModel.cs | 8 ----
Flow.Launcher/WelcomeWindow.xaml.cs | 10 +++--
3 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index b4a3ae47a92..cd3e5414f6f 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -1,6 +1,6 @@
using System;
using System.Windows;
-using System.Windows.Forms;
+using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using CommunityToolkit.Mvvm.DependencyInjection;
@@ -9,35 +9,45 @@
using Flow.Launcher.SettingPages.Views;
using Flow.Launcher.ViewModel;
using ModernWpf.Controls;
-using TextBox = System.Windows.Controls.TextBox;
+using Screen = System.Windows.Forms.Screen;
namespace Flow.Launcher;
public partial class SettingWindow
{
+ #region Private Fields
+
private readonly Settings _settings;
- private readonly SettingWindowViewModel _viewModel;
+
+ #endregion
+
+ #region Constructor
public SettingWindow()
{
- var viewModel = Ioc.Default.GetRequiredService();
_settings = Ioc.Default.GetRequiredService();
+ var viewModel = Ioc.Default.GetRequiredService();
DataContext = viewModel;
- _viewModel = viewModel;
- InitializePosition();
InitializeComponent();
+
+ UpdatePositionAndState();
}
+ #endregion
+
+ #region Window Events
+
private void OnLoaded(object sender, RoutedEventArgs e)
{
RefreshMaximizeRestoreButton();
+
// Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
- InitializePosition();
+ UpdatePositionAndState();
}
private void OnClosed(object sender, EventArgs e)
@@ -45,7 +55,7 @@ private void OnClosed(object sender, EventArgs e)
_settings.SettingWindowState = WindowState;
_settings.SettingWindowTop = Top;
_settings.SettingWindowLeft = Left;
- _viewModel.Save();
+ _settings.Save();
App.API.SavePluginSettings();
}
@@ -104,7 +114,11 @@ private void Window_StateChanged(object sender, EventArgs e)
RefreshMaximizeRestoreButton();
}
- public void InitializePosition()
+ #endregion
+
+ #region Window Position
+
+ public void UpdatePositionAndState()
{
var previousTop = _settings.SettingWindowTop;
var previousLeft = _settings.SettingWindowLeft;
@@ -119,6 +133,7 @@ public void InitializePosition()
Top = previousTop.Value;
Left = previousLeft.Value;
}
+
WindowState = _settings.SettingWindowState;
}
@@ -155,6 +170,10 @@ private double WindowTop()
return top;
}
+ #endregion
+
+ #region Navigation View Events
+
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.IsSettingsSelected)
@@ -201,4 +220,6 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
+
+ #endregion
}
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 0fe4557a702..17a1a2b50f1 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -12,14 +12,6 @@ public SettingWindowViewModel(Settings settings)
_settings = settings;
}
- ///
- /// Save Flow settings. Plugins settings are not included.
- ///
- public void Save()
- {
- _settings.Save();
- }
-
public double SettingWindowWidth
{
get => _settings.SettingWindowWidth;
diff --git a/Flow.Launcher/WelcomeWindow.xaml.cs b/Flow.Launcher/WelcomeWindow.xaml.cs
index 637f9448d9a..d23bd493703 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -2,16 +2,17 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
-using Flow.Launcher.Resources.Pages;
-using ModernWpf.Media.Animation;
using CommunityToolkit.Mvvm.DependencyInjection;
-using Flow.Launcher.ViewModel;
using Flow.Launcher.Infrastructure.UserSettings;
+using Flow.Launcher.Resources.Pages;
+using Flow.Launcher.ViewModel;
+using ModernWpf.Media.Animation;
namespace Flow.Launcher
{
public partial class WelcomeWindow : Window
{
+ private readonly Settings _settings;
private readonly WelcomeViewModel _viewModel;
private readonly NavigationTransitionInfo _forwardTransitionInfo = new SlideNavigationTransitionInfo()
@@ -25,6 +26,7 @@ public partial class WelcomeWindow : Window
public WelcomeWindow()
{
+ _settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
@@ -97,7 +99,7 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
private void Window_Closed(object sender, EventArgs e)
{
// Save settings when window is closed
- Ioc.Default.GetRequiredService().Save();
+ _settings.Save();
}
}
}
From 856346acebe94adadd178616e157607d497c4e8e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 25 Apr 2025 09:03:04 +0800
Subject: [PATCH 1121/1335] Always update main window position when window is
loaded
---
Flow.Launcher/MainWindow.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index ae05d11243b..381d03c1f2f 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -324,7 +324,7 @@ private void OnClosed(object sender, EventArgs e)
private void OnLocationChanged(object sender, EventArgs e)
{
- if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
+ if (IsLoaded)
{
_settings.WindowLeft = Left;
_settings.WindowTop = Top;
From defb2830d632fbebc05f570d149fb078f4a9e2a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 25 Apr 2025 09:04:14 +0800
Subject: [PATCH 1122/1335] Change setting window position & window state
faster & Do not save settings for faster exiting experience
---
Flow.Launcher/App.xaml.cs | 3 ++-
Flow.Launcher/SettingWindow.xaml | 1 +
Flow.Launcher/SettingWindow.xaml.cs | 38 +++++++++++++++++++----------
Flow.Launcher/WelcomeWindow.xaml.cs | 7 +++---
4 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index b1ff136b38a..1b57d5cbe5c 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -31,6 +31,7 @@ public partial class App : IDisposable, ISingleInstanceApp
#region Public Properties
public static IPublicAPI API { get; private set; }
+ public static bool Exiting => _mainWindow.CanClose;
#endregion
@@ -39,7 +40,7 @@ public partial class App : IDisposable, ISingleInstanceApp
private static readonly string ClassName = nameof(App);
private static bool _disposed;
- private MainWindow _mainWindow;
+ private static MainWindow _mainWindow;
private readonly MainViewModel _mainVM;
private readonly Settings _settings;
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index ab27b235a2c..a75a51c8fbb 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -16,6 +16,7 @@
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
+ LocationChanged="Window_LocationChanged"
MouseDown="window_MouseDown"
ResizeMode="CanResize"
SnapsToDevicePixels="True"
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cd3e5414f6f..79bd171edfe 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -52,9 +52,9 @@ private void OnLoaded(object sender, RoutedEventArgs e)
private void OnClosed(object sender, EventArgs e)
{
- _settings.SettingWindowState = WindowState;
- _settings.SettingWindowTop = Top;
- _settings.SettingWindowLeft = Left;
+ // If app is exiting, settings save is not needed because main window closing event will handle this
+ if (App.Exiting) return;
+ // Save settings when window is closed
_settings.Save();
App.API.SavePluginSettings();
}
@@ -66,15 +66,32 @@ private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e)
private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
{
- if (Keyboard.FocusedElement is not TextBox textBox)
- {
- return;
- }
+ if (Keyboard.FocusedElement is not TextBox textBox) return;
var tRequest = new TraversalRequest(FocusNavigationDirection.Next);
textBox.MoveFocus(tRequest);
}
- /* Custom TitleBar */
+ private void Window_StateChanged(object sender, EventArgs e)
+ {
+ RefreshMaximizeRestoreButton();
+ if (IsLoaded)
+ {
+ _settings.SettingWindowState = WindowState;
+ }
+ }
+
+ private void Window_LocationChanged(object sender, EventArgs e)
+ {
+ if (IsLoaded)
+ {
+ _settings.SettingWindowTop = Top;
+ _settings.SettingWindowLeft = Left;
+ }
+ }
+
+ #endregion
+
+ #region Window Custom TitleBar
private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
{
@@ -109,11 +126,6 @@ private void RefreshMaximizeRestoreButton()
}
}
- private void Window_StateChanged(object sender, EventArgs e)
- {
- RefreshMaximizeRestoreButton();
- }
-
#endregion
#region Window Position
diff --git a/Flow.Launcher/WelcomeWindow.xaml.cs b/Flow.Launcher/WelcomeWindow.xaml.cs
index d23bd493703..ef07067650c 100644
--- a/Flow.Launcher/WelcomeWindow.xaml.cs
+++ b/Flow.Launcher/WelcomeWindow.xaml.cs
@@ -78,10 +78,7 @@ private static Type PageTypeSelector(int pageNumber)
private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
{
- if (Keyboard.FocusedElement is not TextBox textBox)
- {
- return;
- }
+ if (Keyboard.FocusedElement is not TextBox textBox) return;
var tRequest = new TraversalRequest(FocusNavigationDirection.Next);
textBox.MoveFocus(tRequest);
}
@@ -98,6 +95,8 @@ private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
private void Window_Closed(object sender, EventArgs e)
{
+ // If app is exiting, settings save is not needed because main window closing event will handle this
+ if (App.Exiting) return;
// Save settings when window is closed
_settings.Save();
}
From f0512d7861f0e9698b093bb69296c21f1f652d54 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 25 Apr 2025 09:13:51 +0800
Subject: [PATCH 1123/1335] Add blank line
---
Flow.Launcher/Resources/SettingWindowStyle.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml
index 60655fa7c32..fc9246aa33d 100644
--- a/Flow.Launcher/Resources/SettingWindowStyle.xaml
+++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml
@@ -7,6 +7,7 @@
+
F1 M512,512z M0,0z M448,256C448,150,362,64,256,64L256,448C362,448,448,362,448,256z M0,256A256,256,0,1,1,512,256A256,256,0,1,1,0,256z
-
-
-
+ Orientation="Horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
Date: Tue, 29 Apr 2025 10:46:16 +0800
Subject: [PATCH 1131/1335] Remove unused image
---
Flow.Launcher/Images/EXE.png | Bin 2173 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 Flow.Launcher/Images/EXE.png
diff --git a/Flow.Launcher/Images/EXE.png b/Flow.Launcher/Images/EXE.png
deleted file mode 100644
index ecc91bdb3ab7b81b7a01f5a46cc127a883e6a6ed..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2173
zcmbVOc~BEq99|F)u$FkWlv-Eqc0&R>mf~Q=
zO6%yL1xE*vPN`aHwH_6Z`bVLTil|f++o@9=!D0)wYQ4a|g^*E;$GEebeQ)3QzTffv
z-fvQpmYOssBs>IypfUPnT{?K9{4;6<_{|Kw`!RS0JComK!FntI1jJ9-?1iA=^|UdI
z%QB?kBx4s7CMJgxd+knuhM-xoUME53QXHH^S!jnw*j;~A2-7BwFjH
zR7OFnku1n1)h1!=Y|Or;|;=DhBR2q
zxF}dD#zZ8FqOejeCR9o(mZP2lOHc`hplWc7P!yLcaj6RST|!{aWisRGx2}%rjhje>vQc)*!La~~`LRwb!!fLt
zc?z|E`7r|^w+4gX#*n_)?S2z1myid-@FiqOG;7RvQb;<*GHw@1CFB7&qxoo@xYk7x
z9OE)FjBQYEJrvH(iWDS)iPUnLLPRL!5|LV|$|2P<(yWx4
z2lwk3(#PT
zdH4gzmjs?nvp}qT--*bemik6E8t$(GoFMt?)(A;nR>~yweWr)Vz>7sNK;EsmmvP;fR?#Bk;hV~U
zD9Dp~^{+kBfCk~9tMNmBKLrziN2VNr+6DS;@hPhWf>U7XSS(Vv?P^Tx-8HGX*7
zR-aW>Sqe{Be87uFMZ{DFSA^AVUAy>LPq_?hV3r)Z6O2Zz9&vNd>Y{`iq-bJWQNTfI
zM4PdqHs!)zZF?WGdCLRo>3=Te=b0n0hUQc0yT*^&5%$C0gAp)67NlL-ip^4>;fl-m
zPW+t7hBi7bdhLp^9TS^ZCC!fs{bs|ClzFp{pGw4Dzp$yfxHfRj*gRL+wXeSXzIFb|
zjw_LZ=$3`kl-mkBRfTY=MJL!Y5C`@Lb$f-bhY
z9qRb&)yUxay$3Y*(NT)VTfKp)6{|X;4cm{_b|EZQnCsRQE{N@!Tz(@orK)YVs%7Nj
z+;#e@#Is9YDOfuG-tw4VS02x7yT0BKZOLeCifRe@yfnLL|8VZenx@v~yWuUvPF@uk
z+?GxX>MZLHVs5OitNi6=UFM<{dsx9c#m?!?6<3Q(W=WzPq>XkBgbGKCL#lL;K^W
zSEbiSR@U@>H?z!^DCjwy_b?7>%er+aY3ewLkz9H|{(iu*_sGIS@?zhj~*!+bdW%sp6eRO$ycYGC8^IKB(
z?3EYWX3EYFTjoAgGQ)+Jc-(@0|Dwg=>-F*nW!gT$aqaSQwhqXd1GTORcyIa$=ht9j
z3pn!N+>8}<@;5iURfuXWQRjoqwzUiQpV_eU;nhghw*c8SxvTSb({^ik4gUv0pOC8C
I6~CnDKgG8Q3jhEB
From 7e50eb542676f711c6e5ed272ff0bb4fac6bf4bc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 29 Apr 2025 10:47:13 +0800
Subject: [PATCH 1132/1335] Code quality
---
Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
index 7867fa98016..66c1cb1bfc0 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
@@ -377,9 +377,7 @@
Text="{Binding Description, Mode=OneWay}"
TextTrimming="WordEllipsis"
TextWrapping="Wrap" />
-
-
From 9b666d31363796bef10e8f031fe99b7d7e13ee73 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 29 Apr 2025 20:06:46 +0900
Subject: [PATCH 1133/1335] Add Flyout UI for Filter
---
.../Views/SettingsPanePluginStore.xaml | 55 +++++++++----------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
index 66c1cb1bfc0..fde022da79c 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
@@ -65,34 +65,33 @@
Command="{Binding RefreshExternalPluginsCommand}"
Content="{DynamicResource refresh}"
FontSize="13" />
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
Date: Tue, 29 Apr 2025 19:31:37 +0800
Subject: [PATCH 1134/1335] Adjust margin & Improve ui
---
.../SettingPages/Views/SettingsPanePluginStore.xaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
index fde022da79c..df9cc355621 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
@@ -58,14 +58,14 @@
Orientation="Horizontal">
-
+
@@ -80,7 +80,7 @@
IsChecked="{Binding ShowPython, Mode=TwoWay}"
StaysOpenOnClick="True" />
From d0b44854ca282999fdba8f72be7c9306acfa00e2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 29 Apr 2025 19:33:56 +0800
Subject: [PATCH 1135/1335] Set menu flyout to bottom
---
Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
index df9cc355621..9312b0c2dfd 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
@@ -68,7 +68,7 @@
-
+
Date: Wed, 30 Apr 2025 10:45:09 +0800
Subject: [PATCH 1136/1335] Change function name to suppress warning
---
Flow.Launcher/ActionKeywords.xaml.cs | 2 +-
Flow.Launcher/ViewModel/PluginViewModel.cs | 7 +------
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/ActionKeywords.xaml.cs b/Flow.Launcher/ActionKeywords.xaml.cs
index ad24f2a761f..9420b4c380e 100644
--- a/Flow.Launcher/ActionKeywords.xaml.cs
+++ b/Flow.Launcher/ActionKeywords.xaml.cs
@@ -80,7 +80,7 @@ private void ReplaceActionKeyword(string id, IReadOnlyList removedAction
}
// Update action keywords text and close window
- _pluginViewModel.OnActionKeywordsChanged();
+ _pluginViewModel.OnActionKeywordsTextChanged();
Close();
}
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 8312806fb58..64a7f3db84e 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -155,16 +155,11 @@ public Control SettingControl
public bool SearchDelayEnabled => Settings.SearchQueryResultsWithDelay;
public string DefaultSearchDelay => Settings.SearchDelayTime.ToString();
- public void OnActionKeywordsChanged()
+ public void OnActionKeywordsTextChanged()
{
OnPropertyChanged(nameof(ActionKeywordsText));
}
- public void OnSearchDelayTimeChanged()
- {
- OnPropertyChanged(nameof(SearchDelayTimeText));
- }
-
[RelayCommand]
private void OpenPluginDirectory()
{
From 6b9a710145c5e4022e3b977ad31b3533dbef4148 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 30 Apr 2025 10:45:18 +0800
Subject: [PATCH 1137/1335] Set private assets all for PropertyChanged.Fody
---
.../Flow.Launcher.Infrastructure.csproj | 4 +++-
Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 4 +++-
Flow.Launcher/Flow.Launcher.csproj | 4 +++-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
index f02b2297f64..31547200b23 100644
--- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
+++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj
@@ -66,7 +66,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+ all
+
diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
index 1472813b8a5..ce3b7ab1a90 100644
--- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
+++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj
@@ -76,7 +76,9 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+ all
+
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index 91cab9fa0ad..8d43eff9870 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -98,7 +98,9 @@
-
+
+ all
+
From a9641505b63a19248d68a6c1b118fece029fe582 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 30 Apr 2025 19:21:59 +0800
Subject: [PATCH 1138/1335] Fix clean cache issue
---
.../ViewModels/SettingsPaneAboutViewModel.cs | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 231d14d5551..3889b9b00c8 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -186,6 +186,7 @@ private bool ClearLogFolder()
{
try
{
+ // Make sure directory clean
dir.Delete(true);
}
catch (Exception e)
@@ -214,6 +215,7 @@ private bool ClearCacheFolder()
{
var success = true;
var cacheDirectory = GetCacheDir();
+ var pluginCacheDirectory = GetPluginCacheDir();
var cacheFiles = GetCacheFiles();
cacheFiles.ForEach(f =>
@@ -229,12 +231,31 @@ private bool ClearCacheFolder()
}
});
+ // Firstly, delete plugin cache directories
+ pluginCacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
+ .ToList()
+ .ForEach(dir =>
+ {
+ try
+ {
+ // Plugin may create directories in its cache directory
+ dir.Delete(true);
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
+ success = false;
+ }
+ });
+
+ // Then, delete plugin directory
cacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
.ToList()
.ForEach(dir =>
{
try
{
+ // Make sure directory clean
dir.Delete(true);
}
catch (Exception e)
@@ -254,6 +275,11 @@ private static DirectoryInfo GetCacheDir()
return new DirectoryInfo(DataLocation.CacheDirectory);
}
+ private static DirectoryInfo GetPluginCacheDir()
+ {
+ return new DirectoryInfo(DataLocation.PluginCacheDirectory);
+ }
+
private static List GetCacheFiles()
{
return GetCacheDir().EnumerateFiles("*", SearchOption.AllDirectories).ToList();
From c9e85a1888f0936342ea74121c7e070ff7322777 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 30 Apr 2025 19:35:35 +0800
Subject: [PATCH 1139/1335] Use recursive false
---
.../ViewModels/SettingsPaneAboutViewModel.cs | 29 ++++++++-----------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 3889b9b00c8..652fc1ce5a2 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -186,8 +186,8 @@ private bool ClearLogFolder()
{
try
{
- // Make sure directory clean
- dir.Delete(true);
+ // Log folders are the last level of folders
+ dir.Delete(false);
}
catch (Exception e)
{
@@ -249,21 +249,16 @@ private bool ClearCacheFolder()
});
// Then, delete plugin directory
- cacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
- .ToList()
- .ForEach(dir =>
- {
- try
- {
- // Make sure directory clean
- dir.Delete(true);
- }
- catch (Exception e)
- {
- App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
- success = false;
- }
- });
+ try
+ {
+ // Log folders are the last level of folders
+ GetPluginCacheDir().Delete(false);
+ }
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
+ success = false;
+ }
OnPropertyChanged(nameof(CacheFolderSize));
From 7762c7929e5837d0c3606c4cb2f0e53e5105991f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 30 Apr 2025 19:38:15 +0800
Subject: [PATCH 1140/1335] Explictly add recursive & Fix build
---
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 652fc1ce5a2..374dcb3ad52 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -187,7 +187,7 @@ private bool ClearLogFolder()
try
{
// Log folders are the last level of folders
- dir.Delete(false);
+ dir.Delete(recursive: false);
}
catch (Exception e)
{
@@ -239,7 +239,7 @@ private bool ClearCacheFolder()
try
{
// Plugin may create directories in its cache directory
- dir.Delete(true);
+ dir.Delete(recursive: true);
}
catch (Exception e)
{
@@ -249,10 +249,11 @@ private bool ClearCacheFolder()
});
// Then, delete plugin directory
+ var dir = GetPluginCacheDir();
try
{
// Log folders are the last level of folders
- GetPluginCacheDir().Delete(false);
+ dir.Delete(recursive: false);
}
catch (Exception e)
{
From 541e1981a93a727ad81b55c2a26954f2f6c0f847 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 30 Apr 2025 19:40:23 +0800
Subject: [PATCH 1141/1335] Fix code comments
---
.../SettingPages/ViewModels/SettingsPaneAboutViewModel.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
index 374dcb3ad52..00f40b00957 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
@@ -252,7 +252,6 @@ private bool ClearCacheFolder()
var dir = GetPluginCacheDir();
try
{
- // Log folders are the last level of folders
dir.Delete(recursive: false);
}
catch (Exception e)
From 980b792cb360515f4d4b17c49a955a156a50bc15 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 11:06:52 +0800
Subject: [PATCH 1142/1335] Wrap operation in one class
---
Flow.Launcher/Storage/TopMostRecord.cs | 34 ++++++++++++++++++++++++
Flow.Launcher/ViewModel/MainViewModel.cs | 8 +++---
2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 7f35904a520..63f0a2fcebd 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -1,10 +1,44 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.Json.Serialization;
+using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Storage
{
+ public class FlowLauncherJsonStorageTopMostRecord : ISavable
+ {
+ private readonly FlowLauncherJsonStorage _topMostRecordStorage;
+
+ private readonly TopMostRecord _topMostRecord;
+
+ public FlowLauncherJsonStorageTopMostRecord()
+ {
+ _topMostRecordStorage = new FlowLauncherJsonStorage();
+ _topMostRecord = _topMostRecordStorage.Load();
+ }
+
+ public void Save()
+ {
+ _topMostRecordStorage.Save();
+ }
+
+ public bool IsTopMost(Result result)
+ {
+ return _topMostRecord.IsTopMost(result);
+ }
+
+ public void Remove(Result result)
+ {
+ _topMostRecord.Remove(result);
+ }
+
+ public void AddOrUpdate(Result result)
+ {
+ _topMostRecord.AddOrUpdate(result);
+ }
+ }
+
public class TopMostRecord
{
[JsonInclude]
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 00675149b41..54ad6c288cd 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -37,11 +37,10 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly FlowLauncherJsonStorage _historyItemsStorage;
private readonly FlowLauncherJsonStorage _userSelectedRecordStorage;
- private readonly FlowLauncherJsonStorage _topMostRecordStorage;
+ private readonly FlowLauncherJsonStorageTopMostRecord _topMostRecord;
private readonly History _history;
private int lastHistoryIndex = 1;
private readonly UserSelectedRecord _userSelectedRecord;
- private readonly TopMostRecord _topMostRecord;
private CancellationTokenSource _updateSource;
private CancellationToken _updateToken;
@@ -134,10 +133,9 @@ public MainViewModel()
_historyItemsStorage = new FlowLauncherJsonStorage();
_userSelectedRecordStorage = new FlowLauncherJsonStorage();
- _topMostRecordStorage = new FlowLauncherJsonStorage();
+ _topMostRecord = new FlowLauncherJsonStorageTopMostRecord();
_history = _historyItemsStorage.Load();
_userSelectedRecord = _userSelectedRecordStorage.Load();
- _topMostRecord = _topMostRecordStorage.Load();
ContextMenu = new ResultsViewModel(Settings)
{
@@ -1612,7 +1610,7 @@ public void Save()
{
_historyItemsStorage.Save();
_userSelectedRecordStorage.Save();
- _topMostRecordStorage.Save();
+ _topMostRecord.Save();
}
///
From 0d619085753cb8e443044c6cd016b86b5fc5b1d3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 11:41:53 +0800
Subject: [PATCH 1143/1335] Support multiple topmost records
---
.../Storage/JsonStorage.cs | 5 +
Flow.Launcher/Storage/TopMostRecord.cs | 137 ++++++++++++++++--
2 files changed, 132 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 0b10382ee9b..20aacb3447e 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -45,6 +45,11 @@ public JsonStorage(string filePath)
FilesFolders.ValidateDirectory(DirectoryPath);
}
+ public bool Exists()
+ {
+ return File.Exists(FilePath);
+ }
+
public async Task LoadAsync()
{
if (Data != null)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 63f0a2fcebd..25774a2c0e4 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Linq;
using System.Text.Json.Serialization;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
@@ -8,14 +9,29 @@ namespace Flow.Launcher.Storage
{
public class FlowLauncherJsonStorageTopMostRecord : ISavable
{
- private readonly FlowLauncherJsonStorage _topMostRecordStorage;
-
- private readonly TopMostRecord _topMostRecord;
+ private readonly FlowLauncherJsonStorage _topMostRecordStorage;
+ private readonly MultipleTopMostRecord _topMostRecord;
public FlowLauncherJsonStorageTopMostRecord()
{
- _topMostRecordStorage = new FlowLauncherJsonStorage();
- _topMostRecord = _topMostRecordStorage.Load();
+ var topMostRecordStorage = new FlowLauncherJsonStorage();
+ var exist = topMostRecordStorage.Exists();
+ if (exist)
+ {
+ // Get old data
+ var topMostRecord = topMostRecordStorage.Load();
+
+ // Convert to new data
+ _topMostRecordStorage = new FlowLauncherJsonStorage();
+ _topMostRecord = _topMostRecordStorage.Load();
+ _topMostRecord.Add(topMostRecord);
+ }
+ else
+ {
+ // Get new data
+ _topMostRecordStorage = new FlowLauncherJsonStorage();
+ _topMostRecord = _topMostRecordStorage.Load();
+ }
}
public void Save()
@@ -42,7 +58,7 @@ public void AddOrUpdate(Result result)
public class TopMostRecord
{
[JsonInclude]
- public ConcurrentDictionary records { get; private set; } = new ConcurrentDictionary();
+ public ConcurrentDictionary records { get; private set; } = new();
internal bool IsTopMost(Result result)
{
@@ -90,12 +106,113 @@ internal void AddOrUpdate(Result result)
}
}
+ public class MultipleTopMostRecord
+ {
+ [JsonInclude]
+ public ConcurrentDictionary> records { get; private set; } = new();
+
+ internal void Add(TopMostRecord topMostRecord)
+ {
+ if (topMostRecord == null || topMostRecord.records.IsEmpty)
+ {
+ return;
+ }
+
+ foreach (var record in topMostRecord.records)
+ {
+ records.AddOrUpdate(record.Key, new ConcurrentBag { record.Value }, (key, oldValue) =>
+ {
+ oldValue.Add(record.Value);
+ return oldValue;
+ });
+ }
+ }
+
+ internal bool IsTopMost(Result result)
+ {
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to check if the result is top most
+ if (records.IsEmpty || result.OriginQuery == null ||
+ !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
+ {
+ return false;
+ }
+
+ // since this dictionary should be very small (or empty) going over it should be pretty fast.
+ return value.Any(record => record.Equals(result));
+ }
+
+ internal void Remove(Result result)
+ {
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to remove the record
+ if (result.OriginQuery == null ||
+ !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
+ {
+ return;
+ }
+
+ // remove the record from the bag
+ var recordToRemove = value.FirstOrDefault(r => r.Equals(result));
+ if (recordToRemove != null)
+ {
+ value.TryTake(out recordToRemove);
+ }
+ }
+
+ internal void AddOrUpdate(Result result)
+ {
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to add or update the record
+ if (result.OriginQuery == null)
+ {
+ return;
+ }
+
+ var record = new Record
+ {
+ PluginID = result.PluginID,
+ Title = result.Title,
+ SubTitle = result.SubTitle,
+ RecordKey = result.RecordKey
+ };
+ if (!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
+ {
+ // create a new bag if it does not exist
+ value = new ConcurrentBag()
+ {
+ record
+ };
+ records.TryAdd(result.OriginQuery.RawQuery, value);
+ }
+ else
+ {
+ // add or update the record in the bag
+ if (value.Any(r => r.Equals(result)))
+ {
+ // update the record
+ var recordToUpdate = value.FirstOrDefault(r => r.Equals(result));
+ if (recordToUpdate != null)
+ {
+ value.TryTake(out recordToUpdate);
+ value.Add(record);
+ }
+ }
+ else
+ {
+ // add the record
+ value.Add(record);
+ }
+ }
+ }
+ }
+
public class Record
{
- public string Title { get; set; }
- public string SubTitle { get; set; }
- public string PluginID { get; set; }
- public string RecordKey { get; set; }
+ public string Title { get; init; }
+ public string SubTitle { get; init; }
+ public string PluginID { get; init; }
+ public string RecordKey { get; init; }
public bool Equals(Result r)
{
From af087fb85b50096b69fc8965436b109eecdc3950 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 12:49:20 +0800
Subject: [PATCH 1144/1335] Support multiple topmost records storage
---
.../Storage/JsonStorage.cs | 16 ++++
Flow.Launcher/Storage/TopMostRecord.cs | 78 ++++++++++++++++---
2 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index 20aacb3447e..db9ccc28a7e 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -50,6 +50,22 @@ public bool Exists()
return File.Exists(FilePath);
}
+ public void Delete()
+ {
+ if (File.Exists(FilePath))
+ {
+ File.Delete(FilePath);
+ }
+ if (File.Exists(BackupFilePath))
+ {
+ File.Delete(BackupFilePath);
+ }
+ if (File.Exists(TempFilePath))
+ {
+ File.Delete(TempFilePath);
+ }
+ }
+
public async Task LoadAsync()
{
if (Data != null)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 25774a2c0e4..f7459dc402b 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -1,35 +1,64 @@
-using System.Collections.Concurrent;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using System.Text.Json;
using System.Text.Json.Serialization;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Storage
{
- public class FlowLauncherJsonStorageTopMostRecord : ISavable
+ public class FlowLauncherJsonStorageTopMostRecord
{
private readonly FlowLauncherJsonStorage _topMostRecordStorage;
private readonly MultipleTopMostRecord _topMostRecord;
public FlowLauncherJsonStorageTopMostRecord()
{
+ // Get old data & new data
var topMostRecordStorage = new FlowLauncherJsonStorage();
- var exist = topMostRecordStorage.Exists();
- if (exist)
- {
- // Get old data
- var topMostRecord = topMostRecordStorage.Load();
+ _topMostRecordStorage = new FlowLauncherJsonStorage();
+
+ // Check if data exist
+ var oldDataExist = topMostRecordStorage.Exists();
+ var newDataExist = _topMostRecordStorage.Exists();
- // Convert to new data
- _topMostRecordStorage = new FlowLauncherJsonStorage();
+ // If new data exist, it means we have already migrated the old data
+ // So we can safely delete the old data and load the new data
+ if (newDataExist)
+ {
+ try
+ {
+ topMostRecordStorage.Delete();
+ }
+ catch
+ {
+ // Ignored
+ }
_topMostRecord = _topMostRecordStorage.Load();
- _topMostRecord.Add(topMostRecord);
}
+ // If new data does not exist and old data exist, we need to migrate the old data to the new data
+ else if (oldDataExist)
+ {
+ // Migrate old data to new data
+ _topMostRecord = _topMostRecordStorage.Load();
+ _topMostRecord.Add(topMostRecordStorage.Load());
+
+ // Delete old data and save the new data
+ try
+ {
+ topMostRecordStorage.Delete();
+ }
+ catch
+ {
+ // Ignored
+ }
+ Save();
+ }
+ // If both data do not exist, we just need to create a new data
else
{
- // Get new data
- _topMostRecordStorage = new FlowLauncherJsonStorage();
_topMostRecord = _topMostRecordStorage.Load();
}
}
@@ -109,6 +138,7 @@ internal void AddOrUpdate(Result result)
public class MultipleTopMostRecord
{
[JsonInclude]
+ [JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
public ConcurrentDictionary> records { get; private set; } = new();
internal void Add(TopMostRecord topMostRecord)
@@ -207,6 +237,30 @@ internal void AddOrUpdate(Result result)
}
}
+ public class ConcurrentDictionaryConcurrentBagConverter : JsonConverter>>
+ {
+ public override ConcurrentDictionary> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var dictionary = JsonSerializer.Deserialize>>(ref reader, options);
+ var concurrentDictionary = new ConcurrentDictionary>();
+ foreach (var kvp in dictionary)
+ {
+ concurrentDictionary.TryAdd(kvp.Key, new ConcurrentBag(kvp.Value));
+ }
+ return concurrentDictionary;
+ }
+
+ public override void Write(Utf8JsonWriter writer, ConcurrentDictionary> value, JsonSerializerOptions options)
+ {
+ var dict = new Dictionary>();
+ foreach (var kvp in value)
+ {
+ dict.Add(kvp.Key, kvp.Value.ToList());
+ }
+ JsonSerializer.Serialize(writer, dict, options);
+ }
+ }
+
public class Record
{
public string Title { get; init; }
From 845c331cac40301da43d107ae547c2818faaff29 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:16:16 +0800
Subject: [PATCH 1145/1335] Remove the bag from dictionary if the bag is empty
---
Flow.Launcher/Storage/TopMostRecord.cs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index f7459dc402b..aaf7194e706 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -188,6 +188,12 @@ internal void Remove(Result result)
{
value.TryTake(out recordToRemove);
}
+
+ // if the bag is empty, remove the bag from the dictionary
+ if (value.IsEmpty)
+ {
+ records.TryRemove(result.OriginQuery.RawQuery, out _);
+ }
}
internal void AddOrUpdate(Result result)
From 07f44f23771e4ac21f5b837fcee66a884513a282 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:19:23 +0800
Subject: [PATCH 1146/1335] Add code comments
---
Flow.Launcher/Storage/TopMostRecord.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index aaf7194e706..d604eabc180 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -243,6 +243,9 @@ internal void AddOrUpdate(Result result)
}
}
+ ///
+ /// Because ConcurrentBag does not support serialization, we need to convert it to a List
+ ///
public class ConcurrentDictionaryConcurrentBagConverter : JsonConverter>>
{
public override ConcurrentDictionary> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
From 0673d07c2a14a6595d4c495c1ab7b3fde3395782 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:23:22 +0800
Subject: [PATCH 1147/1335] Improve code comments & Make classes internal
---
Flow.Launcher/Storage/TopMostRecord.cs | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index d604eabc180..7c45bcf66f3 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -34,7 +34,7 @@ public FlowLauncherJsonStorageTopMostRecord()
}
catch
{
- // Ignored
+ // Ignored - Flow will delete the old data during next startup
}
_topMostRecord = _topMostRecordStorage.Load();
}
@@ -52,7 +52,7 @@ public FlowLauncherJsonStorageTopMostRecord()
}
catch
{
- // Ignored
+ // Ignored - Flow will delete the old data during next startup
}
Save();
}
@@ -84,7 +84,10 @@ public void AddOrUpdate(Result result)
}
}
- public class TopMostRecord
+ ///
+ /// Old data structure to support only one top most record for the same query
+ ///
+ internal class TopMostRecord
{
[JsonInclude]
public ConcurrentDictionary records { get; private set; } = new();
@@ -135,7 +138,10 @@ internal void AddOrUpdate(Result result)
}
}
- public class MultipleTopMostRecord
+ ///
+ /// New data structure to support multiple top most records for the same query
+ ///
+ internal class MultipleTopMostRecord
{
[JsonInclude]
[JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
@@ -246,7 +252,7 @@ internal void AddOrUpdate(Result result)
///
/// Because ConcurrentBag does not support serialization, we need to convert it to a List
///
- public class ConcurrentDictionaryConcurrentBagConverter : JsonConverter>>
+ internal class ConcurrentDictionaryConcurrentBagConverter : JsonConverter>>
{
public override ConcurrentDictionary> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
@@ -270,7 +276,7 @@ public override void Write(Utf8JsonWriter writer, ConcurrentDictionary
Date: Thu, 1 May 2025 13:33:24 +0800
Subject: [PATCH 1148/1335] Code quality
---
.../Storage/JsonStorage.cs | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
index db9ccc28a7e..c7eba05fd5c 100644
--- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
+++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs
@@ -52,17 +52,12 @@ public bool Exists()
public void Delete()
{
- if (File.Exists(FilePath))
- {
- File.Delete(FilePath);
- }
- if (File.Exists(BackupFilePath))
+ foreach (var path in new[] { FilePath, BackupFilePath, TempFilePath })
{
- File.Delete(BackupFilePath);
- }
- if (File.Exists(TempFilePath))
- {
- File.Delete(TempFilePath);
+ if (File.Exists(path))
+ {
+ File.Delete(path);
+ }
}
}
From c49b3b7cba86ffadaec56e748751041f5e5c47c1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:42:54 +0800
Subject: [PATCH 1149/1335] Fix TryTake may remove the wrong element
---
Flow.Launcher/Storage/TopMostRecord.cs | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 7c45bcf66f3..0a9921f7338 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -189,11 +189,8 @@ internal void Remove(Result result)
}
// remove the record from the bag
- var recordToRemove = value.FirstOrDefault(r => r.Equals(result));
- if (recordToRemove != null)
- {
- value.TryTake(out recordToRemove);
- }
+ var bag = new ConcurrentQueue(value.Where(r => !r.Equals(result)));
+ records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
// if the bag is empty, remove the bag from the dictionary
if (value.IsEmpty)
@@ -230,21 +227,9 @@ internal void AddOrUpdate(Result result)
else
{
// add or update the record in the bag
- if (value.Any(r => r.Equals(result)))
- {
- // update the record
- var recordToUpdate = value.FirstOrDefault(r => r.Equals(result));
- if (recordToUpdate != null)
- {
- value.TryTake(out recordToUpdate);
- value.Add(record);
- }
- }
- else
- {
- // add the record
- value.Add(record);
- }
+ var bag = new ConcurrentQueue(value.Where(r => !r.Equals(result))); // make sure we don't have duplicates
+ bag.Enqueue(record);
+ records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
}
}
}
From 58b9f0c19cbff0fa202701dad68c875562829456 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 1 May 2025 13:47:35 +0800
Subject: [PATCH 1150/1335] Improve remove logic
---
Flow.Launcher/Storage/TopMostRecord.cs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 0a9921f7338..47ebb4a9598 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -190,13 +190,16 @@ internal void Remove(Result result)
// remove the record from the bag
var bag = new ConcurrentQueue(value.Where(r => !r.Equals(result)));
- records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
-
- // if the bag is empty, remove the bag from the dictionary
- if (value.IsEmpty)
+ if (bag.IsEmpty)
{
+ // if the bag is empty, remove the bag from the dictionary
records.TryRemove(result.OriginQuery.RawQuery, out _);
}
+ else
+ {
+ // change the bag in the dictionary
+ records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
+ }
}
internal void AddOrUpdate(Result result)
From 7103c8d24afa9e65e7a03a9c6721aa2eac787cc2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 09:59:06 +0800
Subject: [PATCH 1151/1335] Mark old data as obsolete
---
Flow.Launcher/Storage/TopMostRecord.cs | 31 +++++++++++---------------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 47ebb4a9598..7ddca721b57 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -16,8 +16,10 @@ public class FlowLauncherJsonStorageTopMostRecord
public FlowLauncherJsonStorageTopMostRecord()
{
+#pragma warning disable CS0618 // Type or member is obsolete
// Get old data & new data
var topMostRecordStorage = new FlowLauncherJsonStorage();
+#pragma warning restore CS0618 // Type or member is obsolete
_topMostRecordStorage = new FlowLauncherJsonStorage();
// Check if data exist
@@ -43,7 +45,16 @@ public FlowLauncherJsonStorageTopMostRecord()
{
// Migrate old data to new data
_topMostRecord = _topMostRecordStorage.Load();
- _topMostRecord.Add(topMostRecordStorage.Load());
+ var oldTopMostRecord = topMostRecordStorage.Load();
+ if (oldTopMostRecord == null || oldTopMostRecord.records.IsEmpty) return;
+ foreach (var record in oldTopMostRecord.records)
+ {
+ _topMostRecord.records.AddOrUpdate(record.Key, new ConcurrentBag { record.Value }, (key, oldValue) =>
+ {
+ oldValue.Add(record.Value);
+ return oldValue;
+ });
+ }
// Delete old data and save the new data
try
@@ -87,6 +98,7 @@ public void AddOrUpdate(Result result)
///
/// Old data structure to support only one top most record for the same query
///
+ [Obsolete("Use MultipleTopMostRecord instead. This class will be removed in future versions.")]
internal class TopMostRecord
{
[JsonInclude]
@@ -147,23 +159,6 @@ internal class MultipleTopMostRecord
[JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
public ConcurrentDictionary> records { get; private set; } = new();
- internal void Add(TopMostRecord topMostRecord)
- {
- if (topMostRecord == null || topMostRecord.records.IsEmpty)
- {
- return;
- }
-
- foreach (var record in topMostRecord.records)
- {
- records.AddOrUpdate(record.Key, new ConcurrentBag { record.Value }, (key, oldValue) =>
- {
- oldValue.Add(record.Value);
- return oldValue;
- });
- }
- }
-
internal bool IsTopMost(Result result)
{
// origin query is null when user select the context menu item directly of one item from query list
From b25777b73457d872637ad594cad571d65fdea43c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 10:28:35 +0800
Subject: [PATCH 1152/1335] Use ConcurrentQueue to storage the data sequence &
Put latter record topper
---
Flow.Launcher/Storage/TopMostRecord.cs | 81 ++++++++++++++++--------
Flow.Launcher/ViewModel/MainViewModel.cs | 5 +-
2 files changed, 59 insertions(+), 27 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 7ddca721b57..d75e9cb7908 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -49,9 +49,11 @@ public FlowLauncherJsonStorageTopMostRecord()
if (oldTopMostRecord == null || oldTopMostRecord.records.IsEmpty) return;
foreach (var record in oldTopMostRecord.records)
{
- _topMostRecord.records.AddOrUpdate(record.Key, new ConcurrentBag { record.Value }, (key, oldValue) =>
+ var newValue = new ConcurrentQueue();
+ newValue.Enqueue(record.Value);
+ _topMostRecord.records.AddOrUpdate(record.Key, newValue, (key, oldValue) =>
{
- oldValue.Add(record.Value);
+ oldValue.Enqueue(record.Value);
return oldValue;
});
}
@@ -84,6 +86,11 @@ public bool IsTopMost(Result result)
return _topMostRecord.IsTopMost(result);
}
+ public int GetTopMostIndex(Result result)
+ {
+ return _topMostRecord.GetTopMostIndex(result);
+ }
+
public void Remove(Result result)
{
_topMostRecord.Remove(result);
@@ -156,8 +163,8 @@ internal void AddOrUpdate(Result result)
internal class MultipleTopMostRecord
{
[JsonInclude]
- [JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
- public ConcurrentDictionary> records { get; private set; } = new();
+ [JsonConverter(typeof(ConcurrentDictionaryConcurrentQueueConverter))]
+ public ConcurrentDictionary> records { get; private set; } = new();
internal bool IsTopMost(Result result)
{
@@ -173,6 +180,32 @@ internal bool IsTopMost(Result result)
return value.Any(record => record.Equals(result));
}
+ internal int GetTopMostIndex(Result result)
+ {
+ // origin query is null when user select the context menu item directly of one item from query list
+ // in this case, we do not need to check if the result is top most
+ if (records.IsEmpty || result.OriginQuery == null ||
+ !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
+ {
+ return -1;
+ }
+
+ // since this dictionary should be very small (or empty) going over it should be pretty fast.
+ // since the latter items should be more recent, we should return the smaller index for score to subtract
+ // which can make them more topmost
+ // A, B, C => 2, 1, 0 => (max - 2), (max - 1), (max - 0)
+ var index = 0;
+ foreach (var record in value)
+ {
+ if (record.Equals(result))
+ {
+ return value.Count - 1 - index;
+ }
+ index++;
+ }
+ return -1;
+ }
+
internal void Remove(Result result)
{
// origin query is null when user select the context menu item directly of one item from query list
@@ -183,17 +216,17 @@ internal void Remove(Result result)
return;
}
- // remove the record from the bag
- var bag = new ConcurrentQueue(value.Where(r => !r.Equals(result)));
- if (bag.IsEmpty)
+ // remove the record from the queue
+ var queue = new ConcurrentQueue(value.Where(r => !r.Equals(result)));
+ if (queue.IsEmpty)
{
- // if the bag is empty, remove the bag from the dictionary
+ // if the queue is empty, remove the queue from the dictionary
records.TryRemove(result.OriginQuery.RawQuery, out _);
}
else
{
- // change the bag in the dictionary
- records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
+ // change the queue in the dictionary
+ records[result.OriginQuery.RawQuery] = queue;
}
}
@@ -215,40 +248,38 @@ internal void AddOrUpdate(Result result)
};
if (!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
- // create a new bag if it does not exist
- value = new ConcurrentBag()
- {
- record
- };
+ // create a new queue if it does not exist
+ value = new ConcurrentQueue();
+ value.Enqueue(record);
records.TryAdd(result.OriginQuery.RawQuery, value);
}
else
{
- // add or update the record in the bag
- var bag = new ConcurrentQueue(value.Where(r => !r.Equals(result))); // make sure we don't have duplicates
- bag.Enqueue(record);
- records[result.OriginQuery.RawQuery] = new ConcurrentBag(bag);
+ // add or update the record in the queue
+ var queue = new ConcurrentQueue(value.Where(r => !r.Equals(result))); // make sure we don't have duplicates
+ queue.Enqueue(record);
+ records[result.OriginQuery.RawQuery] = queue;
}
}
}
///
- /// Because ConcurrentBag does not support serialization, we need to convert it to a List
+ /// Because ConcurrentQueue does not support serialization, we need to convert it to a List
///
- internal class ConcurrentDictionaryConcurrentBagConverter : JsonConverter>>
+ internal class ConcurrentDictionaryConcurrentQueueConverter : JsonConverter>>
{
- public override ConcurrentDictionary> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override ConcurrentDictionary> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dictionary = JsonSerializer.Deserialize>>(ref reader, options);
- var concurrentDictionary = new ConcurrentDictionary>();
+ var concurrentDictionary = new ConcurrentDictionary>();
foreach (var kvp in dictionary)
{
- concurrentDictionary.TryAdd(kvp.Key, new ConcurrentBag(kvp.Value));
+ concurrentDictionary.TryAdd(kvp.Key, new ConcurrentQueue(kvp.Value));
}
return concurrentDictionary;
}
- public override void Write(Utf8JsonWriter writer, ConcurrentDictionary> value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, ConcurrentDictionary> value, JsonSerializerOptions options)
{
var dict = new Dictionary>();
foreach (var kvp in value)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 54ad6c288cd..adb04279e56 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1643,9 +1643,10 @@ public void UpdateResultView(ICollection resultsForUpdates)
{
foreach (var result in metaResults.Results)
{
- if (_topMostRecord.IsTopMost(result))
+ var deviationIndex = _topMostRecord.GetTopMostIndex(result);
+ if (deviationIndex != -1)
{
- result.Score = Result.MaxScore;
+ result.Score = Result.MaxScore - deviationIndex;
}
else
{
From 1cf264a3a9c5d519482f5585e7fb54ad23ce9dfe Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 2 May 2025 10:32:24 +0800
Subject: [PATCH 1153/1335] Add code comments
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index adb04279e56..96e039ebefd 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1646,6 +1646,8 @@ public void UpdateResultView(ICollection resultsForUpdates)
var deviationIndex = _topMostRecord.GetTopMostIndex(result);
if (deviationIndex != -1)
{
+ // Adjust the score based on the result's position in the top-most list.
+ // A lower deviationIndex (closer to the top) results in a higher score.
result.Score = Result.MaxScore - deviationIndex;
}
else
From 8bb96d7f5866b5bf90dbf0224137144ccd91bd70 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 2 May 2025 12:26:14 +0800
Subject: [PATCH 1154/1335] Fix copy to clipboard STA thread issue & Support
retry for copy & Async build-in shortcut model & Fix build shortcuts text
replace issue & Fix startup window hide issue (#3314)
---
Flow.Launcher.Core/Plugin/QueryBuilder.cs | 6 +-
Flow.Launcher.Core/Resource/Theme.cs | 20 +-
.../NativeMethods.txt | 5 +-
.../UserSettings/CustomShortcutModel.cs | 67 ++++--
.../UserSettings/Settings.cs | 4 +-
Flow.Launcher.Infrastructure/Win32Helper.cs | 74 +++++++
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 5 +-
Flow.Launcher.Plugin/Query.cs | 7 +-
Flow.Launcher/App.xaml.cs | 9 +-
Flow.Launcher/Helper/DataWebRequestFactory.cs | 12 +-
Flow.Launcher/Helper/ErrorReporting.cs | 18 +-
Flow.Launcher/Languages/en.xaml | 1 +
Flow.Launcher/MainWindow.xaml.cs | 4 -
Flow.Launcher/PublicAPIInstance.cs | 88 ++++++--
.../SettingsPanePluginStoreViewModel.cs | 4 +-
.../SettingsPanePluginsViewModel.cs | 33 +--
.../Views/SettingsPanePlugins.xaml | 9 +-
.../Views/SettingsPanePlugins.xaml.cs | 31 ++-
Flow.Launcher/ViewModel/MainViewModel.cs | 197 ++++++++++++------
19 files changed, 439 insertions(+), 155 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
index 3dc7877acc2..0ef3f30f5e1 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Flow.Launcher.Plugin;
@@ -33,7 +33,7 @@ public static Query Build(string text, Dictionary nonGlobalP
searchTerms = terms;
}
- return new Query ()
+ return new Query()
{
Search = search,
RawQuery = rawQuery,
@@ -42,4 +42,4 @@ public static Query Build(string text, Dictionary nonGlobalP
};
}
}
-}
\ No newline at end of file
+}
diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index a46932c6af4..059359694b4 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -76,7 +76,7 @@ public Theme(IPublicAPI publicAPI, Settings settings)
{
_api.LogError(ClassName, "Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
- };
+ }
}
#endregion
@@ -126,7 +126,7 @@ public void UpdateFonts()
// Load a ResourceDictionary for the specified theme.
var themeName = _settings.Theme;
var dict = GetThemeResourceDictionary(themeName);
-
+
// Apply font settings to the theme resource.
ApplyFontSettings(dict);
UpdateResourceDictionary(dict);
@@ -152,11 +152,11 @@ private void ApplyFontSettings(ResourceDictionary dict)
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.QueryBoxFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);
-
+
SetFontProperties(queryBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, true);
SetFontProperties(querySuggestionBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
-
+
if (dict["ItemTitleStyle"] is Style resultItemStyle &&
dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle &&
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
@@ -172,7 +172,7 @@ private void ApplyFontSettings(ResourceDictionary dict)
SetFontProperties(resultHotkeyItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultHotkeyItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
-
+
if (dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle)
{
@@ -197,7 +197,7 @@ private static void SetFontProperties(Style style, FontFamily fontFamily, FontSt
// First, find the setters to remove and store them in a list
var settersToRemove = style.Setters
.OfType()
- .Where(setter =>
+ .Where(setter =>
setter.Property == Control.FontFamilyProperty ||
setter.Property == Control.FontStyleProperty ||
setter.Property == Control.FontWeightProperty ||
@@ -227,18 +227,18 @@ private static void SetFontProperties(Style style, FontFamily fontFamily, FontSt
{
var settersToRemove = style.Setters
.OfType()
- .Where(setter =>
+ .Where(setter =>
setter.Property == TextBlock.FontFamilyProperty ||
setter.Property == TextBlock.FontStyleProperty ||
setter.Property == TextBlock.FontWeightProperty ||
setter.Property == TextBlock.FontStretchProperty)
.ToList();
-
+
foreach (var setter in settersToRemove)
{
style.Setters.Remove(setter);
}
-
+
style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, fontFamily));
style.Setters.Add(new Setter(TextBlock.FontStyleProperty, fontStyle));
style.Setters.Add(new Setter(TextBlock.FontWeightProperty, fontWeight));
@@ -421,7 +421,7 @@ public bool ChangeTheme(string theme = null)
// Retrieve theme resource – always use the resource with font settings applied.
var resourceDict = GetResourceDictionary(theme);
-
+
UpdateResourceDictionary(resourceDict);
_settings.Theme = theme;
diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt
index 18b20602213..0e50420b0e0 100644
--- a/Flow.Launcher.Infrastructure/NativeMethods.txt
+++ b/Flow.Launcher.Infrastructure/NativeMethods.txt
@@ -43,6 +43,9 @@ MONITORINFOEXW
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
+OleInitialize
+OleUninitialize
+
GetKeyboardLayout
GetWindowThreadProcessId
ActivateKeyboardLayout
@@ -53,4 +56,4 @@ INPUTLANGCHANGE_FORWARD
LOCALE_TRANSIENT_KEYBOARD1
LOCALE_TRANSIENT_KEYBOARD2
LOCALE_TRANSIENT_KEYBOARD3
-LOCALE_TRANSIENT_KEYBOARD4
\ No newline at end of file
+LOCALE_TRANSIENT_KEYBOARD4
diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
index 71020369a60..2d15b54c5be 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/CustomShortcutModel.cs
@@ -1,15 +1,15 @@
using System;
using System.Text.Json.Serialization;
+using System.Threading.Tasks;
namespace Flow.Launcher.Infrastructure.UserSettings
{
+ #region Base
+
public abstract class ShortcutBaseModel
{
public string Key { get; set; }
- [JsonIgnore]
- public Func Expand { get; set; } = () => { return ""; };
-
public override bool Equals(object obj)
{
return obj is ShortcutBaseModel other &&
@@ -22,16 +22,14 @@ public override int GetHashCode()
}
}
- public class CustomShortcutModel : ShortcutBaseModel
+ public class BaseCustomShortcutModel : ShortcutBaseModel
{
public string Value { get; set; }
- [JsonConstructorAttribute]
- public CustomShortcutModel(string key, string value)
+ public BaseCustomShortcutModel(string key, string value)
{
Key = key;
Value = value;
- Expand = () => { return Value; };
}
public void Deconstruct(out string key, out string value)
@@ -40,26 +38,69 @@ public void Deconstruct(out string key, out string value)
value = Value;
}
- public static implicit operator (string Key, string Value)(CustomShortcutModel shortcut)
+ public static implicit operator (string Key, string Value)(BaseCustomShortcutModel shortcut)
{
return (shortcut.Key, shortcut.Value);
}
- public static implicit operator CustomShortcutModel((string Key, string Value) shortcut)
+ public static implicit operator BaseCustomShortcutModel((string Key, string Value) shortcut)
{
- return new CustomShortcutModel(shortcut.Key, shortcut.Value);
+ return new BaseCustomShortcutModel(shortcut.Key, shortcut.Value);
}
}
- public class BuiltinShortcutModel : ShortcutBaseModel
+ public class BaseBuiltinShortcutModel : ShortcutBaseModel
{
public string Description { get; set; }
- public BuiltinShortcutModel(string key, string description, Func expand)
+ public BaseBuiltinShortcutModel(string key, string description)
{
Key = key;
Description = description;
- Expand = expand ?? (() => { return ""; });
}
}
+
+ #endregion
+
+ #region Custom Shortcut
+
+ public class CustomShortcutModel : BaseCustomShortcutModel
+ {
+ [JsonIgnore]
+ public Func Expand { get; set; } = () => { return string.Empty; };
+
+ [JsonConstructor]
+ public CustomShortcutModel(string key, string value) : base(key, value)
+ {
+ Expand = () => { return Value; };
+ }
+ }
+
+ #endregion
+
+ #region Builtin Shortcut
+
+ public class BuiltinShortcutModel : BaseBuiltinShortcutModel
+ {
+ [JsonIgnore]
+ public Func Expand { get; set; } = () => { return string.Empty; };
+
+ public BuiltinShortcutModel(string key, string description, Func expand) : base(key, description)
+ {
+ Expand = expand ?? (() => { return string.Empty; });
+ }
+ }
+
+ public class AsyncBuiltinShortcutModel : BaseBuiltinShortcutModel
+ {
+ [JsonIgnore]
+ public Func> ExpandAsync { get; set; } = () => { return Task.FromResult(string.Empty); };
+
+ public AsyncBuiltinShortcutModel(string key, string description, Func> expandAsync) : base(key, description)
+ {
+ ExpandAsync = expandAsync ?? (() => { return Task.FromResult(string.Empty); });
+ }
+ }
+
+ #endregion
}
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 1cccc38d938..b7a1d1f6367 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -312,9 +312,9 @@ public bool KeepMaxResults
public ObservableCollection CustomShortcuts { get; set; } = new ObservableCollection();
[JsonIgnore]
- public ObservableCollection BuiltinShortcuts { get; set; } = new()
+ public ObservableCollection BuiltinShortcuts { get; set; } = new()
{
- new BuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", Clipboard.GetText),
+ new AsyncBuiltinShortcutModel("{clipboard}", "shortcut_clipboard_description", () => Win32Helper.StartSTATaskAsync(Clipboard.GetText)),
new BuiltinShortcutModel("{active_explorer_path}", "shortcut_active_explorer_path", FileExplorerHelper.GetActiveExplorerPath)
};
diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs
index 2788060eb4c..783ade14ebe 100644
--- a/Flow.Launcher.Infrastructure/Win32Helper.cs
+++ b/Flow.Launcher.Infrastructure/Win32Helper.cs
@@ -5,6 +5,8 @@
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Markup;
@@ -337,6 +339,78 @@ internal static HWND GetWindowHandle(Window window, bool ensure = false)
#endregion
+ #region STA Thread
+
+ /*
+ Inspired by https://github.com/files-community/Files code on STA Thread handling.
+ */
+
+ public static Task StartSTATaskAsync(Action action)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+ Thread thread = new(() =>
+ {
+ PInvoke.OleInitialize();
+
+ try
+ {
+ action();
+ taskCompletionSource.SetResult();
+ }
+ catch (System.Exception ex)
+ {
+ taskCompletionSource.SetException(ex);
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+
+ public static Task StartSTATaskAsync(Func func)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ Thread thread = new(() =>
+ {
+ PInvoke.OleInitialize();
+
+ try
+ {
+ taskCompletionSource.SetResult(func());
+ }
+ catch (System.Exception ex)
+ {
+ taskCompletionSource.SetException(ex);
+ }
+ finally
+ {
+ PInvoke.OleUninitialize();
+ }
+ })
+ {
+ IsBackground = true,
+ Priority = ThreadPriority.Normal
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return taskCompletionSource.Task;
+ }
+
+ #endregion
+
#region Keyboard Layout
private const string UserProfileRegistryPath = @"Control Panel\International\User Profile";
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 31580fbe80a..d4eb02a909e 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -471,8 +471,11 @@ public interface IPublicAPI
public Task UpdatePluginManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default);
///
- /// Get the plugin manifest
+ /// Get the plugin manifest.
///
+ ///
+ /// If Flow cannot get manifest data, this could be null
+ ///
///
public IReadOnlyList GetPluginManifest();
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index 913dc31ae65..c3eede4c6b6 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -8,7 +8,8 @@ namespace Flow.Launcher.Plugin
public class Query
{
///
- /// Raw query, this includes action keyword if it has
+ /// Raw query, this includes action keyword if it has.
+ /// It has handled buildin custom query shortkeys and build-in shortcuts, and it trims the whitespace.
/// We didn't recommend use this property directly. You should always use Search property.
///
public string RawQuery { get; internal init; }
@@ -63,10 +64,10 @@ public class Query
///
[JsonIgnore]
public string FirstSearch => SplitSearch(0);
-
+
[JsonIgnore]
private string _secondToEndSearch;
-
+
///
/// strings from second search (including) to last search
///
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 1b57d5cbe5c..402812a92d7 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -23,6 +23,7 @@
using Flow.Launcher.ViewModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.VisualStudio.Threading;
namespace Flow.Launcher
{
@@ -198,6 +199,10 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
Current.MainWindow = _mainWindow;
Current.MainWindow.Title = Constant.FlowLauncher;
+ // Initialize hotkey mapper instantly after main window is created because
+ // it will steal focus from main window which causes window hide
+ HotKeyMapper.Initialize();
+
// Main windows needs initialized before theme change because of blur settings
Ioc.Default.GetRequiredService().ChangeTheme();
@@ -239,6 +244,7 @@ private void AutoStartup()
}
}
+ [Conditional("RELEASE")]
private void AutoUpdates()
{
_ = Task.Run(async () =>
@@ -296,13 +302,12 @@ private void RegisterDispatcherUnhandledException()
[Conditional("RELEASE")]
private static void RegisterAppDomainExceptions()
{
- AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
+ AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledException;
}
///
/// Let exception throw as normal is better for Debug
///
- [Conditional("RELEASE")]
private static void RegisterTaskSchedulerUnhandledException()
{
TaskScheduler.UnobservedTaskException += ErrorReporting.TaskSchedulerUnobservedTaskException;
diff --git a/Flow.Launcher/Helper/DataWebRequestFactory.cs b/Flow.Launcher/Helper/DataWebRequestFactory.cs
index 2e72ee240fd..db198ede4e7 100644
--- a/Flow.Launcher/Helper/DataWebRequestFactory.cs
+++ b/Flow.Launcher/Helper/DataWebRequestFactory.cs
@@ -28,18 +28,18 @@ class DataWebResponse : WebResponse
public DataWebResponse(Uri uri)
{
- string uriString = uri.AbsoluteUri;
+ var uriString = uri.AbsoluteUri;
- int commaIndex = uriString.IndexOf(',');
- var headers = uriString.Substring(0, commaIndex).Split(';');
+ var commaIndex = uriString.IndexOf(',');
+ var headers = uriString[..commaIndex].Split(';');
_contentType = headers[0];
- string dataString = uriString.Substring(commaIndex + 1);
+ var dataString = uriString[(commaIndex + 1)..];
_data = Convert.FromBase64String(dataString);
}
public override string ContentType
{
- get { return _contentType; }
+ get => _contentType;
set
{
throw new NotSupportedException();
@@ -48,7 +48,7 @@ public override string ContentType
public override long ContentLength
{
- get { return _data.Length; }
+ get => _data.Length;
set
{
throw new NotSupportedException();
diff --git a/Flow.Launcher/Helper/ErrorReporting.cs b/Flow.Launcher/Helper/ErrorReporting.cs
index b1ddba7179a..aa810ba651a 100644
--- a/Flow.Launcher/Helper/ErrorReporting.cs
+++ b/Flow.Launcher/Helper/ErrorReporting.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
@@ -10,33 +11,34 @@ namespace Flow.Launcher.Helper;
public static class ErrorReporting
{
- private static void Report(Exception e)
+ private static void Report(Exception e, [CallerMemberName] string methodName = "UnHandledException")
{
- var logger = LogManager.GetLogger("UnHandledException");
+ var logger = LogManager.GetLogger(methodName);
logger.Fatal(ExceptionFormatter.FormatExcpetion(e));
var reportWindow = new ReportWindow(e);
reportWindow.Show();
}
- public static void UnhandledExceptionHandle(object sender, UnhandledExceptionEventArgs e)
+ public static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
- //handle non-ui thread exceptions
+ // handle non-ui thread exceptions
Report((Exception)e.ExceptionObject);
}
public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
- //handle ui thread exceptions
+ // handle ui thread exceptions
Report(e.Exception);
- //prevent application exist, so the user can copy prompted error info
+ // prevent application exist, so the user can copy prompted error info
e.Handled = true;
}
public static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
- //handle unobserved task exceptions
+ // handle unobserved task exceptions on UI thread
Application.Current.Dispatcher.Invoke(() => Report(e.Exception));
- //prevent application exit, so the user can copy the prompted error info
+ // prevent application exit, so the user can copy the prompted error info
+ e.SetObserved();
}
public static string RuntimeInfo()
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index d3252cb314c..ca0ed33b514 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -394,6 +394,7 @@
This new Action Keyword is the same as old, please choose a different one
Success
Completed successfully
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 10aff050ee8..ae7b098a206 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -16,7 +16,6 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Image;
@@ -182,9 +181,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
// Set the initial state of the QueryTextBoxCursorMovedToEnd property
// Without this part, when shown for the first time, switching the context menu does not move the cursor to the end.
_viewModel.QueryTextCursorMovedToEnd = false;
-
- // Initialize hotkey mapper after window is loaded
- HotKeyMapper.Initialize();
// View model property changed event
_viewModel.PropertyChanged += (o, e) =>
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 3abc57b8a81..5b8e8c9af89 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -40,7 +40,7 @@ public class PublicAPIInstance : IPublicAPI, IRemovable
private readonly Settings _settings;
private readonly MainViewModel _mainVM;
- // Must use getter to access Application.Current.Resources.MergedDictionaries so earlier
+ // Must use getter to avoid accessing Application.Current.Resources.MergedDictionaries so earlier in theme constructor
private Theme _theme;
private Theme Theme => _theme ??= Ioc.Default.GetRequiredService();
@@ -69,8 +69,7 @@ public void ChangeQuery(string query, bool requery = false)
_mainVM.ChangeQueryText(query, requery);
}
-#pragma warning disable VSTHRD100 // Avoid async void methods
-
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
public async void RestartApp()
{
_mainVM.Hide();
@@ -89,8 +88,6 @@ public async void RestartApp()
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
-#pragma warning restore VSTHRD100 // Avoid async void methods
-
public void ShowMainWindow() => _mainVM.Show();
public void HideMainWindow() => _mainVM.Hide();
@@ -145,35 +142,90 @@ public void ShellRun(string cmd, string filename = "cmd.exe")
ShellCommand.Execute(startInfo);
}
- public void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
+ public async void CopyToClipboard(string stringToCopy, bool directCopy = false, bool showDefaultNotification = true)
{
if (string.IsNullOrEmpty(stringToCopy))
+ {
return;
+ }
var isFile = File.Exists(stringToCopy);
if (directCopy && (isFile || Directory.Exists(stringToCopy)))
{
- var paths = new StringCollection
+ // Sometimes the clipboard is locked and cannot be accessed,
+ // we need to retry a few times before giving up
+ var exception = await RetryActionOnSTAThreadAsync(() =>
+ {
+ var paths = new StringCollection
{
stringToCopy
};
- Clipboard.SetFileDropList(paths);
-
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
- GetTranslation("completedSuccessfully"));
+ Clipboard.SetFileDropList(paths);
+ });
+
+ if (exception == null)
+ {
+ if (showDefaultNotification)
+ {
+ ShowMsg(
+ $"{GetTranslation("copy")} {(isFile ? GetTranslation("fileTitle") : GetTranslation("folderTitle"))}",
+ GetTranslation("completedSuccessfully"));
+ }
+ }
+ else
+ {
+ LogException(nameof(PublicAPIInstance), "Failed to copy file/folder to clipboard", exception);
+ ShowMsgError(GetTranslation("failedToCopy"));
+ }
}
else
{
- Clipboard.SetDataObject(stringToCopy);
+ // Sometimes the clipboard is locked and cannot be accessed,
+ // we need to retry a few times before giving up
+ var exception = await RetryActionOnSTAThreadAsync(() =>
+ {
+ // We should use SetText instead of SetDataObject to avoid the clipboard being locked by other applications
+ Clipboard.SetText(stringToCopy);
+ });
+
+ if (exception == null)
+ {
+ if (showDefaultNotification)
+ {
+ ShowMsg(
+ $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
+ GetTranslation("completedSuccessfully"));
+ }
+ }
+ else
+ {
+ LogException(nameof(PublicAPIInstance), "Failed to copy text to clipboard", exception);
+ ShowMsgError(GetTranslation("failedToCopy"));
+ }
+ }
+ }
- if (showDefaultNotification)
- ShowMsg(
- $"{GetTranslation("copy")} {GetTranslation("textTitle")}",
- GetTranslation("completedSuccessfully"));
+ private static async Task RetryActionOnSTAThreadAsync(Action action, int retryCount = 6, int retryDelay = 150)
+ {
+ for (var i = 0; i < retryCount; i++)
+ {
+ try
+ {
+ await Win32Helper.StartSTATaskAsync(action).ConfigureAwait(false);
+ break;
+ }
+ catch (Exception e)
+ {
+ if (i == retryCount - 1)
+ {
+ return e;
+ }
+ await Task.Delay(retryDelay);
+ }
}
+ return null;
}
public void StartLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Visible;
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
index 249e4dd424e..07df0682dbb 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
@@ -79,8 +79,8 @@ public bool ShowExecutable
}
}
- public IList ExternalPlugins =>
- App.API.GetPluginManifest()?.Select(p => new PluginStoreItemViewModel(p))
+ public IList ExternalPlugins => App.API.GetPluginManifest()?
+ .Select(p => new PluginStoreItemViewModel(p))
.OrderByDescending(p => p.Category == PluginStoreItemViewModel.NewRelease)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.RecentlyUpdated)
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.None)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
index de7cf15c399..abb314355b4 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginsViewModel.cs
@@ -86,12 +86,22 @@ public SettingsPanePluginsViewModel(Settings settings)
UpdateEnumDropdownLocalizations();
}
- public string FilterText { get; set; } = string.Empty;
-
- public PluginViewModel? SelectedPlugin { get; set; }
+ private string filterText = string.Empty;
+ public string FilterText
+ {
+ get => filterText;
+ set
+ {
+ if (filterText != value)
+ {
+ filterText = value;
+ OnPropertyChanged();
+ }
+ }
+ }
- private IEnumerable? _pluginViewModels;
- private IEnumerable PluginViewModels => _pluginViewModels ??= PluginManager.AllPlugins
+ private IList? _pluginViewModels;
+ public IList PluginViewModels => _pluginViewModels ??= PluginManager.AllPlugins
.OrderBy(plugin => plugin.Metadata.Disabled)
.ThenBy(plugin => plugin.Metadata.Name)
.Select(plugin => new PluginViewModel
@@ -102,13 +112,12 @@ public SettingsPanePluginsViewModel(Settings settings)
.Where(plugin => plugin.PluginSettingsObject != null)
.ToList();
- public List FilteredPluginViewModels => PluginViewModels
- .Where(v =>
- string.IsNullOrEmpty(FilterText) ||
- App.API.FuzzySearch(FilterText, v.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet() ||
- App.API.FuzzySearch(FilterText, v.PluginPair.Metadata.Description).IsSearchPrecisionScoreMet()
- )
- .ToList();
+ public bool SatisfiesFilter(PluginViewModel plugin)
+ {
+ return string.IsNullOrEmpty(FilterText) ||
+ App.API.FuzzySearch(FilterText, plugin.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet() ||
+ App.API.FuzzySearch(FilterText, plugin.PluginPair.Metadata.Description).IsSearchPrecisionScoreMet();
+ }
[RelayCommand]
private async Task OpenHelperAsync(Button button)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
index bb742f800e0..52d77f91418 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml
@@ -15,6 +15,12 @@
FocusManager.FocusedElement="{Binding ElementName=PluginFilterTextbox}"
KeyDown="SettingsPanePlugins_OnKeyDown"
mc:Ignorable="d">
+
+
+
@@ -115,10 +121,9 @@
Background="{DynamicResource Color01B}"
FontSize="14"
ItemContainerStyle="{StaticResource PluginList}"
- ItemsSource="{Binding FilteredPluginViewModels}"
+ ItemsSource="{Binding Source={StaticResource PluginCollectionView}}"
ScrollViewer.CanContentScroll="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
- SelectedItem="{Binding SelectedPlugin}"
SnapsToDevicePixels="True"
Style="{DynamicResource PluginListStyle}"
VirtualizingPanel.ScrollUnit="Pixel"
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index 97574b3ce48..e9490804ab5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -1,7 +1,10 @@
-using System.Windows.Input;
+using System.ComponentModel;
+using System.Windows.Data;
+using System.Windows.Input;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
@@ -17,12 +20,38 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
DataContext = _viewModel;
InitializeComponent();
}
+ _viewModel.PropertyChanged += ViewModel_PropertyChanged;
base.OnNavigatedTo(e);
}
+ private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(SettingsPanePluginsViewModel.FilterText))
+ {
+ ((CollectionViewSource)FindResource("PluginCollectionView")).View.Refresh();
+ }
+ }
+
+ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
+ {
+ _viewModel.PropertyChanged -= ViewModel_PropertyChanged;
+ base.OnNavigatingFrom(e);
+ }
+
private void SettingsPanePlugins_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key is not Key.F || Keyboard.Modifiers is not ModifierKeys.Control) return;
PluginFilterTextbox.Focus();
}
+
+ private void PluginCollectionView_OnFilter(object sender, FilterEventArgs e)
+ {
+ if (e.Item is not PluginViewModel plugin)
+ {
+ e.Accepted = false;
+ return;
+ }
+
+ e.Accepted = _viewModel.SatisfiesFilter(plugin);
+ }
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 00675149b41..2f1ed0f5103 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -43,8 +43,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly UserSelectedRecord _userSelectedRecord;
private readonly TopMostRecord _topMostRecord;
- private CancellationTokenSource _updateSource;
- private CancellationToken _updateToken;
+ private CancellationTokenSource _updateSource; // Used to cancel old query flows
private ChannelWriter _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask;
@@ -241,7 +240,7 @@ public void RegisterResultsUpdatedEvent()
return;
}
- var token = e.Token == default ? _updateToken : e.Token;
+ var token = e.Token == default ? _updateSource.Token : e.Token;
// make a clone to avoid possible issue that plugin will also change the list and items when updating view model
var resultsCopy = DeepCloneResults(e.Results, token);
@@ -255,8 +254,11 @@ public void RegisterResultsUpdatedEvent()
}
PluginManager.UpdatePluginMetadata(resultsCopy, pair.Metadata, e.Query);
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
- token)))
+
+ if (token.IsCancellationRequested) return;
+
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
+ token)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
@@ -640,7 +642,31 @@ private void DecreaseMaxResult()
/// Force query even when Query Text doesn't change
public void ChangeQueryText(string queryText, bool isReQuery = false)
{
- _ = ChangeQueryTextAsync(queryText, isReQuery);
+ // Must check access so that we will not block the UI thread which causes window visibility issue
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ Application.Current.Dispatcher.Invoke(() => ChangeQueryText(queryText, isReQuery));
+ return;
+ }
+
+ if (QueryText != queryText)
+ {
+ // Change query text first
+ QueryText = queryText;
+ // When we are changing query from codes, we should not delay the query
+ Query(false, isReQuery: false);
+
+ // set to false so the subsequent set true triggers
+ // PropertyChanged and MoveQueryTextToEnd is called
+ QueryTextCursorMovedToEnd = false;
+ }
+ else if (isReQuery)
+ {
+ // When we are re-querying, we should not delay the query
+ Query(false, isReQuery: true);
+ }
+
+ QueryTextCursorMovedToEnd = true;
}
///
@@ -648,10 +674,10 @@ public void ChangeQueryText(string queryText, bool isReQuery = false)
///
private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false)
{
- // Must check access so that we will not block the UI thread which cause window visibility issue
+ // Must check access so that we will not block the UI thread which causes window visibility issue
if (!Application.Current.Dispatcher.CheckAccess())
{
- await Application.Current.Dispatcher.InvokeAsync(() => ChangeQueryText(queryText, isReQuery));
+ await Application.Current.Dispatcher.InvokeAsync(() => ChangeQueryTextAsync(queryText, isReQuery));
return;
}
@@ -1050,7 +1076,18 @@ private bool QueryResultsPreviewed()
public void Query(bool searchDelay, bool isReQuery = false)
{
- _ = QueryAsync(searchDelay, isReQuery);
+ if (QueryResultsSelected())
+ {
+ _ = QueryResultsAsync(searchDelay, isReQuery);
+ }
+ else if (ContextMenuSelected())
+ {
+ QueryContextMenu();
+ }
+ else if (HistorySelected())
+ {
+ QueryHistory();
+ }
}
private async Task QueryAsync(bool searchDelay, bool isReQuery = false)
@@ -1160,37 +1197,25 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
_updateSource?.Cancel();
- var query = ConstructQuery(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
-
- var plugins = PluginManager.ValidPluginsForQuery(query);
+ var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
- if (query == null || plugins.Count == 0) // shortcut expanded
+ if (query == null) // shortcut expanded
{
- Results.Clear();
+ // Hide and clear results again because running query may show and add some results
Results.Visibility = Visibility.Collapsed;
+ Results.Clear();
+
+ // Reset plugin icon
PluginIconPath = null;
PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
+
+ // Hide progress bar again because running query may set this to visible
+ ProgressBarVisibility = Visibility.Hidden;
return;
}
- else if (plugins.Count == 1)
- {
- PluginIconPath = plugins.Single().Metadata.IcoPath;
- PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
- SearchIconVisibility = Visibility.Hidden;
- }
- else
- {
- PluginIconPath = null;
- PluginIconSource = null;
- SearchIconVisibility = Visibility.Visible;
- }
-
- _updateSource?.Dispose();
- var currentUpdateSource = new CancellationTokenSource();
- _updateSource = currentUpdateSource;
- _updateToken = _updateSource.Token;
+ _updateSource = new CancellationTokenSource();
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
@@ -1198,8 +1223,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Switch to ThreadPool thread
await TaskScheduler.Default;
- if (_updateSource.Token.IsCancellationRequested)
- return;
+ if (_updateSource.Token.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
@@ -1209,19 +1233,35 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
_lastQuery = query;
- if (string.IsNullOrEmpty(query.ActionKeyword))
+ var plugins = PluginManager.ValidPluginsForQuery(query);
+
+ if (plugins.Count == 1)
+ {
+ PluginIconPath = plugins.Single().Metadata.IcoPath;
+ PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
+ SearchIconVisibility = Visibility.Hidden;
+ }
+ else
+ {
+ PluginIconPath = null;
+ PluginIconSource = null;
+ SearchIconVisibility = Visibility.Visible;
+ }
+
+ // Do not wait for performance improvement
+ /*if (string.IsNullOrEmpty(query.ActionKeyword))
{
// Wait 15 millisecond for query change in global query
// if query changes, return so that it won't be calculated
await Task.Delay(15, _updateSource.Token);
if (_updateSource.Token.IsCancellationRequested)
return;
- }
+ }*/
_ = Task.Delay(200, _updateSource.Token).ContinueWith(_ =>
{
// start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
- if (!_updateSource.Token.IsCancellationRequested && _isQueryRunning)
+ if (_isQueryRunning)
{
ProgressBarVisibility = Visibility.Visible;
}
@@ -1248,12 +1288,12 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// nothing to do here
}
- if (_updateSource.Token.IsCancellationRequested)
- return;
+ if (_updateSource.Token.IsCancellationRequested) return;
// this should happen once after all queries are done so progress bar should continue
// until the end of all querying
_isQueryRunning = false;
+
if (!_updateSource.Token.IsCancellationRequested)
{
// update to hidden if this is still the current query
@@ -1269,8 +1309,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
await Task.Delay(searchDelayTime, token);
- if (token.IsCancellationRequested)
- return;
+ if (token.IsCancellationRequested) return;
}
// Since it is wrapped within a ThreadPool Thread, the synchronous context is null
@@ -1279,8 +1318,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
- if (token.IsCancellationRequested)
- return;
+ if (token.IsCancellationRequested) return;
IReadOnlyList resultsCopy;
if (results == null)
@@ -1301,6 +1339,8 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
}
}
+ if (token.IsCancellationRequested) return;
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect)))
{
@@ -1309,16 +1349,16 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
}
}
- private Query ConstructQuery(string queryText, IEnumerable customShortcuts,
- IEnumerable builtInShortcuts)
+ private async Task ConstructQueryAsync(string queryText, IEnumerable customShortcuts,
+ IEnumerable builtInShortcuts)
{
if (string.IsNullOrWhiteSpace(queryText))
{
return null;
}
- StringBuilder queryBuilder = new(queryText);
- StringBuilder queryBuilderTmp = new(queryText);
+ var queryBuilder = new StringBuilder(queryText);
+ var queryBuilderTmp = new StringBuilder(queryText);
// Sorting order is important here, the reason is for matching longest shortcut by default
foreach (var shortcut in customShortcuts.OrderByDescending(x => x.Key.Length))
@@ -1331,36 +1371,56 @@ private Query ConstructQuery(string queryText, IEnumerable
queryBuilder.Replace('@' + shortcut.Key, shortcut.Expand());
}
- string customExpanded = queryBuilder.ToString();
+ // Applying builtin shortcuts
+ await BuildQueryAsync(builtInShortcuts, queryBuilder, queryBuilderTmp);
+
+ return QueryBuilder.Build(queryBuilder.ToString().Trim(), PluginManager.NonGlobalPlugins);
+ }
+
+ private async Task BuildQueryAsync(IEnumerable builtInShortcuts,
+ StringBuilder queryBuilder, StringBuilder queryBuilderTmp)
+ {
+ var customExpanded = queryBuilder.ToString();
+
+ var queryChanged = false;
- Application.Current.Dispatcher.Invoke(() =>
+ foreach (var shortcut in builtInShortcuts)
{
- foreach (var shortcut in builtInShortcuts)
+ try
{
- try
+ if (customExpanded.Contains(shortcut.Key))
{
- if (customExpanded.Contains(shortcut.Key))
+ string expansion;
+ if (shortcut is BuiltinShortcutModel syncShortcut)
{
- var expansion = shortcut.Expand();
- queryBuilder.Replace(shortcut.Key, expansion);
- queryBuilderTmp.Replace(shortcut.Key, expansion);
+ expansion = syncShortcut.Expand();
}
- }
- catch (Exception e)
- {
- App.API.LogException(ClassName,
- $"Error when expanding shortcut {shortcut.Key}",
- e);
+ else if (shortcut is AsyncBuiltinShortcutModel asyncShortcut)
+ {
+ expansion = await asyncShortcut.ExpandAsync();
+ }
+ else
+ {
+ continue;
+ }
+ queryBuilder.Replace(shortcut.Key, expansion);
+ queryBuilderTmp.Replace(shortcut.Key, expansion);
+ queryChanged = true;
}
}
- });
-
- // show expanded builtin shortcuts
- // use private field to avoid infinite recursion
- _queryText = queryBuilderTmp.ToString();
+ catch (Exception e)
+ {
+ App.API.LogException(ClassName, $"Error when expanding shortcut {shortcut.Key}", e);
+ }
+ }
- var query = QueryBuilder.Build(queryBuilder.ToString().Trim(), PluginManager.NonGlobalPlugins);
- return query;
+ if (queryChanged)
+ {
+ // show expanded builtin shortcuts
+ // use private field to avoid infinite recursion
+ _queryText = queryBuilderTmp.ToString();
+ OnPropertyChanged(nameof(QueryText));
+ }
}
private void RemoveOldQueryResults(Query query)
@@ -1489,6 +1549,9 @@ public bool ShouldIgnoreHotkeys()
public void Show()
{
+ // When application is exiting, we should not show the main window
+ if (App.Exiting) return;
+
// When application is exiting, the Application.Current will be null
Application.Current?.Dispatcher.Invoke(() =>
{
From 62e1252ac4a01aff2f2244182092887373282f87 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 14:37:10 +0800
Subject: [PATCH 1155/1335] Use BackToQueryResults for code quality
---
Flow.Launcher/ViewModel/MainViewModel.cs | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2f1ed0f5103..2526adef83b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1170,7 +1170,7 @@ private void QueryHistory()
OriginQuery = new Query { RawQuery = h.Query },
Action = _ =>
{
- SelectedResults = Results;
+ App.API.BackToQueryResults();
App.API.ChangeQuery(h.Query);
return false;
}
@@ -1600,10 +1600,7 @@ public async void Hide()
await CloseExternalPreviewAsync();
}
- if (!QueryResultsSelected())
- {
- SelectedResults = Results;
- }
+ BackToQueryResults();
switch (Settings.LastQueryMode)
{
From b1197858de49abc6c4583085b6124c462f82cfd0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 14:40:18 +0800
Subject: [PATCH 1156/1335] Do not query when back from the context menu
---
Flow.Launcher/ViewModel/MainViewModel.cs | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2526adef83b..f0513c7d9ab 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -34,6 +34,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private bool _isQueryRunning;
private Query _lastQuery;
private string _queryTextBeforeLeaveResults;
+ private string _ignoredQueryText = null;
private readonly FlowLauncherJsonStorage _historyItemsStorage;
private readonly FlowLauncherJsonStorage _userSelectedRecordStorage;
@@ -730,6 +731,9 @@ private ResultsViewModel SelectedResults
if (isReturningFromContextMenu)
{
_queryText = _queryTextBeforeLeaveResults;
+ // When executing OnPropertyChanged, QueryTextBox_TextChanged1 and Query will be called
+ // So we need to ignore it so that we will not call Query again
+ _ignoredQueryText = _queryText;
OnPropertyChanged(nameof(QueryText));
QueryTextCursorMovedToEnd = true;
}
@@ -1076,6 +1080,20 @@ private bool QueryResultsPreviewed()
public void Query(bool searchDelay, bool isReQuery = false)
{
+ if (_ignoredQueryText != null)
+ {
+ if (_ignoredQueryText == QueryText)
+ {
+ _ignoredQueryText = null;
+ return;
+ }
+ else
+ {
+ // If _ignoredQueryText does not match current QueryText, we should still execute Query
+ _ignoredQueryText = null;
+ }
+ }
+
if (QueryResultsSelected())
{
_ = QueryResultsAsync(searchDelay, isReQuery);
From f935d5f078dc414b72375cfa5d01e28e75033a24 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 15:06:20 +0800
Subject: [PATCH 1157/1335] Improve code comments
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f0513c7d9ab..607b70fd23a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1432,10 +1432,10 @@ private async Task BuildQueryAsync(IEnumerable builtIn
}
}
+ // Show expanded builtin shortcuts
if (queryChanged)
{
- // show expanded builtin shortcuts
- // use private field to avoid infinite recursion
+ // Use private field to avoid infinite recursion
_queryText = queryBuilderTmp.ToString();
OnPropertyChanged(nameof(QueryText));
}
From 247272c9aa7a986395a14beab3d6a5b2e22e4b75 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 2 May 2025 15:21:17 +0800
Subject: [PATCH 1158/1335] Do not query when expanding builtin shortcuts
---
Flow.Launcher/ViewModel/MainViewModel.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 607b70fd23a..c505c32a3c9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1437,6 +1437,9 @@ private async Task BuildQueryAsync(IEnumerable builtIn
{
// Use private field to avoid infinite recursion
_queryText = queryBuilderTmp.ToString();
+ // When executing OnPropertyChanged, QueryTextBox_TextChanged1 and Query will be called
+ // So we need to ignore it so that we will not call Query again
+ _ignoredQueryText = _queryText;
OnPropertyChanged(nameof(QueryText));
}
}
From aa0f9b2e73c550964475f4b0e2454c3c5728ecb7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 08:58:40 +0800
Subject: [PATCH 1159/1335] Update name
---
.../{IAsyncEmptyQuery.cs => IAsyncHomeQuery.cs} | 6 +++---
.../Interfaces/{IEmptyQuery.cs => IHomeQuery.cs} | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
rename Flow.Launcher.Plugin/Interfaces/{IAsyncEmptyQuery.cs => IAsyncHomeQuery.cs} (79%)
rename Flow.Launcher.Plugin/Interfaces/{IEmptyQuery.cs => IHomeQuery.cs} (72%)
diff --git a/Flow.Launcher.Plugin/Interfaces/IAsyncEmptyQuery.cs b/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
similarity index 79%
rename from Flow.Launcher.Plugin/Interfaces/IAsyncEmptyQuery.cs
rename to Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
index a18f0848d8d..f7a820f18c6 100644
--- a/Flow.Launcher.Plugin/Interfaces/IAsyncEmptyQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
@@ -7,17 +7,17 @@ namespace Flow.Launcher.Plugin
///
/// Asynchronous Query Model for Flow Launcher When Query Text is Empty
///
- public interface IAsyncEmptyQuery
+ public interface IAsyncHomeQuery
{
///
/// Asynchronous Querying When Query Text is Empty
///
///
/// If the Querying method requires high IO transmission
- /// or performing CPU intense jobs (performing better with cancellation), please use this IAsyncEmptyQuery interface
+ /// or performing CPU intense jobs (performing better with cancellation), please use this IAsyncHomeQuery interface
///
/// Cancel when querying job is obsolete
///
- Task> EmptyQueryAsync(CancellationToken token);
+ Task> HomeQueryAsync(CancellationToken token);
}
}
diff --git a/Flow.Launcher.Plugin/Interfaces/IEmptyQuery.cs b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
similarity index 72%
rename from Flow.Launcher.Plugin/Interfaces/IEmptyQuery.cs
rename to Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
index 4ebdcf1fdcb..f3c9cfcad97 100644
--- a/Flow.Launcher.Plugin/Interfaces/IEmptyQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
@@ -8,10 +8,10 @@ namespace Flow.Launcher.Plugin
/// Synchronous Query Model for Flow Launcher When Query Text is Empty
///
/// If the Querying method requires high IO transmission
- /// or performaing CPU intense jobs (performing better with cancellation), please try the IAsyncEmptyQuery interface
+ /// or performaing CPU intense jobs (performing better with cancellation), please try the IAsyncHomeQuery interface
///
///
- public interface IEmptyQuery : IAsyncEmptyQuery
+ public interface IHomeQuery : IAsyncHomeQuery
{
///
/// Querying When Query Text is Empty
@@ -21,8 +21,8 @@ public interface IEmptyQuery : IAsyncEmptyQuery
///
///
///
- List EmptyQuery();
+ List HomeQuery();
- Task> IAsyncEmptyQuery.EmptyQueryAsync(CancellationToken token) => Task.Run(EmptyQuery);
+ Task> IAsyncHomeQuery.HomeQueryAsync(CancellationToken token) => Task.Run(HomeQuery);
}
}
From 3089928599fca94487b21dbeff5fa35609e43463 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 16:31:49 +0800
Subject: [PATCH 1160/1335] Support home query interface
---
.../Main.cs | 20 +++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
index 05e8d960fb0..48717816b0d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Main.cs
@@ -3,21 +3,33 @@
namespace Flow.Launcher.Plugin.PluginIndicator
{
- public class Main : IPlugin, IPluginI18n
+ public class Main : IPlugin, IPluginI18n, IHomeQuery
{
internal PluginInitContext Context { get; private set; }
public List Query(Query query)
+ {
+ return QueryResults(query);
+ }
+
+ public List HomeQuery()
+ {
+ return QueryResults();
+ }
+
+ private List QueryResults(Query query = null)
{
var nonGlobalPlugins = GetNonGlobalPlugins();
+ var querySearch = query?.Search ?? string.Empty;
+
var results =
from keyword in nonGlobalPlugins.Keys
let plugin = nonGlobalPlugins[keyword].Metadata
- let keywordSearchResult = Context.API.FuzzySearch(query.Search, keyword)
- let searchResult = keywordSearchResult.IsSearchPrecisionScoreMet() ? keywordSearchResult : Context.API.FuzzySearch(query.Search, plugin.Name)
+ let keywordSearchResult = Context.API.FuzzySearch(querySearch, keyword)
+ let searchResult = keywordSearchResult.IsSearchPrecisionScoreMet() ? keywordSearchResult : Context.API.FuzzySearch(querySearch, plugin.Name)
let score = searchResult.Score
where (searchResult.IsSearchPrecisionScoreMet()
- || string.IsNullOrEmpty(query.Search)) // To list all available action keywords
+ || string.IsNullOrEmpty(querySearch)) // To list all available action keywords
&& !plugin.Disabled
select new Result
{
From 0f09fea30b28526d72088e9c6603dfacf614e725 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 16:32:07 +0800
Subject: [PATCH 1161/1335] Make async home query to be feature interface
---
Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs b/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
index f7a820f18c6..78d6454ae5f 100644
--- a/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IAsyncHomeQuery.cs
@@ -7,7 +7,7 @@ namespace Flow.Launcher.Plugin
///
/// Asynchronous Query Model for Flow Launcher When Query Text is Empty
///
- public interface IAsyncHomeQuery
+ public interface IAsyncHomeQuery : IFeatures
{
///
/// Asynchronous Querying When Query Text is Empty
From 17a0834bcda4ba856179543f152a04c987ff9c1c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 16:50:50 +0800
Subject: [PATCH 1162/1335] Support query for plugins with home query interface
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 51 ++++++++++++++
.../UserSettings/Settings.cs | 5 ++
Flow.Launcher.Plugin/Result.cs | 3 +
Flow.Launcher/ViewModel/MainViewModel.cs | 68 ++++++++++++-------
4 files changed, 104 insertions(+), 23 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 72303c8b754..b0f8962145f 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -25,6 +25,7 @@ public static class PluginManager
private static readonly string ClassName = nameof(PluginManager);
private static IEnumerable _contextMenuPlugins;
+ private static IEnumerable _homePlugins;
public static List AllPlugins { get; private set; }
public static readonly HashSet GlobalPlugins = new();
@@ -227,6 +228,8 @@ public static async Task InitializePluginsAsync()
await Task.WhenAll(InitTasks);
_contextMenuPlugins = GetPluginsForInterface();
+ _homePlugins = GetPluginsForInterface();
+
foreach (var plugin in AllPlugins)
{
// set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
@@ -274,6 +277,14 @@ public static ICollection ValidPluginsForQuery(Query query)
};
}
+ public static ICollection ValidPluginsForHomeQuery(Query query)
+ {
+ if (query is not null)
+ return Array.Empty();
+
+ return _homePlugins.ToList();
+ }
+
public static async Task> QueryForPluginAsync(PluginPair pair, Query query, CancellationToken token)
{
var results = new List();
@@ -318,6 +329,36 @@ public static async Task> QueryForPluginAsync(PluginPair pair, Quer
return results;
}
+ public static async Task> QueryHomeForPluginAsync(PluginPair pair, CancellationToken token)
+ {
+ var results = new List();
+ var metadata = pair.Metadata;
+
+ try
+ {
+ var milliseconds = await API.StopwatchLogDebugAsync(ClassName, $"Cost for {metadata.Name}",
+ async () => results = await ((IAsyncHomeQuery)pair.Plugin).HomeQueryAsync(token).ConfigureAwait(false));
+
+ token.ThrowIfCancellationRequested();
+ if (results == null)
+ return null;
+ UpdatePluginMetadata(results, metadata);
+
+ token.ThrowIfCancellationRequested();
+ }
+ catch (OperationCanceledException)
+ {
+ // null will be fine since the results will only be added into queue if the token hasn't been cancelled
+ return null;
+ }
+ catch (Exception e)
+ {
+ API.LogException(ClassName, $"Failed to query home for plugin: {metadata.Name}", e);
+ return null;
+ }
+ return results;
+ }
+
public static void UpdatePluginMetadata(IReadOnlyList results, PluginMetadata metadata, Query query)
{
foreach (var r in results)
@@ -333,6 +374,16 @@ public static void UpdatePluginMetadata(IReadOnlyList results, PluginMet
}
}
+ private static void UpdatePluginMetadata(IReadOnlyList results, PluginMetadata metadata)
+ {
+ foreach (var r in results)
+ {
+ r.PluginDirectory = metadata.PluginDirectory;
+ r.PluginID = metadata.ID;
+ r.OriginQuery = null;
+ }
+ }
+
///
/// get specified plugin, return null if not found
///
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index b7a1d1f6367..2b5fc6bc0d4 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -158,6 +158,11 @@ public string PlaceholderText
}
}
}
+
+ public bool ShowHomeQuery { get; set; } = true;
+ public bool ShowHistoryRecordsForHomeQuery { get; set; } = false;
+ public int HistoryRecordsCountForHomeQuery { get; set; } = 5;
+
public int CustomExplorerIndex { get; set; } = 0;
[JsonIgnore]
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index f0fcd48ffc0..060c0331729 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -174,6 +174,9 @@ public string BadgeIcoPath
///
/// Query information associated with the result
///
+ ///
+ /// If the query is for home query, this will be null
+ ///
internal Query OriginQuery { get; set; }
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 2f1ed0f5103..b5afe4b7ed9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1198,21 +1198,31 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
_updateSource?.Cancel();
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
+ var homeQuery = query == null;
+ ICollection plugins = Array.Empty();
if (query == null) // shortcut expanded
{
- // Hide and clear results again because running query may show and add some results
- Results.Visibility = Visibility.Collapsed;
- Results.Clear();
+ if (Settings.ShowHomeQuery)
+ {
+ plugins = PluginManager.ValidPluginsForHomeQuery(query);
+ }
+
+ if (plugins.Count == 0)
+ {
+ // Hide and clear results again because running query may show and add some results
+ Results.Visibility = Visibility.Collapsed;
+ Results.Clear();
- // Reset plugin icon
- PluginIconPath = null;
- PluginIconSource = null;
- SearchIconVisibility = Visibility.Visible;
+ // Reset plugin icon
+ PluginIconPath = null;
+ PluginIconSource = null;
+ SearchIconVisibility = Visibility.Visible;
- // Hide progress bar again because running query may set this to visible
- ProgressBarVisibility = Visibility.Hidden;
- return;
+ // Hide progress bar again because running query may set this to visible
+ ProgressBarVisibility = Visibility.Hidden;
+ return;
+ }
}
_updateSource = new CancellationTokenSource();
@@ -1226,27 +1236,37 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
if (_updateSource.Token.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query
- query.IsReQuery = isReQuery;
+ if (!homeQuery) query.IsReQuery = isReQuery;
// handle the exclusiveness of plugin using action keyword
RemoveOldQueryResults(query);
_lastQuery = query;
- var plugins = PluginManager.ValidPluginsForQuery(query);
-
- if (plugins.Count == 1)
- {
- PluginIconPath = plugins.Single().Metadata.IcoPath;
- PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
- SearchIconVisibility = Visibility.Hidden;
- }
- else
+ if (homeQuery)
{
+ // Do not show plugin icon if this is a home query
PluginIconPath = null;
PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
}
+ else
+ {
+ plugins = PluginManager.ValidPluginsForQuery(query);
+
+ if (plugins.Count == 1)
+ {
+ PluginIconPath = plugins.Single().Metadata.IcoPath;
+ PluginIconSource = await App.API.LoadImageAsync(PluginIconPath);
+ SearchIconVisibility = Visibility.Hidden;
+ }
+ else
+ {
+ PluginIconPath = null;
+ PluginIconSource = null;
+ SearchIconVisibility = Visibility.Visible;
+ }
+ }
// Do not wait for performance improvement
/*if (string.IsNullOrEmpty(query.ActionKeyword))
@@ -1303,7 +1323,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Local function
async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
- if (searchDelay)
+ if (searchDelay && !homeQuery) // Do not delay for home query
{
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
@@ -1316,7 +1336,9 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
// Task.Yield will force it to run in ThreadPool
await Task.Yield();
- var results = await PluginManager.QueryForPluginAsync(plugin, query, token);
+ var results = homeQuery ?
+ await PluginManager.QueryHomeForPluginAsync(plugin, token) :
+ await PluginManager.QueryForPluginAsync(plugin, query, token);
if (token.IsCancellationRequested) return;
@@ -1616,7 +1638,7 @@ public async void Hide()
break;
case LastQueryMode.ActionKeywordPreserved:
case LastQueryMode.ActionKeywordSelected:
- var newQuery = _lastQuery.ActionKeyword;
+ var newQuery = _lastQuery?.ActionKeyword;
if (!string.IsNullOrEmpty(newQuery))
newQuery += " ";
From 54994ddb7b264c51452e13dac7f7306b9fc44f41 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 17:02:39 +0800
Subject: [PATCH 1163/1335] Initialize home query when window is loaded
---
Flow.Launcher/MainWindow.xaml.cs | 3 +++
Flow.Launcher/ViewModel/MainViewModel.cs | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index ae7b098a206..546f32cc5fa 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -292,6 +292,9 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
DependencyPropertyDescriptor
.FromProperty(VisibilityProperty, typeof(StackPanel))
.AddValueChanged(History, (s, e) => UpdateClockPanelVisibility());
+
+ // Initialize query state
+ _viewModel.InitializeQuery();
}
private async void OnClosing(object sender, CancelEventArgs e)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index b5afe4b7ed9..8244d5765ee 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1074,6 +1074,14 @@ private bool QueryResultsPreviewed()
#region Query
+ public void InitializeQuery()
+ {
+ if (Settings.ShowHomeQuery)
+ {
+ _ = QueryResultsAsync(false);
+ }
+ }
+
public void Query(bool searchDelay, bool isReQuery = false)
{
if (QueryResultsSelected())
From e9ef26a8dde26530f21e0ce244c0e03e9cf8d60b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 18:17:00 +0800
Subject: [PATCH 1164/1335] Change related setting names
---
Flow.Launcher.Infrastructure/UserSettings/Settings.cs | 6 +++---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 2b5fc6bc0d4..b630a4ecc7c 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -159,9 +159,9 @@ public string PlaceholderText
}
}
- public bool ShowHomeQuery { get; set; } = true;
- public bool ShowHistoryRecordsForHomeQuery { get; set; } = false;
- public int HistoryRecordsCountForHomeQuery { get; set; } = 5;
+ public bool ShowHomePage { get; set; } = true;
+ public bool ShowHistoryResultsForHomePage { get; set; } = false;
+ public int MaxHistoryResultsToShowForHomePage { get; set; } = 5;
public int CustomExplorerIndex { get; set; } = 0;
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8244d5765ee..06cce302611 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1076,7 +1076,7 @@ private bool QueryResultsPreviewed()
public void InitializeQuery()
{
- if (Settings.ShowHomeQuery)
+ if (Settings.ShowHomePage)
{
_ = QueryResultsAsync(false);
}
@@ -1211,7 +1211,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
if (query == null) // shortcut expanded
{
- if (Settings.ShowHomeQuery)
+ if (Settings.ShowHomePage)
{
plugins = PluginManager.ValidPluginsForHomeQuery(query);
}
From e8333331b0a348c9ba2eceb995943faea21130d0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 18:17:07 +0800
Subject: [PATCH 1165/1335] Add ui in general page
---
Flow.Launcher/Languages/en.xaml | 4 ++
.../SettingsPaneGeneralViewModel.cs | 15 +++++-
.../Views/SettingsPaneGeneral.xaml | 51 +++++++++++++++----
3 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index ca0ed33b514..af718946db0 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -126,6 +126,10 @@
Open
Use Previous Korean IME
You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
Search Plugin
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
index 1a887c4b7f3..840269b037e 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
@@ -154,11 +154,22 @@ public int SearchDelayTimeValue
{
Settings.SearchDelayTime = value;
OnPropertyChanged();
- OnPropertyChanged(nameof(SearchDelayTimeDisplay));
}
}
}
- public string SearchDelayTimeDisplay => $"{SearchDelayTimeValue}ms";
+
+ public int MaxHistoryResultsToShowValue
+ {
+ get => Settings.MaxHistoryResultsToShowForHomePage;
+ set
+ {
+ if (Settings.MaxHistoryResultsToShowForHomePage != value)
+ {
+ Settings.MaxHistoryResultsToShowForHomePage = value;
+ OnPropertyChanged();
+ }
+ }
+ }
private void UpdateEnumDropdownLocalizations()
{
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
index d45d28d8bba..c0c5613de04 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
@@ -217,17 +217,46 @@
Title="{DynamicResource searchDelayTime}"
Sub="{DynamicResource searchDelayTimeToolTip}"
Type="InsideFit">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From d6704ed5da47077b0751176d0e3185fb77ef320b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 22:09:25 +0800
Subject: [PATCH 1166/1335] Support history items
---
Flow.Launcher/ViewModel/MainViewModel.cs | 81 ++++++++++++++++++++++--
1 file changed, 77 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 06cce302611..d850e0f7c41 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -50,6 +50,12 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly IReadOnlyList _emptyResult = new List();
+ private readonly PluginMetadata _historyMetadata = new()
+ {
+ ID = "298303A65D128A845D28A7B83B3968C2",
+ Priority = 0
+ };
+
#endregion
#region Constructor
@@ -1300,11 +1306,30 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// plugins are ICollection, meaning LINQ will get the Count and preallocate Array
- var tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
+ Task[] tasks;
+ if (homeQuery)
{
- false => QueryTaskAsync(plugin, _updateSource.Token),
- true => Task.CompletedTask
- }).ToArray();
+ var homeTasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
+ {
+ false => QueryTaskAsync(plugin, _updateSource.Token),
+ true => Task.CompletedTask
+ }).ToList();
+
+ if (Settings.ShowHistoryResultsForHomePage)
+ {
+ homeTasks.Add(QueryHistoryTaskAsync());
+ }
+
+ tasks = homeTasks.ToArray();
+ }
+ else
+ {
+ tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
+ {
+ false => QueryTaskAsync(plugin, _updateSource.Token),
+ true => Task.CompletedTask
+ }).ToArray();
+ }
try
{
@@ -1377,6 +1402,54 @@ await PluginManager.QueryHomeForPluginAsync(plugin, token) :
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
}
+
+ async Task QueryHistoryTaskAsync()
+ {
+ // Since it is wrapped within a ThreadPool Thread, the synchronous context is null
+ // Task.Yield will force it to run in ThreadPool
+ await Task.Yield();
+
+ // Select last history results and revert its order to make sure last history results are on top
+ var lastHistoryResults = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
+
+ var historyResults = new List();
+ foreach (var h in lastHistoryResults)
+ {
+ var title = App.API.GetTranslation("executeQuery");
+ var time = App.API.GetTranslation("lastExecuteTime");
+ var result = new Result
+ {
+ Title = string.Format(title, h.Query),
+ SubTitle = string.Format(time, h.ExecutedDateTime),
+ IcoPath = "Images\\history.png",
+ Preview = new Result.PreviewInfo
+ {
+ PreviewImagePath = Constant.HistoryIcon,
+ Description = string.Format(time, h.ExecutedDateTime)
+ },
+ OriginQuery = new Query { RawQuery = h.Query },
+ Action = _ =>
+ {
+ SelectedResults = Results;
+ App.API.ChangeQuery(h.Query);
+ return false;
+ }
+ };
+ historyResults.Add(result);
+ }
+
+ // No need to make copy of results and update badge ico property
+
+ if (_updateSource.Token.IsCancellationRequested) return;
+
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(historyResults, _historyMetadata, query,
+ _updateSource.Token)))
+ {
+ App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
+ }
+
+ await Task.CompletedTask;
+ }
}
private async Task ConstructQueryAsync(string queryText, IEnumerable customShortcuts,
From f2f4ebf0ac641eb1feafdb7f0f8feccabbd6d283 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 22:34:58 +0800
Subject: [PATCH 1167/1335] Support home state change & Add ui
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 6 +++
.../UserSettings/PluginSettings.cs | 3 ++
Flow.Launcher.Plugin/PluginMetadata.cs | 5 +++
Flow.Launcher/Languages/en.xaml | 6 +++
.../Controls/InstalledPluginDisplay.xaml | 11 +++++-
.../SettingsPanePluginsViewModel.cs | 38 ++++++++++++++++++-
Flow.Launcher/ViewModel/PluginViewModel.cs | 11 ++++++
7 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index b0f8962145f..caa3fd00b13 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -221,6 +221,7 @@ public static async Task InitializePluginsAsync()
{
API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
pair.Metadata.Disabled = true;
+ pair.Metadata.HomeDisabled = true;
failedPlugins.Enqueue(pair);
}
}));
@@ -429,6 +430,11 @@ public static List GetContextMenusForPlugin(Result result)
return results;
}
+ public static bool IsHomePlugin(string id)
+ {
+ return _homePlugins.Any(p => p.Metadata.ID == id);
+ }
+
public static bool ActionKeywordRegistered(string actionKeyword)
{
// this method is only checking for action keywords (defined as not '*') registration
diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
index 7fb9b895a24..837d0ebb61b 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -67,6 +67,7 @@ public void UpdatePluginSettings(List metadatas)
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
metadata.SearchDelayTime = settings.SearchDelayTime;
+ metadata.HomeDisabled = settings.HomeDiabled;
}
else
{
@@ -79,6 +80,7 @@ public void UpdatePluginSettings(List metadatas)
DefaultActionKeywords = metadata.ActionKeywords, // metadata provides default values
ActionKeywords = metadata.ActionKeywords, // use default value
Disabled = metadata.Disabled,
+ HomeDiabled = metadata.HomeDisabled,
Priority = metadata.Priority,
DefaultSearchDelayTime = metadata.SearchDelayTime, // metadata provides default values
SearchDelayTime = metadata.SearchDelayTime, // use default value
@@ -128,5 +130,6 @@ public class Plugin
/// Used only to save the state of the plugin in settings
///
public bool Disabled { get; set; }
+ public bool HomeDiabled { get; set; }
}
}
diff --git a/Flow.Launcher.Plugin/PluginMetadata.cs b/Flow.Launcher.Plugin/PluginMetadata.cs
index da10bc6a504..09803cbd7cc 100644
--- a/Flow.Launcher.Plugin/PluginMetadata.cs
+++ b/Flow.Launcher.Plugin/PluginMetadata.cs
@@ -50,6 +50,11 @@ public class PluginMetadata : BaseModel
///
public bool Disabled { get; set; }
+ ///
+ /// Whether plugin is disabled in home query.
+ ///
+ public bool HomeDisabled { get; set; }
+
///
/// Plugin execute file path.
///
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index af718946db0..22ab2016cc0 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -130,6 +130,7 @@
Show home page results when query text is empty.
Show History Results in Home Page
Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -152,6 +153,7 @@
Enabled
Priority
Search Delay
+ Home Page
Current Priority
New Priority
Priority
@@ -405,6 +407,10 @@
Search Delay Time Setting
Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
+
Custom Query Hotkey
Press a custom hotkey to open Flow Launcher and input the specified query automatically.
diff --git a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
index 619da22dc64..0842a64f345 100644
--- a/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
+++ b/Flow.Launcher/Resources/Controls/InstalledPluginDisplay.xaml
@@ -100,10 +100,19 @@
ToolTipService.InitialShowDelay="0"
ToolTipService.ShowOnDisabled="True"
Value="{Binding PluginSearchDelayTime, Mode=TwoWay}" />
-
+
+
_isHomeOnOffSelected;
+ set
+ {
+ if (_isHomeOnOffSelected != value)
+ {
+ _isHomeOnOffSelected = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public SettingsPanePluginsViewModel(Settings settings)
{
_settings = settings;
@@ -152,6 +166,18 @@ private async Task OpenHelperAsync(Button button)
{
Text = (string)Application.Current.Resources["searchDelayTimeTips"],
TextWrapping = TextWrapping.Wrap
+ },
+ new TextBlock
+ {
+ Text = (string)Application.Current.Resources["homeTitle"],
+ FontSize = 18,
+ Margin = new Thickness(0, 24, 0, 10),
+ TextWrapping = TextWrapping.Wrap
+ },
+ new TextBlock
+ {
+ Text = (string)Application.Current.Resources["homeTips"],
+ TextWrapping = TextWrapping.Wrap
}
}
},
@@ -176,16 +202,25 @@ private void UpdateDisplayModeFromSelection()
IsOnOffSelected = false;
IsPrioritySelected = true;
IsSearchDelaySelected = false;
+ IsHomeOnOffSelected = false;
break;
case DisplayMode.SearchDelay:
IsOnOffSelected = false;
IsPrioritySelected = false;
IsSearchDelaySelected = true;
+ IsHomeOnOffSelected = false;
+ break;
+ case DisplayMode.HomeOnOff:
+ IsOnOffSelected = false;
+ IsPrioritySelected = false;
+ IsSearchDelaySelected = false;
+ IsHomeOnOffSelected = true;
break;
default:
IsOnOffSelected = true;
IsPrioritySelected = false;
IsSearchDelaySelected = false;
+ IsHomeOnOffSelected = false;
break;
}
}
@@ -195,5 +230,6 @@ public enum DisplayMode
{
OnOff,
Priority,
- SearchDelay
+ SearchDelay,
+ HomeOnOff
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 64a7f3db84e..09289601905 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -75,6 +75,16 @@ public bool PluginState
}
}
+ public bool PluginHomeState
+ {
+ get => !PluginPair.Metadata.HomeDisabled;
+ set
+ {
+ PluginPair.Metadata.HomeDisabled = !value;
+ PluginSettingsObject.HomeDiabled = !value;
+ }
+ }
+
public bool IsExpanded
{
get => _isExpanded;
@@ -154,6 +164,7 @@ public Control SettingControl
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public bool SearchDelayEnabled => Settings.SearchQueryResultsWithDelay;
public string DefaultSearchDelay => Settings.SearchDelayTime.ToString();
+ public bool HomeEnabled => Settings.ShowHomePage && PluginManager.IsHomePlugin(PluginPair.Metadata.ID);
public void OnActionKeywordsTextChanged()
{
From 96bb62af27932df8e0afab3940ffc97cda28d349 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 May 2025 22:54:46 +0800
Subject: [PATCH 1168/1335] Refresh interface when Home Page is changed
---
.../UserSettings/Settings.cs | 15 ++++++++++++++-
Flow.Launcher/MainWindow.xaml.cs | 16 +++++++++++++++-
Flow.Launcher/ViewModel/MainViewModel.cs | 7 ++-----
Flow.Launcher/ViewModel/PluginViewModel.cs | 3 +++
4 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index b630a4ecc7c..34bf4f90e5c 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -159,7 +159,20 @@ public string PlaceholderText
}
}
- public bool ShowHomePage { get; set; } = true;
+ private bool _showHomePage { get; set; } = true;
+ public bool ShowHomePage
+ {
+ get => _showHomePage;
+ set
+ {
+ if (_showHomePage != value)
+ {
+ _showHomePage = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public bool ShowHistoryResultsForHomePage { get; set; } = false;
public int MaxHistoryResultsToShowForHomePage { get; set; } = 5;
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 546f32cc5fa..6dcd8d22dcd 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -277,6 +277,17 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
case nameof(Settings.SettingWindowFont):
InitializeContextMenu();
break;
+ case nameof(Settings.ShowHomePage):
+ // We should refresh results when these two settings are changed but we cannot do that
+ // Because the order of the results will change, making the interface look weird
+ // So we would better refresh results when query text is changed next time
+ /*case nameof(Settings.ShowHistoryResultsForHomePage):
+ case nameof(Settings.MaxHistoryResultsToShowForHomePage):*/
+ if (string.IsNullOrEmpty(_viewModel.QueryText))
+ {
+ _viewModel.QueryResults();
+ }
+ break;
}
};
@@ -294,7 +305,10 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
.AddValueChanged(History, (s, e) => UpdateClockPanelVisibility());
// Initialize query state
- _viewModel.InitializeQuery();
+ if (_settings.ShowHomePage && string.IsNullOrEmpty(_viewModel.QueryText))
+ {
+ _viewModel.QueryResults();
+ }
}
private async void OnClosing(object sender, CancelEventArgs e)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index d850e0f7c41..993cc3ba9b2 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1080,12 +1080,9 @@ private bool QueryResultsPreviewed()
#region Query
- public void InitializeQuery()
+ public void QueryResults()
{
- if (Settings.ShowHomePage)
- {
- _ = QueryResultsAsync(false);
- }
+ _ = QueryResultsAsync(false);
}
public void Query(bool searchDelay, bool isReQuery = false)
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 09289601905..61f6dea33da 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -82,6 +82,9 @@ public bool PluginHomeState
{
PluginPair.Metadata.HomeDisabled = !value;
PluginSettingsObject.HomeDiabled = !value;
+ // We should refresh results when these two settings are changed but we cannot do that
+ // Because the order of the results will change, making the interface look weird
+ // So we would better refresh results when query text is changed next time
}
}
From 13cfbe54306d5eabe76d4f0e3f89c979e69a5f11 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 09:07:14 +0800
Subject: [PATCH 1169/1335] Check query results
---
Flow.Launcher/MainWindow.xaml.cs | 7 +------
Flow.Launcher/ViewModel/PluginViewModel.cs | 3 ---
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 6dcd8d22dcd..e2948c54043 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -278,12 +278,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
InitializeContextMenu();
break;
case nameof(Settings.ShowHomePage):
- // We should refresh results when these two settings are changed but we cannot do that
- // Because the order of the results will change, making the interface look weird
- // So we would better refresh results when query text is changed next time
- /*case nameof(Settings.ShowHistoryResultsForHomePage):
- case nameof(Settings.MaxHistoryResultsToShowForHomePage):*/
- if (string.IsNullOrEmpty(_viewModel.QueryText))
+ if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText))
{
_viewModel.QueryResults();
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 61f6dea33da..09289601905 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -82,9 +82,6 @@ public bool PluginHomeState
{
PluginPair.Metadata.HomeDisabled = !value;
PluginSettingsObject.HomeDiabled = !value;
- // We should refresh results when these two settings are changed but we cannot do that
- // Because the order of the results will change, making the interface look weird
- // So we would better refresh results when query text is changed next time
}
}
From 4500f1deebccad17076628174050a71e95881efa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 09:14:57 +0800
Subject: [PATCH 1170/1335] Fix history items context menu issue
---
Flow.Launcher/ViewModel/MainViewModel.cs | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 993cc3ba9b2..8e708fbc4a8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1127,9 +1127,20 @@ private void QueryContextMenu()
if (selected != null) // SelectedItem returns null if selection is empty.
{
- var results = PluginManager.GetContextMenusForPlugin(selected);
- results.Add(ContextMenuTopMost(selected));
- results.Add(ContextMenuPluginInfo(selected.PluginID));
+ List results;
+ if (selected.PluginID == null) // SelectedItem from history in home page.
+ {
+ results = new()
+ {
+ ContextMenuTopMost(selected)
+ };
+ }
+ else
+ {
+ results = PluginManager.GetContextMenusForPlugin(selected);
+ results.Add(ContextMenuTopMost(selected));
+ results.Add(ContextMenuPluginInfo(selected.PluginID));
+ }
if (!string.IsNullOrEmpty(query))
{
From 19d70592a8f66f5a4f16f3f840019c232865c1a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 09:38:35 +0800
Subject: [PATCH 1171/1335] Add empty & global query for home page
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 5 +--
Flow.Launcher.Core/Plugin/QueryBuilder.cs | 21 +++++++--
Flow.Launcher/ViewModel/MainViewModel.cs | 51 ++++++++++------------
3 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index caa3fd00b13..c2265173877 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -278,11 +278,8 @@ public static ICollection ValidPluginsForQuery(Query query)
};
}
- public static ICollection ValidPluginsForHomeQuery(Query query)
+ public static ICollection ValidPluginsForHomeQuery()
{
- if (query is not null)
- return Array.Empty();
-
return _homePlugins.ToList();
}
diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
index 0ef3f30f5e1..fae821736fb 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -8,10 +8,23 @@ public static class QueryBuilder
{
public static Query Build(string text, Dictionary nonGlobalPlugins)
{
+ // home query
+ if (string.IsNullOrEmpty(text))
+ {
+ return new Query()
+ {
+ Search = string.Empty,
+ RawQuery = string.Empty,
+ SearchTerms = Array.Empty(),
+ ActionKeyword = string.Empty
+ };
+ }
+
// replace multiple white spaces with one white space
var terms = text.Split(Query.TermSeparator, StringSplitOptions.RemoveEmptyEntries);
if (terms.Length == 0)
- { // nothing was typed
+ {
+ // nothing was typed
return null;
}
@@ -21,13 +34,15 @@ public static Query Build(string text, Dictionary nonGlobalP
string[] searchTerms;
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
- { // use non global plugin for query
+ {
+ // use non global plugin for query
actionKeyword = possibleActionKeyword;
search = terms.Length > 1 ? rawQuery[(actionKeyword.Length + 1)..].TrimStart() : string.Empty;
searchTerms = terms[1..];
}
else
- { // non action keyword
+ {
+ // non action keyword
actionKeyword = string.Empty;
search = rawQuery.TrimStart();
searchTerms = terms;
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8e708fbc4a8..517cf5323a6 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1220,31 +1220,21 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
_updateSource?.Cancel();
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
- var homeQuery = query == null;
- ICollection plugins = Array.Empty();
if (query == null) // shortcut expanded
{
- if (Settings.ShowHomePage)
- {
- plugins = PluginManager.ValidPluginsForHomeQuery(query);
- }
-
- if (plugins.Count == 0)
- {
- // Hide and clear results again because running query may show and add some results
- Results.Visibility = Visibility.Collapsed;
- Results.Clear();
+ // Hide and clear results again because running query may show and add some results
+ Results.Visibility = Visibility.Collapsed;
+ Results.Clear();
- // Reset plugin icon
- PluginIconPath = null;
- PluginIconSource = null;
- SearchIconVisibility = Visibility.Visible;
+ // Reset plugin icon
+ PluginIconPath = null;
+ PluginIconSource = null;
+ SearchIconVisibility = Visibility.Visible;
- // Hide progress bar again because running query may set this to visible
- ProgressBarVisibility = Visibility.Hidden;
- return;
- }
+ // Hide progress bar again because running query may set this to visible
+ ProgressBarVisibility = Visibility.Hidden;
+ return;
}
_updateSource = new CancellationTokenSource();
@@ -1258,16 +1248,22 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
if (_updateSource.Token.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query
- if (!homeQuery) query.IsReQuery = isReQuery;
+ query.IsReQuery = isReQuery;
// handle the exclusiveness of plugin using action keyword
RemoveOldQueryResults(query);
_lastQuery = query;
+ var homeQuery = query.RawQuery == string.Empty;
+ ICollection plugins = Array.Empty();
if (homeQuery)
{
- // Do not show plugin icon if this is a home query
+ if (Settings.ShowHomePage)
+ {
+ plugins = PluginManager.ValidPluginsForHomeQuery();
+ }
+
PluginIconPath = null;
PluginIconSource = null;
SearchIconVisibility = Visibility.Visible;
@@ -1317,18 +1313,17 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
Task[] tasks;
if (homeQuery)
{
- var homeTasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
+ tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
false => QueryTaskAsync(plugin, _updateSource.Token),
true => Task.CompletedTask
- }).ToList();
+ }).ToArray();
+ // Query history results for home page firstly so it will be put on top of the results
if (Settings.ShowHistoryResultsForHomePage)
{
- homeTasks.Add(QueryHistoryTaskAsync());
+ await QueryHistoryTaskAsync();
}
-
- tasks = homeTasks.ToArray();
}
else
{
@@ -1465,7 +1460,7 @@ private async Task ConstructQueryAsync(string queryText, IEnumerable
Date: Sun, 4 May 2025 10:28:20 +0800
Subject: [PATCH 1172/1335] Fix topmost issue in home page
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 14 ++------------
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index c2265173877..a3e80a73f74 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -327,7 +327,7 @@ public static async Task> QueryForPluginAsync(PluginPair pair, Quer
return results;
}
- public static async Task> QueryHomeForPluginAsync(PluginPair pair, CancellationToken token)
+ public static async Task> QueryHomeForPluginAsync(PluginPair pair, Query query, CancellationToken token)
{
var results = new List();
var metadata = pair.Metadata;
@@ -340,7 +340,7 @@ public static async Task> QueryHomeForPluginAsync(PluginPair pair,
token.ThrowIfCancellationRequested();
if (results == null)
return null;
- UpdatePluginMetadata(results, metadata);
+ UpdatePluginMetadata(results, metadata, query);
token.ThrowIfCancellationRequested();
}
@@ -372,16 +372,6 @@ public static void UpdatePluginMetadata(IReadOnlyList results, PluginMet
}
}
- private static void UpdatePluginMetadata(IReadOnlyList results, PluginMetadata metadata)
- {
- foreach (var r in results)
- {
- r.PluginDirectory = metadata.PluginDirectory;
- r.PluginID = metadata.ID;
- r.OriginQuery = null;
- }
- }
-
///
/// get specified plugin, return null if not found
///
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 517cf5323a6..eb22dc3e28e 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1373,7 +1373,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
await Task.Yield();
var results = homeQuery ?
- await PluginManager.QueryHomeForPluginAsync(plugin, token) :
+ await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
await PluginManager.QueryForPluginAsync(plugin, query, token);
if (token.IsCancellationRequested) return;
From 35e4bfc937158f5a180188626fdd351daf3f188b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 11:05:23 +0800
Subject: [PATCH 1173/1335] Improve code quality
---
Flow.Launcher/ViewModel/MainViewModel.cs | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index eb22dc3e28e..64284d7668c 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1413,10 +1413,10 @@ async Task QueryHistoryTaskAsync()
await Task.Yield();
// Select last history results and revert its order to make sure last history results are on top
- var lastHistoryResults = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
+ var historyResults = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
- var historyResults = new List();
- foreach (var h in lastHistoryResults)
+ var results = new List();
+ foreach (var h in historyResults)
{
var title = App.API.GetTranslation("executeQuery");
var time = App.API.GetTranslation("lastExecuteTime");
@@ -1438,14 +1438,12 @@ async Task QueryHistoryTaskAsync()
return false;
}
};
- historyResults.Add(result);
+ results.Add(result);
}
- // No need to make copy of results and update badge ico property
-
if (_updateSource.Token.IsCancellationRequested) return;
- if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(historyResults, _historyMetadata, query,
+ if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
_updateSource.Token)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
From 2ab007b3b6db29ad4347a3f6b84e4f2459cecabc Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 11:26:00 +0800
Subject: [PATCH 1174/1335] Fix typos
---
Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs | 6 +++---
Flow.Launcher/ViewModel/PluginViewModel.cs | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
index 837d0ebb61b..920abc28426 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
@@ -67,7 +67,7 @@ public void UpdatePluginSettings(List metadatas)
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
metadata.SearchDelayTime = settings.SearchDelayTime;
- metadata.HomeDisabled = settings.HomeDiabled;
+ metadata.HomeDisabled = settings.HomeDisabled;
}
else
{
@@ -80,7 +80,7 @@ public void UpdatePluginSettings(List metadatas)
DefaultActionKeywords = metadata.ActionKeywords, // metadata provides default values
ActionKeywords = metadata.ActionKeywords, // use default value
Disabled = metadata.Disabled,
- HomeDiabled = metadata.HomeDisabled,
+ HomeDisabled = metadata.HomeDisabled,
Priority = metadata.Priority,
DefaultSearchDelayTime = metadata.SearchDelayTime, // metadata provides default values
SearchDelayTime = metadata.SearchDelayTime, // use default value
@@ -130,6 +130,6 @@ public class Plugin
/// Used only to save the state of the plugin in settings
///
public bool Disabled { get; set; }
- public bool HomeDiabled { get; set; }
+ public bool HomeDisabled { get; set; }
}
}
diff --git a/Flow.Launcher/ViewModel/PluginViewModel.cs b/Flow.Launcher/ViewModel/PluginViewModel.cs
index 09289601905..01fa3d20326 100644
--- a/Flow.Launcher/ViewModel/PluginViewModel.cs
+++ b/Flow.Launcher/ViewModel/PluginViewModel.cs
@@ -81,7 +81,7 @@ public bool PluginHomeState
set
{
PluginPair.Metadata.HomeDisabled = !value;
- PluginSettingsObject.HomeDiabled = !value;
+ PluginSettingsObject.HomeDisabled = !value;
}
}
From eaea38c13ab7c6536ee3b92bf8ad9b8ff436c599 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sun, 4 May 2025 11:40:45 +0800
Subject: [PATCH 1175/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
index f3c9cfcad97..129f43b8567 100644
--- a/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
@@ -8,7 +8,7 @@ namespace Flow.Launcher.Plugin
/// Synchronous Query Model for Flow Launcher When Query Text is Empty
///
/// If the Querying method requires high IO transmission
- /// or performaing CPU intense jobs (performing better with cancellation), please try the IAsyncHomeQuery interface
+ /// or performing CPU intense jobs (performing better with cancellation), please try the IAsyncHomeQuery interface
///
///
public interface IHomeQuery : IAsyncHomeQuery
From 78f606f2fcb74467962bb582cd70f65c2d35104e Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Sun, 4 May 2025 11:40:57 +0800
Subject: [PATCH 1176/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
index 129f43b8567..81186fca2de 100644
--- a/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IHomeQuery.cs
@@ -17,7 +17,7 @@ public interface IHomeQuery : IAsyncHomeQuery
/// Querying When Query Text is Empty
///
/// This method will be called within a Task.Run,
- /// so please avoid synchrously wait for long.
+ /// so please avoid synchronously wait for long.
///
///
///
From 72bd1e60dbe7bdef77704e88641b818d1bb8f98f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 11:44:41 +0800
Subject: [PATCH 1177/1335] Remove code comments with issues
---
Flow.Launcher.Plugin/Result.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 060c0331729..f0fcd48ffc0 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -174,9 +174,6 @@ public string BadgeIcoPath
///
/// Query information associated with the result
///
- ///
- /// If the query is for home query, this will be null
- ///
internal Query OriginQuery { get; set; }
///
From 0d9fb29f12948253a956f80fedae0d3a9473091e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 16:37:15 +0800
Subject: [PATCH 1178/1335] Improve code quality
---
Flow.Launcher/ViewModel/MainViewModel.cs | 64 +++++++++---------------
1 file changed, 23 insertions(+), 41 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6d7b4a8a47a..f79596c96de 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1192,8 +1192,27 @@ private void QueryHistory()
var query = QueryText.ToLower().Trim();
History.Clear();
+ var results = GetHistoryItems(_history.Items);
+
+ if (!string.IsNullOrEmpty(query))
+ {
+ var filtered = results.Where
+ (
+ r => App.API.FuzzySearch(query, r.Title).IsSearchPrecisionScoreMet() ||
+ App.API.FuzzySearch(query, r.SubTitle).IsSearchPrecisionScoreMet()
+ ).ToList();
+ History.AddResults(filtered, id);
+ }
+ else
+ {
+ History.AddResults(results, id);
+ }
+ }
+
+ private static List GetHistoryItems(IEnumerable historyItems)
+ {
var results = new List();
- foreach (var h in _history.Items)
+ foreach (var h in historyItems)
{
var title = App.API.GetTranslation("executeQuery");
var time = App.API.GetTranslation("lastExecuteTime");
@@ -1217,20 +1236,7 @@ private void QueryHistory()
};
results.Add(result);
}
-
- if (!string.IsNullOrEmpty(query))
- {
- var filtered = results.Where
- (
- r => App.API.FuzzySearch(query, r.Title).IsSearchPrecisionScoreMet() ||
- App.API.FuzzySearch(query, r.SubTitle).IsSearchPrecisionScoreMet()
- ).ToList();
- History.AddResults(filtered, id);
- }
- else
- {
- History.AddResults(results, id);
- }
+ return results;
}
private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, bool reSelect = true)
@@ -1431,33 +1437,9 @@ async Task QueryHistoryTaskAsync()
await Task.Yield();
// Select last history results and revert its order to make sure last history results are on top
- var historyResults = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
+ var historyItems = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
- var results = new List();
- foreach (var h in historyResults)
- {
- var title = App.API.GetTranslation("executeQuery");
- var time = App.API.GetTranslation("lastExecuteTime");
- var result = new Result
- {
- Title = string.Format(title, h.Query),
- SubTitle = string.Format(time, h.ExecutedDateTime),
- IcoPath = "Images\\history.png",
- Preview = new Result.PreviewInfo
- {
- PreviewImagePath = Constant.HistoryIcon,
- Description = string.Format(time, h.ExecutedDateTime)
- },
- OriginQuery = new Query { RawQuery = h.Query },
- Action = _ =>
- {
- SelectedResults = Results;
- App.API.ChangeQuery(h.Query);
- return false;
- }
- };
- results.Add(result);
- }
+ var results = GetHistoryItems(historyItems);
if (_updateSource.Token.IsCancellationRequested) return;
From 67facb8f18f4325def9572e37ccf7f25fbb7a8fa Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 16:44:05 +0800
Subject: [PATCH 1179/1335] Use non-async version
---
Flow.Launcher/ViewModel/MainViewModel.cs | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index f79596c96de..5fd8d395f89 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1346,7 +1346,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Query history results for home page firstly so it will be put on top of the results
if (Settings.ShowHistoryResultsForHomePage)
{
- await QueryHistoryTaskAsync();
+ QueryHistoryTask();
}
}
else
@@ -1430,12 +1430,8 @@ await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
}
}
- async Task QueryHistoryTaskAsync()
+ void QueryHistoryTask()
{
- // Since it is wrapped within a ThreadPool Thread, the synchronous context is null
- // Task.Yield will force it to run in ThreadPool
- await Task.Yield();
-
// Select last history results and revert its order to make sure last history results are on top
var historyItems = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
@@ -1448,8 +1444,6 @@ async Task QueryHistoryTaskAsync()
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
-
- await Task.CompletedTask;
}
}
From 21d6ec20d45597ad872341afbcb82ef85a85ee87 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 18:29:39 +0800
Subject: [PATCH 1180/1335] Use null to distinguish between home query and
global query
---
Flow.Launcher.Core/Plugin/QueryBuilder.cs | 3 ++-
Flow.Launcher.Plugin/Query.cs | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
index fae821736fb..82745c2394f 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -16,7 +16,8 @@ public static Query Build(string text, Dictionary nonGlobalP
Search = string.Empty,
RawQuery = string.Empty,
SearchTerms = Array.Empty(),
- ActionKeyword = string.Empty
+ // must use null because we need to distinguish between home query and global query
+ ActionKeyword = null
};
}
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index c3eede4c6b6..7d98a4afe8a 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -53,6 +53,7 @@ public class Query
///
/// The action keyword part of this query.
/// For global plugins this value will be empty.
+ /// For home query this value will be null.
///
public string ActionKeyword { get; init; }
From 28b8cb6013fb56de9d9946acc6a300af1e0883cf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 21:43:48 +0800
Subject: [PATCH 1181/1335] Improve distinguish between home query and global
query
---
Flow.Launcher.Core/Plugin/QueryBuilder.cs | 3 +--
Flow.Launcher.Plugin/Query.cs | 1 -
Flow.Launcher/ViewModel/MainViewModel.cs | 17 +++++++++++++----
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
index 82745c2394f..fae821736fb 100644
--- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs
+++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs
@@ -16,8 +16,7 @@ public static Query Build(string text, Dictionary nonGlobalP
Search = string.Empty,
RawQuery = string.Empty,
SearchTerms = Array.Empty(),
- // must use null because we need to distinguish between home query and global query
- ActionKeyword = null
+ ActionKeyword = string.Empty
};
}
diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs
index 7d98a4afe8a..c3eede4c6b6 100644
--- a/Flow.Launcher.Plugin/Query.cs
+++ b/Flow.Launcher.Plugin/Query.cs
@@ -53,7 +53,6 @@ public class Query
///
/// The action keyword part of this query.
/// For global plugins this value will be empty.
- /// For home query this value will be null.
///
public string ActionKeyword { get; init; }
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 5fd8d395f89..30df8250cea 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,6 +33,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private bool _isQueryRunning;
private Query _lastQuery;
+ private bool _lastHomeQuery;
private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText = null;
@@ -1261,6 +1262,8 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
return;
}
+ var homeQuery = query.RawQuery == string.Empty;
+
_updateSource = new CancellationTokenSource();
ProgressBarVisibility = Visibility.Hidden;
@@ -1275,11 +1278,11 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
query.IsReQuery = isReQuery;
// handle the exclusiveness of plugin using action keyword
- RemoveOldQueryResults(query);
+ RemoveOldQueryResults(query, homeQuery);
_lastQuery = query;
+ _lastHomeQuery = homeQuery;
- var homeQuery = query.RawQuery == string.Empty;
ICollection plugins = Array.Empty();
if (homeQuery)
{
@@ -1524,9 +1527,15 @@ private async Task BuildQueryAsync(IEnumerable builtIn
}
}
- private void RemoveOldQueryResults(Query query)
+ private void RemoveOldQueryResults(Query query, bool homeQuery)
{
- if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
+ // If last or current query is home query, we need to clear the results
+ if (_lastHomeQuery || homeQuery)
+ {
+ Results.Clear();
+ }
+ // If last and current query are not home query, we need to check action keyword
+ else if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
{
Results.Clear();
}
From 51fb1515a0d88636d26bfbc5913a994de8871209 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 22:04:01 +0800
Subject: [PATCH 1182/1335] Add more debug log info for query
---
Flow.Launcher/ViewModel/MainViewModel.cs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index c505c32a3c9..c481be02eb3 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1215,10 +1215,14 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
_updateSource?.Cancel();
+ App.API.LogDebug(ClassName, $"Start query with text: {QueryText}");
+
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
if (query == null) // shortcut expanded
{
+ App.API.LogDebug(ClassName, $"Clear query results");
+
// Hide and clear results again because running query may show and add some results
Results.Visibility = Visibility.Collapsed;
Results.Clear();
@@ -1233,6 +1237,8 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
return;
}
+ App.API.LogDebug(ClassName, $"Start query with ActionKeyword <{query.ActionKeyword}> and RawQuery <{query.RawQuery}>");
+
_updateSource = new CancellationTokenSource();
ProgressBarVisibility = Visibility.Hidden;
@@ -1253,6 +1259,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var plugins = PluginManager.ValidPluginsForQuery(query);
+ var validPluginNames = plugins.Select(x => $"<{x.Metadata.Name}>");
+ App.API.LogDebug(ClassName, $"Valid <{plugins.Count}> plugins: {string.Join(" ", validPluginNames)}");
+
if (plugins.Count == 1)
{
PluginIconPath = plugins.Single().Metadata.IcoPath;
@@ -1321,6 +1330,8 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Local function
async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
+ App.API.LogDebug(ClassName, $"Wait for querying plugin <{plugin.Metadata.Name}>");
+
if (searchDelay)
{
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
@@ -1359,6 +1370,8 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
if (token.IsCancellationRequested) return;
+ App.API.LogDebug(ClassName, $"Update results for plugin <{plugin.Metadata.Name}>");
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect)))
{
@@ -1448,6 +1461,8 @@ private void RemoveOldQueryResults(Query query)
{
if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
{
+ App.API.LogDebug(ClassName, $"Remove old results");
+
Results.Clear();
}
}
From 197316397a1596a694cc445351724542b54b66bd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 4 May 2025 22:05:57 +0800
Subject: [PATCH 1183/1335] Improve log info
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index c481be02eb3..228e66edb25 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1215,7 +1215,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
_updateSource?.Cancel();
- App.API.LogDebug(ClassName, $"Start query with text: {QueryText}");
+ App.API.LogDebug(ClassName, $"Start query with text: <{QueryText}>");
var query = await ConstructQueryAsync(QueryText, Settings.CustomShortcuts, Settings.BuiltinShortcuts);
From b9aa5a88cf5350ca7165fa570de225428472bd3f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 08:30:53 +0800
Subject: [PATCH 1184/1335] Change variable name for code quality
---
Flow.Launcher/ViewModel/MainViewModel.cs | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 566cb6814c5..476c10e747b 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,7 +33,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private bool _isQueryRunning;
private Query _lastQuery;
- private bool _lastHomeQuery;
+ private bool _lastIsHomeQuery;
private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText = null;
@@ -1268,7 +1268,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
App.API.LogDebug(ClassName, $"Start query with ActionKeyword <{query.ActionKeyword}> and RawQuery <{query.RawQuery}>");
- var homeQuery = query.RawQuery == string.Empty;
+ var isHomeQuery = query.RawQuery == string.Empty;
_updateSource = new CancellationTokenSource();
@@ -1284,13 +1284,13 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
query.IsReQuery = isReQuery;
// handle the exclusiveness of plugin using action keyword
- RemoveOldQueryResults(query, homeQuery);
+ RemoveOldQueryResults(query, isHomeQuery);
_lastQuery = query;
- _lastHomeQuery = homeQuery;
+ _lastIsHomeQuery = isHomeQuery;
ICollection plugins = Array.Empty();
- if (homeQuery)
+ if (isHomeQuery)
{
if (Settings.ShowHomePage)
{
@@ -1347,7 +1347,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// plugins are ICollection, meaning LINQ will get the Count and preallocate Array
Task[] tasks;
- if (homeQuery)
+ if (isHomeQuery)
{
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
@@ -1397,7 +1397,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
App.API.LogDebug(ClassName, $"Wait for querying plugin <{plugin.Metadata.Name}>");
- if (searchDelay && !homeQuery) // Do not delay for home query
+ if (searchDelay && !isHomeQuery) // Do not delay for home query
{
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
@@ -1410,7 +1410,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
// Task.Yield will force it to run in ThreadPool
await Task.Yield();
- var results = homeQuery ?
+ var results = isHomeQuery ?
await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
await PluginManager.QueryForPluginAsync(plugin, query, token);
@@ -1542,10 +1542,10 @@ private async Task BuildQueryAsync(IEnumerable builtIn
}
}
- private void RemoveOldQueryResults(Query query, bool homeQuery)
+ private void RemoveOldQueryResults(Query query, bool isHomeQuery)
{
// If last or current query is home query, we need to clear the results
- if (_lastHomeQuery || homeQuery)
+ if (_lastIsHomeQuery || isHomeQuery)
{
Results.Clear();
}
From 2713c5babfaaf1a7989043f04b42b34b712116ca Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 08:35:20 +0800
Subject: [PATCH 1185/1335] Add code comments
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 476c10e747b..23958ca7060 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -54,8 +54,8 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly PluginMetadata _historyMetadata = new()
{
- ID = "298303A65D128A845D28A7B83B3968C2",
- Priority = 0
+ ID = "298303A65D128A845D28A7B83B3968C2", // ID is for ResultsForUpdate constructor
+ Priority = 0 // Priority is for calculating scores in UpdateResultView
};
#endregion
From 41211e8cd380df56a44dc9df996ac2833b431dc1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 08:44:08 +0800
Subject: [PATCH 1186/1335] Improve code comments
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 23958ca7060..dc35a6aa998 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -54,7 +54,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly PluginMetadata _historyMetadata = new()
{
- ID = "298303A65D128A845D28A7B83B3968C2", // ID is for ResultsForUpdate constructor
+ ID = "298303A65D128A845D28A7B83B3968C2", // ID is for identifying the update plugin in UpdateActionAsync
Priority = 0 // Priority is for calculating scores in UpdateResultView
};
From 16404bc2a780430028e3515f19f02b2568f57b5e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 12:54:15 +0800
Subject: [PATCH 1187/1335] Improve log information
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index dc35a6aa998..25c39ac7aec 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1547,13 +1547,13 @@ private void RemoveOldQueryResults(Query query, bool isHomeQuery)
// If last or current query is home query, we need to clear the results
if (_lastIsHomeQuery || isHomeQuery)
{
+ App.API.LogDebug(ClassName, $"Remove old results");
Results.Clear();
}
// If last and current query are not home query, we need to check action keyword
else if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
{
App.API.LogDebug(ClassName, $"Remove old results");
-
Results.Clear();
}
}
From 36a4f4176778253f00c09a7675ec43b07953282a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 17:32:43 +0800
Subject: [PATCH 1188/1335] Do not need to clear the result when last and
current query are home query
---
Flow.Launcher/ViewModel/MainViewModel.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 25c39ac7aec..a8e431d9990 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1544,8 +1544,13 @@ private async Task BuildQueryAsync(IEnumerable builtIn
private void RemoveOldQueryResults(Query query, bool isHomeQuery)
{
+ // If last and current query are home query, we don't need to clear the results
+ if (_lastIsHomeQuery && isHomeQuery)
+ {
+ return;
+ }
// If last or current query is home query, we need to clear the results
- if (_lastIsHomeQuery || isHomeQuery)
+ else if (_lastIsHomeQuery || isHomeQuery)
{
App.API.LogDebug(ClassName, $"Remove old results");
Results.Clear();
From 0882378988b72615118150db4c011eafd59ceca9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 18:53:40 +0800
Subject: [PATCH 1189/1335] Add Glyph for history items & topmost items
---
Flow.Launcher/ViewModel/MainViewModel.cs | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index a8e431d9990..a98172f0ac1 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1221,19 +1221,15 @@ private static List GetHistoryItems(IEnumerable historyItem
{
Title = string.Format(title, h.Query),
SubTitle = string.Format(time, h.ExecutedDateTime),
- IcoPath = "Images\\history.png",
- Preview = new Result.PreviewInfo
- {
- PreviewImagePath = Constant.HistoryIcon,
- Description = string.Format(time, h.ExecutedDateTime)
- },
+ IcoPath = Constant.HistoryIcon,
OriginQuery = new Query { RawQuery = h.Query },
Action = _ =>
{
App.API.BackToQueryResults();
App.API.ChangeQuery(h.Query);
return false;
- }
+ },
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE81C")
};
results.Add(result);
}
@@ -1579,7 +1575,8 @@ private Result ContextMenuTopMost(Result result)
App.API.ShowMsg(App.API.GetTranslation("success"));
App.API.ReQuery();
return false;
- }
+ },
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74B")
};
}
else
@@ -1588,7 +1585,6 @@ private Result ContextMenuTopMost(Result result)
{
Title = App.API.GetTranslation("setAsTopMostInThisQuery"),
IcoPath = "Images\\up.png",
- Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\xeac2"),
PluginDirectory = Constant.ProgramDirectory,
Action = _ =>
{
@@ -1596,7 +1592,8 @@ private Result ContextMenuTopMost(Result result)
App.API.ShowMsg(App.API.GetTranslation("success"));
App.API.ReQuery();
return false;
- }
+ },
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74A")
};
}
From 7083849d149f4262b478f29d5c0c6834c78fd3c6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 May 2025 19:11:46 +0800
Subject: [PATCH 1190/1335] Remove unused codes
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index a98172f0ac1..6c4236db9d1 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -790,8 +790,6 @@ private ResultsViewModel SelectedResults
}
}
}
-
- _selectedResults.Visibility = Visibility.Visible;
}
}
From b1a48e296a9d3ee22b09b98c894e35dc4a2a3bc4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 13:58:28 +0800
Subject: [PATCH 1191/1335] Improve code quality
---
Flow.Launcher/ViewModel/MainViewModel.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 6c4236db9d1..8ec29c216ff 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -35,7 +35,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private Query _lastQuery;
private bool _lastIsHomeQuery;
private string _queryTextBeforeLeaveResults;
- private string _ignoredQueryText = null;
+ private string _ignoredQueryText; // Used to ignore query text change when switching between context menu and query results
private readonly FlowLauncherJsonStorage _historyItemsStorage;
private readonly FlowLauncherJsonStorage _userSelectedRecordStorage;
@@ -67,6 +67,7 @@ public MainViewModel()
_queryTextBeforeLeaveResults = "";
_queryText = "";
_lastQuery = new Query();
+ _ignoredQueryText = null; // null as invalid value
Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
From 639a5aebe5a5a5feaf6f1fa10c4845d56218367d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 14:02:18 +0800
Subject: [PATCH 1192/1335] Dispose _updateSource when creating new one & Use
_updateToken instead of _updateSource.Token
---
Flow.Launcher/ViewModel/MainViewModel.cs | 30 ++++++++++++++----------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 8ec29c216ff..175f4ff84bb 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -46,6 +46,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private readonly TopMostRecord _topMostRecord;
private CancellationTokenSource _updateSource; // Used to cancel old query flows
+ private CancellationToken _updateToken; // Used to avoid ObjectDisposedException of _updateSource.Token
private ChannelWriter _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask;
@@ -68,6 +69,8 @@ public MainViewModel()
_queryText = "";
_lastQuery = new Query();
_ignoredQueryText = null; // null as invalid value
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
@@ -249,7 +252,7 @@ public void RegisterResultsUpdatedEvent()
return;
}
- var token = e.Token == default ? _updateSource.Token : e.Token;
+ var token = e.Token == default ? _updateToken : e.Token;
// make a clone to avoid possible issue that plugin will also change the list and items when updating view model
var resultsCopy = DeepCloneResults(e.Results, token);
@@ -1265,7 +1268,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
+ _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
_updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
@@ -1273,7 +1278,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Switch to ThreadPool thread
await TaskScheduler.Default;
- if (_updateSource.Token.IsCancellationRequested) return;
+ if (_updateToken.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
@@ -1322,12 +1327,11 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
// Wait 15 millisecond for query change in global query
// if query changes, return so that it won't be calculated
- await Task.Delay(15, _updateSource.Token);
- if (_updateSource.Token.IsCancellationRequested)
- return;
+ await Task.Delay(15, _updateToken);
+ if (_updateToken.IsCancellationRequested) return;
}*/
- _ = Task.Delay(200, _updateSource.Token).ContinueWith(_ =>
+ _ = Task.Delay(200, _updateToken).ContinueWith(_ =>
{
// start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
if (_isQueryRunning)
@@ -1335,7 +1339,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
ProgressBarVisibility = Visibility.Visible;
}
},
- _updateSource.Token,
+ _updateToken,
TaskContinuationOptions.NotOnCanceled,
TaskScheduler.Default);
@@ -1346,7 +1350,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
- false => QueryTaskAsync(plugin, _updateSource.Token),
+ false => QueryTaskAsync(plugin, _updateToken),
true => Task.CompletedTask
}).ToArray();
@@ -1360,7 +1364,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
{
- false => QueryTaskAsync(plugin, _updateSource.Token),
+ false => QueryTaskAsync(plugin, _updateToken),
true => Task.CompletedTask
}).ToArray();
}
@@ -1375,13 +1379,13 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// nothing to do here
}
- if (_updateSource.Token.IsCancellationRequested) return;
+ if (_updateToken.IsCancellationRequested) return;
// this should happen once after all queries are done so progress bar should continue
// until the end of all querying
_isQueryRunning = false;
- if (!_updateSource.Token.IsCancellationRequested)
+ if (!_updateToken.IsCancellationRequested)
{
// update to hidden if this is still the current query
ProgressBarVisibility = Visibility.Hidden;
@@ -1448,12 +1452,12 @@ void QueryHistoryTask()
var results = GetHistoryItems(historyItems);
- if (_updateSource.Token.IsCancellationRequested) return;
+ if (_updateToken.IsCancellationRequested) return;
App.API.LogDebug(ClassName, $"Update results for history");
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
- _updateSource.Token)))
+ _updateToken)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
From 265fd9c868e881da4f61060bb40385268c8d6420 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 14:13:14 +0800
Subject: [PATCH 1193/1335] Add update source lock
---
Flow.Launcher/ViewModel/MainViewModel.cs | 27 ++++++++++++++++++------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 175f4ff84bb..afef8f64eef 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -47,6 +47,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private CancellationTokenSource _updateSource; // Used to cancel old query flows
private CancellationToken _updateToken; // Used to avoid ObjectDisposedException of _updateSource.Token
+ private readonly object _updateSourceLock = new();
private ChannelWriter _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask;
@@ -69,8 +70,11 @@ public MainViewModel()
_queryText = "";
_lastQuery = new Query();
_ignoredQueryText = null; // null as invalid value
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
+ lock (_updateSourceLock)
+ {
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
+ }
Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
@@ -1240,7 +1244,10 @@ private static List GetHistoryItems(IEnumerable historyItem
private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, bool reSelect = true)
{
- _updateSource?.Cancel();
+ lock (_updateSourceLock)
+ {
+ _updateSource.Cancel();
+ }
App.API.LogDebug(ClassName, $"Start query with text: <{QueryText}>");
@@ -1268,9 +1275,12 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
- _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
+ lock (_updateSourceLock)
+ {
+ _updateSource.Dispose(); // Dispose old update source to fix possible cancellation issue
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
+ }
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
@@ -1888,7 +1898,10 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
- _updateSource?.Dispose();
+ lock (_updateSourceLock)
+ {
+ _updateSource?.Dispose();
+ }
_resultsUpdateChannelWriter?.Complete();
if (_resultsViewUpdateTask?.IsCompleted == true)
{
From b156afed0bdac5cbe19749fcad2687d4bf2b9e20 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 14:14:10 +0800
Subject: [PATCH 1194/1335] Revert "Add update source lock"
This reverts commit 265fd9c868e881da4f61060bb40385268c8d6420.
---
Flow.Launcher/ViewModel/MainViewModel.cs | 27 ++++++------------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index afef8f64eef..175f4ff84bb 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -47,7 +47,6 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private CancellationTokenSource _updateSource; // Used to cancel old query flows
private CancellationToken _updateToken; // Used to avoid ObjectDisposedException of _updateSource.Token
- private readonly object _updateSourceLock = new();
private ChannelWriter _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask;
@@ -70,11 +69,8 @@ public MainViewModel()
_queryText = "";
_lastQuery = new Query();
_ignoredQueryText = null; // null as invalid value
- lock (_updateSourceLock)
- {
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
- }
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
@@ -1244,10 +1240,7 @@ private static List GetHistoryItems(IEnumerable historyItem
private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, bool reSelect = true)
{
- lock (_updateSourceLock)
- {
- _updateSource.Cancel();
- }
+ _updateSource?.Cancel();
App.API.LogDebug(ClassName, $"Start query with text: <{QueryText}>");
@@ -1275,12 +1268,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
- lock (_updateSourceLock)
- {
- _updateSource.Dispose(); // Dispose old update source to fix possible cancellation issue
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
- }
+ _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
@@ -1898,10 +1888,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
- lock (_updateSourceLock)
- {
- _updateSource?.Dispose();
- }
+ _updateSource?.Dispose();
_resultsUpdateChannelWriter?.Complete();
if (_resultsViewUpdateTask?.IsCompleted == true)
{
From 2672512a62503a76d72777c3716cfe48dc1465b7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 14:14:50 +0800
Subject: [PATCH 1195/1335] Dispose the old CancellationTokenSource atomically
to avoid races
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 175f4ff84bb..383256dcc4a 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,9 +1268,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
- _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
- _updateSource = new CancellationTokenSource();
+ var oldSource = Interlocked.Exchange(ref _updateSource, new CancellationTokenSource());
_updateToken = _updateSource.Token;
+ oldSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
From 788cb3cc16cc639ffbe1d55acb3ab20f4f900396 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 19:17:33 +0800
Subject: [PATCH 1196/1335] Revert "Dispose the old CancellationTokenSource
atomically to avoid races"
This reverts commit 2672512a62503a76d72777c3716cfe48dc1465b7.
---
Flow.Launcher/ViewModel/MainViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 383256dcc4a..175f4ff84bb 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1268,9 +1268,9 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
- var oldSource = Interlocked.Exchange(ref _updateSource, new CancellationTokenSource());
+ _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
+ _updateSource = new CancellationTokenSource();
_updateToken = _updateSource.Token;
- oldSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
From deb0c2139f6cbf6f6efd99ba640f65d76596edcd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 19:22:37 +0800
Subject: [PATCH 1197/1335] Remove unused initialization value
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 175f4ff84bb..aab2e2d0300 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -69,8 +69,6 @@ public MainViewModel()
_queryText = "";
_lastQuery = new Query();
_ignoredQueryText = null; // null as invalid value
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
Settings = Ioc.Default.GetRequiredService();
Settings.PropertyChanged += (_, args) =>
From 297643c3e52d9800154390e40a5518e64cb86d9e Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 6 May 2025 19:35:40 +0800
Subject: [PATCH 1198/1335] Revert all changes as master branch
---
Flow.Launcher/ViewModel/MainViewModel.cs | 35 +++++++++++++-----------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index aab2e2d0300..c0b74dc6870 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1266,9 +1266,12 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
var isHomeQuery = query.RawQuery == string.Empty;
- _updateSource?.Dispose(); // Dispose old update source to fix possible cancellation issue
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
+ _updateSource?.Dispose();
+
+ var currentUpdateSource = new CancellationTokenSource();
+ _updateSource = currentUpdateSource;
+ var currentCancellationToken = _updateSource.Token;
+ _updateToken = currentCancellationToken;
ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true;
@@ -1276,7 +1279,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Switch to ThreadPool thread
await TaskScheduler.Default;
- if (_updateToken.IsCancellationRequested) return;
+ if (currentCancellationToken.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
@@ -1325,11 +1328,11 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
// Wait 15 millisecond for query change in global query
// if query changes, return so that it won't be calculated
- await Task.Delay(15, _updateToken);
- if (_updateToken.IsCancellationRequested) return;
+ await Task.Delay(15, currentCancellationToken);
+ if (currentCancellationToken.IsCancellationRequested) return;
}*/
- _ = Task.Delay(200, _updateToken).ContinueWith(_ =>
+ _ = Task.Delay(200, currentCancellationToken).ContinueWith(_ =>
{
// start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
if (_isQueryRunning)
@@ -1337,7 +1340,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
ProgressBarVisibility = Visibility.Visible;
}
},
- _updateToken,
+ currentCancellationToken,
TaskContinuationOptions.NotOnCanceled,
TaskScheduler.Default);
@@ -1348,21 +1351,21 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
{
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
- false => QueryTaskAsync(plugin, _updateToken),
+ false => QueryTaskAsync(plugin, currentCancellationToken),
true => Task.CompletedTask
}).ToArray();
// Query history results for home page firstly so it will be put on top of the results
if (Settings.ShowHistoryResultsForHomePage)
{
- QueryHistoryTask();
+ QueryHistoryTask(currentCancellationToken);
}
}
else
{
tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
{
- false => QueryTaskAsync(plugin, _updateToken),
+ false => QueryTaskAsync(plugin, currentCancellationToken),
true => Task.CompletedTask
}).ToArray();
}
@@ -1377,13 +1380,13 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// nothing to do here
}
- if (_updateToken.IsCancellationRequested) return;
+ if (currentCancellationToken.IsCancellationRequested) return;
// this should happen once after all queries are done so progress bar should continue
// until the end of all querying
_isQueryRunning = false;
- if (!_updateToken.IsCancellationRequested)
+ if (!currentCancellationToken.IsCancellationRequested)
{
// update to hidden if this is still the current query
ProgressBarVisibility = Visibility.Hidden;
@@ -1443,19 +1446,19 @@ await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
}
}
- void QueryHistoryTask()
+ void QueryHistoryTask(CancellationToken token)
{
// Select last history results and revert its order to make sure last history results are on top
var historyItems = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
var results = GetHistoryItems(historyItems);
- if (_updateToken.IsCancellationRequested) return;
+ if (token.IsCancellationRequested) return;
App.API.LogDebug(ClassName, $"Update results for history");
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
- _updateToken)))
+ token)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
From 29f94d66c229cd4036fc00f48e64add87d0fab00 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 9 May 2025 15:57:18 +0800
Subject: [PATCH 1199/1335] Fix startup flicker
---
Flow.Launcher/App.xaml.cs | 2 +-
Flow.Launcher/MainWindow.xaml.cs | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs
index 402812a92d7..942e9447037 100644
--- a/Flow.Launcher/App.xaml.cs
+++ b/Flow.Launcher/App.xaml.cs
@@ -203,7 +203,7 @@ await API.StopwatchLogInfoAsync(ClassName, "Startup cost", async () =>
// it will steal focus from main window which causes window hide
HotKeyMapper.Initialize();
- // Main windows needs initialized before theme change because of blur settings
+ // Initialize theme for main window
Ioc.Default.GetRequiredService().ChangeTheme();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e2948c54043..e243549e31e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -166,9 +166,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
// Force update position
UpdatePosition();
- // Refresh frame
- await _theme.RefreshFrameAsync();
-
// Initialize resize mode after refreshing frame
SetupResizeMode();
From 7c8a4379a33d9e1fbd0c64d713519d5e8d455831 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sat, 10 May 2025 22:56:48 +1000
Subject: [PATCH 1200/1335] fix clearing of results logic & minor adjustment to
results update (#3524)
---
Flow.Launcher/ViewModel/MainViewModel.cs | 64 ++++++++++++---------
Flow.Launcher/ViewModel/ResultsForUpdate.cs | 3 +-
Flow.Launcher/ViewModel/ResultsViewModel.cs | 11 +++-
3 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index c0b74dc6870..0c299875fdf 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -33,7 +33,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
private bool _isQueryRunning;
private Query _lastQuery;
- private bool _lastIsHomeQuery;
+ private bool _previousIsHomeQuery;
private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText; // Used to ignore query text change when switching between context menu and query results
@@ -1264,7 +1264,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
App.API.LogDebug(ClassName, $"Start query with ActionKeyword <{query.ActionKeyword}> and RawQuery <{query.RawQuery}>");
- var isHomeQuery = query.RawQuery == string.Empty;
+ var currentIsHomeQuery = query.RawQuery == string.Empty;
_updateSource?.Dispose();
@@ -1284,14 +1284,10 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery;
- // handle the exclusiveness of plugin using action keyword
- RemoveOldQueryResults(query, isHomeQuery);
-
- _lastQuery = query;
- _lastIsHomeQuery = isHomeQuery;
+
ICollection plugins = Array.Empty();
- if (isHomeQuery)
+ if (currentIsHomeQuery)
{
if (Settings.ShowHomePage)
{
@@ -1347,7 +1343,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
// plugins are ICollection, meaning LINQ will get the Count and preallocate Array
Task[] tasks;
- if (isHomeQuery)
+ if (currentIsHomeQuery)
{
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{
@@ -1397,7 +1393,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
{
App.API.LogDebug(ClassName, $"Wait for querying plugin <{plugin.Metadata.Name}>");
- if (searchDelay && !isHomeQuery) // Do not delay for home query
+ if (searchDelay && !currentIsHomeQuery) // Do not delay for home query
{
var searchDelayTime = plugin.Metadata.SearchDelayTime ?? Settings.SearchDelayTime;
@@ -1410,7 +1406,7 @@ async Task QueryTaskAsync(PluginPair plugin, CancellationToken token)
// Task.Yield will force it to run in ThreadPool
await Task.Yield();
- var results = isHomeQuery ?
+ var results = currentIsHomeQuery ?
await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
await PluginManager.QueryForPluginAsync(plugin, query, token);
@@ -1439,8 +1435,13 @@ await PluginManager.QueryHomeForPluginAsync(plugin, query, token) :
App.API.LogDebug(ClassName, $"Update results for plugin <{plugin.Metadata.Name}>");
+ // Indicate if to clear existing results so to show only ones from plugins with action keywords
+ var shouldClearExistingResults = ShouldClearExistingResults(query, currentIsHomeQuery);
+ _lastQuery = query;
+ _previousIsHomeQuery = currentIsHomeQuery;
+
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
- token, reSelect)))
+ token, reSelect, shouldClearExistingResults)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
@@ -1542,25 +1543,36 @@ private async Task BuildQueryAsync(IEnumerable builtIn
}
}
- private void RemoveOldQueryResults(Query query, bool isHomeQuery)
+ ///
+ /// Determines whether the existing search results should be cleared based on the current query and the previous query type.
+ /// This is needed because of the design that treats plugins with action keywords and global action keywords separately. Results are gathered
+ /// either from plugins with matching action keywords or global action keyword, but not both. So when the current results are from plugins
+ /// with a matching action keyword and a new result set comes from a new query with the global action keyword, the existing results need to be cleared,
+ /// and vice versa. The same applies to home page query results.
+ ///
+ /// There is no need to clear results from global action keyword if a new set of results comes along that is also from global action keywords.
+ /// This is because the removal of obsolete results is handled in ResultsViewModel.NewResults(ICollection).
+ ///
+ /// The current query.
+ /// A flag indicating if the current query is a home query.
+ /// True if the existing results should be cleared, false otherwise.
+ private bool ShouldClearExistingResults(Query query, bool currentIsHomeQuery)
{
- // If last and current query are home query, we don't need to clear the results
- if (_lastIsHomeQuery && isHomeQuery)
+ // If previous or current results are from home query, we need to clear them
+ if (_previousIsHomeQuery || currentIsHomeQuery)
{
- return;
+ App.API.LogDebug(ClassName, $"Cleared old results");
+ return true;
}
- // If last or current query is home query, we need to clear the results
- else if (_lastIsHomeQuery || isHomeQuery)
- {
- App.API.LogDebug(ClassName, $"Remove old results");
- Results.Clear();
- }
- // If last and current query are not home query, we need to check action keyword
- else if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
+
+ // If the last and current query are not home query type, we need to check the action keyword
+ if (_lastQuery?.ActionKeyword != query?.ActionKeyword)
{
- App.API.LogDebug(ClassName, $"Remove old results");
- Results.Clear();
+ App.API.LogDebug(ClassName, $"Cleared old results");
+ return true;
}
+
+ return false;
}
private Result ContextMenuTopMost(Result result)
diff --git a/Flow.Launcher/ViewModel/ResultsForUpdate.cs b/Flow.Launcher/ViewModel/ResultsForUpdate.cs
index bc0be0de81e..1563f85bae2 100644
--- a/Flow.Launcher/ViewModel/ResultsForUpdate.cs
+++ b/Flow.Launcher/ViewModel/ResultsForUpdate.cs
@@ -9,7 +9,8 @@ public record struct ResultsForUpdate(
PluginMetadata Metadata,
Query Query,
CancellationToken Token,
- bool ReSelectFirstResult = true)
+ bool ReSelectFirstResult = true,
+ bool shouldClearExistingResults = false)
{
public string ID { get; } = Metadata.ID;
}
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 02fb379fa07..cd2736afa37 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -232,10 +232,15 @@ private List NewResults(ICollection resultsFo
if (!resultsForUpdates.Any())
return Results;
+ var newResults = resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings));
+
+ if (resultsForUpdates.Any(x => x.shouldClearExistingResults))
+ return newResults.OrderByDescending(rv => rv.Result.Score).ToList();
+
return Results.Where(r => r?.Result != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
- .Concat(resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)))
- .OrderByDescending(rv => rv.Result.Score)
- .ToList();
+ .Concat(newResults)
+ .OrderByDescending(rv => rv.Result.Score)
+ .ToList();
}
#endregion
From 0c7d0e9300acd52dba2d03dc9f8f54501d01ee71 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 09:28:55 +0800
Subject: [PATCH 1201/1335] Support copy file name
---
.../ContextMenu.cs | 23 +++++++++++++++++++
.../Languages/en.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Explorer/Main.cs | 1 -
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
index 633af7b6ba2..eabd118fb33 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs
@@ -140,6 +140,29 @@ public List LoadContextMenus(Result selectedResult)
Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue8c8")
});
+ contextMenus.Add(new Result
+ {
+ Title = Context.API.GetTranslation("plugin_explorer_copyname"),
+ SubTitle = Context.API.GetTranslation("plugin_explorer_copyname_subtitle"),
+ Action = _ =>
+ {
+ try
+ {
+ Context.API.CopyToClipboard(Path.GetFileName(record.FullPath));
+ return true;
+ }
+ catch (Exception e)
+ {
+ var message = "Fail to set text in clipboard";
+ LogException(message, e);
+ Context.API.ShowMsg(message);
+ return false;
+ }
+ },
+ IcoPath = Constants.CopyImagePath,
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue8c8")
+ });
+
contextMenus.Add(new Result
{
Title = Context.API.GetTranslation("plugin_explorer_copyfilefolder"),
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index f7d5bdb18e4..79f8a5848ec 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -82,6 +82,8 @@
Copy path
Copy path of current item to clipboard
+ Copy name
+ Copy name of current item to clipboard
Copy
Copy current file to clipboard
Copy current folder to clipboard
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index e4056131d4b..1c5d074a0b8 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -8,7 +8,6 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Exceptions;
From 315de2b53146c0120c39e944254b0e7a15dc5295 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 09:44:43 +0800
Subject: [PATCH 1202/1335] Adjust margin in appearance page
---
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
index 37de8045173..700dc3a91d2 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml
@@ -733,7 +733,7 @@
From 4e6a07c0d7954cc5e2d27aa1421d2d74dcfc19da Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 11 May 2025 11:49:52 +1000
Subject: [PATCH 1203/1335] Check spelling workflow ignore PRs targeting dev
branch
---
.github/workflows/spelling.yml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
index 7aaa9296af7..003022ac5ee 100644
--- a/.github/workflows/spelling.yml
+++ b/.github/workflows/spelling.yml
@@ -41,9 +41,8 @@ on:
# tags-ignore:
# - "**"
pull_request_target:
- branches:
- - '**'
- # - '!l10n_dev'
+ branches-ignore:
+ - dev
tags-ignore:
- "**"
types:
From 99a7081d1e60f2edcc5357f115f975fb2fc3b444 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 11 May 2025 11:52:26 +1000
Subject: [PATCH 1204/1335] fix typo
---
.github/workflows/spelling.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
index 003022ac5ee..47bd66107b3 100644
--- a/.github/workflows/spelling.yml
+++ b/.github/workflows/spelling.yml
@@ -42,7 +42,7 @@ on:
# - "**"
pull_request_target:
branches-ignore:
- - dev
+ - master
tags-ignore:
- "**"
types:
From 25d985b98ff4c6b7a90be4715ef6ff835e5de4a5 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 14:32:59 +0800
Subject: [PATCH 1205/1335] Fix Homepage with triggers history results on arrow
up
---
Flow.Launcher/ViewModel/MainViewModel.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 0c299875fdf..df4144510a8 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -518,9 +518,10 @@ private void SelectNextPage()
[RelayCommand]
private void SelectPrevItem()
{
- if (_history.Items.Count > 0
- && QueryText == string.Empty
- && QueryResultsSelected())
+ if (QueryResultsSelected() // Results selected
+ && string.IsNullOrEmpty(QueryText) // No input
+ && Results.Visibility != Visibility.Visible // Results closed which means no items in Results
+ && _history.Items.Count > 0) // Have history items
{
lastHistoryIndex = 1;
ReverseHistory();
From af5ff430c47614824e84cc0ed5690bd34536aa90 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 11 May 2025 18:16:29 +1000
Subject: [PATCH 1206/1335] update comment
---
Flow.Launcher/ViewModel/MainViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index df4144510a8..52581ea1dac 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -520,7 +520,7 @@ private void SelectPrevItem()
{
if (QueryResultsSelected() // Results selected
&& string.IsNullOrEmpty(QueryText) // No input
- && Results.Visibility != Visibility.Visible // Results closed which means no items in Results
+ && Results.Visibility != Visibility.Visible // No items in result list, e.g. when home page is off and no query text is entered, therefore the view is collapsed.
&& _history.Items.Count > 0) // Have history items
{
lastHistoryIndex = 1;
From 6ed5308896762787971ff6e085ac2995b50bcfdf Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 16:53:44 +0800
Subject: [PATCH 1207/1335] Fix null origin query issue
---
Flow.Launcher/Storage/TopMostRecord.cs | 18 +-----------------
Flow.Launcher/ViewModel/MainViewModel.cs | 21 ++++++++++-----------
2 files changed, 11 insertions(+), 28 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 7f35904a520..327ad8336d0 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,9 +12,7 @@ public class TopMostRecord
internal bool IsTopMost(Result result)
{
- // origin query is null when user select the context menu item directly of one item from query list
- // in this case, we do not need to check if the result is top most
- if (records.IsEmpty || result.OriginQuery == null ||
+ if (records.IsEmpty ||
!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
return false;
@@ -26,25 +24,11 @@ internal bool IsTopMost(Result result)
internal void Remove(Result result)
{
- // origin query is null when user select the context menu item directly of one item from query list
- // in this case, we do not need to remove the record
- if (result.OriginQuery == null)
- {
- return;
- }
-
records.Remove(result.OriginQuery.RawQuery, out _);
}
internal void AddOrUpdate(Result result)
{
- // origin query is null when user select the context menu item directly of one item from query list
- // in this case, we do not need to add or update the record
- if (result.OriginQuery == null)
- {
- return;
- }
-
var record = new Record
{
PluginID = result.PluginID,
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 0c299875fdf..efa6dd39d20 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -444,12 +444,7 @@ private async Task OpenResultAsync(string index)
if (QueryResultsSelected())
{
_userSelectedRecord.Add(result);
- // origin query is null when user select the context menu item directly of one item from query list
- // so we don't want to add it to history
- if (result.OriginQuery != null)
- {
- _history.Add(result.OriginQuery.RawQuery);
- }
+ _history.Add(result.OriginQuery.RawQuery);
lastHistoryIndex = 1;
}
@@ -1158,7 +1153,7 @@ private void QueryContextMenu()
{
results = PluginManager.GetContextMenusForPlugin(selected);
results.Add(ContextMenuTopMost(selected));
- results.Add(ContextMenuPluginInfo(selected.PluginID));
+ results.Add(ContextMenuPluginInfo(selected));
}
if (!string.IsNullOrEmpty(query))
@@ -1592,7 +1587,8 @@ private Result ContextMenuTopMost(Result result)
App.API.ReQuery();
return false;
},
- Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74B")
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74B"),
+ OriginQuery = result.OriginQuery
};
}
else
@@ -1609,15 +1605,17 @@ private Result ContextMenuTopMost(Result result)
App.API.ReQuery();
return false;
},
- Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74A")
+ Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\uE74A"),
+ OriginQuery = result.OriginQuery
};
}
return menu;
}
- private static Result ContextMenuPluginInfo(string id)
+ private static Result ContextMenuPluginInfo(Result result)
{
+ var id = result.PluginID;
var metadata = PluginManager.GetPluginForId(id).Metadata;
var translator = App.API;
@@ -1639,7 +1637,8 @@ private static Result ContextMenuPluginInfo(string id)
{
App.API.OpenUrl(metadata.Website);
return true;
- }
+ },
+ OriginQuery = result.OriginQuery
};
return menu;
}
From 0e6741cf3f7d6960df13fc7a53a24c8e8963a47d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 17:05:55 +0800
Subject: [PATCH 1208/1335] Improve code quality
---
Flow.Launcher/Storage/TopMostRecord.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher/Storage/TopMostRecord.cs b/Flow.Launcher/Storage/TopMostRecord.cs
index 327ad8336d0..7714b500146 100644
--- a/Flow.Launcher/Storage/TopMostRecord.cs
+++ b/Flow.Launcher/Storage/TopMostRecord.cs
@@ -12,8 +12,7 @@ public class TopMostRecord
internal bool IsTopMost(Result result)
{
- if (records.IsEmpty ||
- !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
+ if (records.IsEmpty || !records.TryGetValue(result.OriginQuery.RawQuery, out var value))
{
return false;
}
From 1775c0fd26cc2b1efd2d458131e735fc9f72cfbe Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Sun, 11 May 2025 20:27:09 +1000
Subject: [PATCH 1209/1335] New Crowdin updates (#3430)
---
Flow.Launcher/Languages/ar.xaml | 68 +++++++--
Flow.Launcher/Languages/cs.xaml | 68 +++++++--
Flow.Launcher/Languages/da.xaml | 134 +++++++++++-------
Flow.Launcher/Languages/de.xaml | 68 +++++++--
Flow.Launcher/Languages/es-419.xaml | 68 +++++++--
Flow.Launcher/Languages/es.xaml | 68 +++++++--
Flow.Launcher/Languages/fr.xaml | 62 ++++++--
Flow.Launcher/Languages/he.xaml | 77 +++++++---
Flow.Launcher/Languages/it.xaml | 68 +++++++--
Flow.Launcher/Languages/ja.xaml | 134 +++++++++++-------
Flow.Launcher/Languages/ko.xaml | 113 +++++++++------
Flow.Launcher/Languages/nb.xaml | 68 +++++++--
Flow.Launcher/Languages/nl.xaml | 68 +++++++--
Flow.Launcher/Languages/pl.xaml | 112 ++++++++++-----
Flow.Launcher/Languages/pt-br.xaml | 68 +++++++--
Flow.Launcher/Languages/pt-pt.xaml | 59 ++++++--
Flow.Launcher/Languages/ru.xaml | 68 +++++++--
Flow.Launcher/Languages/sk.xaml | 70 ++++++---
Flow.Launcher/Languages/sr.xaml | 68 +++++++--
Flow.Launcher/Languages/tr.xaml | 68 +++++++--
Flow.Launcher/Languages/uk-UA.xaml | 68 +++++++--
Flow.Launcher/Languages/vi.xaml | 68 +++++++--
Flow.Launcher/Languages/zh-cn.xaml | 68 +++++++--
Flow.Launcher/Languages/zh-tw.xaml | 68 +++++++--
.../Languages/ja.xaml | 14 +-
.../Languages/ko.xaml | 4 +-
.../Languages/pt-pt.xaml | 2 +-
.../Languages/ja.xaml | 6 +-
.../Languages/pt-pt.xaml | 2 +-
.../Languages/ja.xaml | 80 +++++------
.../Languages/pt-pt.xaml | 2 +-
.../Languages/ko.xaml | 4 +-
.../Languages/ar.xaml | 1 +
.../Languages/cs.xaml | 1 +
.../Languages/da.xaml | 1 +
.../Languages/de.xaml | 1 +
.../Languages/es-419.xaml | 1 +
.../Languages/es.xaml | 1 +
.../Languages/fr.xaml | 1 +
.../Languages/he.xaml | 1 +
.../Languages/it.xaml | 1 +
.../Languages/ja.xaml | 1 +
.../Languages/ko.xaml | 1 +
.../Languages/nb.xaml | 1 +
.../Languages/nl.xaml | 1 +
.../Languages/pl.xaml | 1 +
.../Languages/pt-br.xaml | 1 +
.../Languages/pt-pt.xaml | 1 +
.../Languages/ru.xaml | 1 +
.../Languages/sk.xaml | 1 +
.../Languages/sr.xaml | 1 +
.../Languages/tr.xaml | 1 +
.../Languages/uk-UA.xaml | 1 +
.../Languages/vi.xaml | 1 +
.../Languages/zh-cn.xaml | 1 +
.../Languages/zh-tw.xaml | 1 +
.../Languages/ar.xaml | 2 +-
.../Languages/cs.xaml | 2 +-
.../Languages/da.xaml | 2 +-
.../Languages/de.xaml | 2 +-
.../Languages/es-419.xaml | 2 +-
.../Languages/es.xaml | 2 +-
.../Languages/fr.xaml | 2 +-
.../Languages/he.xaml | 2 +-
.../Languages/it.xaml | 2 +-
.../Languages/ja.xaml | 22 +--
.../Languages/ko.xaml | 6 +-
.../Languages/nb.xaml | 2 +-
.../Languages/nl.xaml | 2 +-
.../Languages/pl.xaml | 2 +-
.../Languages/pt-br.xaml | 2 +-
.../Languages/pt-pt.xaml | 2 +-
.../Languages/ru.xaml | 2 +-
.../Languages/sk.xaml | 2 +-
.../Languages/sr.xaml | 2 +-
.../Languages/tr.xaml | 2 +-
.../Languages/uk-UA.xaml | 2 +-
.../Languages/vi.xaml | 2 +-
.../Languages/zh-cn.xaml | 2 +-
.../Languages/zh-tw.xaml | 2 +-
.../Languages/ja.xaml | 2 +-
.../Languages/he.xaml | 14 +-
.../Languages/ja.xaml | 28 ++--
.../Languages/ko.xaml | 2 +-
.../Languages/ja.xaml | 2 +-
.../Languages/ko.xaml | 12 +-
.../Properties/Resources.he-IL.resx | 16 +--
87 files changed, 1529 insertions(+), 606 deletions(-)
diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml
index b5eafaae9e9..b81c5c9b575 100644
--- a/Flow.Launcher/Languages/ar.xaml
+++ b/Flow.Launcher/Languages/ar.xaml
@@ -42,6 +42,7 @@
وضع اللعب
تعليق استخدام مفاتيح التشغيل السريع.
إعادة تعيين الموقع
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
خطأ في إعداد التشغيل عند بدء التشغيل
إخفاء Flow Launcher عند فقدان التركيز
عدم عرض إشعارات الإصدار الجديد
- موضع نافذة البحث
+ Search Window Location
تذكر آخر موقع
الشاشة مع مؤشر الماوس
الشاشة مع النافذة المركزة
@@ -106,14 +107,35 @@
فتح لوحة المعاينة دائمًا عند تنشيط Flow. اضغط على {0} للتبديل بين المعاينة وعدمها.
تأثير الظل غير مسموح به بينما يتم تمكين تأثير التمويه في السمة الحالية
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ فتح
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
البحث عن إضافة
@@ -130,8 +152,13 @@
كلمة الفعل الحالية
كلمة فعل جديدة
تغيير كلمات الفعل
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ مفع
+ الأولوي
+ Search Delay
+ Home Page
الأولوية الحالية
أولوية جديدة
الأولوية
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
متجر الإضافات
@@ -184,6 +210,9 @@
خط عنوان النتيجة
خط العنوان الفرعي للنتيجة
إعادة التعيين
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
تخصيص
وضع النافذة
الشفافية
@@ -211,12 +240,13 @@
الساعة
التاريخ
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
بلا
Acrylic
Mica
Mica Alt
- هذه السمة تدعم الوضعين (فاتح/داكن).
+ This theme supports two (light/dark) modes.
هذه السمة تدعم الخلفية الضبابية الشفافة.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
استخدام أيقونات Segoe Fluent
استخدام أيقونات Segoe Fluent لنتائج الاستعلام حيثما كان مدعومًا
اضغط على المفتاح
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
بروكسي HTTP
@@ -323,6 +356,7 @@
مجلد السجلات
مسح السجلات
هل أنت متأكد أنك تريد حذف جميع السجلات؟
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
اختر مدير الملفات
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
نجاح
اكتمل بنجاح
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
مفتاح اختصار الاستعلام المخصص
diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml
index 806e9f2030e..71c9c8c6b66 100644
--- a/Flow.Launcher/Languages/cs.xaml
+++ b/Flow.Launcher/Languages/cs.xaml
@@ -42,6 +42,7 @@
Herní režim
Potlačit užívání klávesových zkratek.
Obnovit pozici
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Při nastavování spouštění došlo k chybě
Skrýt Flow Launcher při vykliknutí
Nezobrazovat oznámení o nové verzi
- Pozice vyhledávacího okna
+ Search Window Location
Zapamatovat poslední pozici
Obrazovka s kurzorem
Obrazovka s aktivním oknem
@@ -106,14 +107,35 @@
Při aktivaci služby Flow vždy otevřete panel náhledu. Stisknutím klávesy {0} přepnete náhled.
Stínový efekt není povolen, pokud je aktivní efekt rozostření
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Otevřít
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Vyhledat plugin
@@ -130,8 +152,13 @@
Aktuální aktivační příkaz
Nový aktivační příkaz
Upravit aktivační příkaz
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Povoleno
+ Priorita
+ Search Delay
+ Home Page
Aktuální priorita
Nová priorita
Priorita
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Obchod s pluginy
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Režim okna
Neprůhlednost
@@ -211,12 +240,13 @@
Hodiny
Datum
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Použít ikony Segoe Fluent
Použití ikon Segoe Fluent, pokud jsou podporovány
Stiskněte klávesu
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP Proxy
@@ -323,6 +356,7 @@
Složka s logy
Vymazat logy
Opravdu chcete odstranit všechny logy?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Vybrat správce souborů
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Úspěšné
Úspěšně dokončeno
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Vlastní klávesová zkratka pro vyhledávání
diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml
index 6055a79e1ea..37723dc9b99 100644
--- a/Flow.Launcher/Languages/da.xaml
+++ b/Flow.Launcher/Languages/da.xaml
@@ -30,32 +30,33 @@
Indstillinger
Om
Afslut
- Close
+ Luk
Copy
- Cut
- Paste
+ Klip
+ Indsæt
Undo
Select All
File
Folder
Text
Game Mode
- Suspend the use of Hotkeys.
+ Suspender brugen af genvejstaster.
Position Reset
+ Reset search window position
Type here to search
Indstillinger
Generelt
Portable Mode
- Store all settings and user data in one folder (Useful when used with removable drives or cloud services).
+ Gem alle indstillinger og brugerdata i én mappe (nyttigt ved brug af flytbare drev eller cloud-tjenester).
Start Flow Launcher ved system start
Use logon task instead of startup entry for faster startup experience
After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler
Error setting launch on startup
Skjul Flow Launcher ved mistet fokus
Vis ikke notifikationer om nye versioner
- Search Window Position
+ Search Window Location
Remember Last Position
Monitor with Mouse Cursor
Monitor with Focused Window
@@ -104,16 +105,37 @@
Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.
Always Preview
Always open preview panel when Flow activates. Press {0} to toggle preview.
- Shadow effect is not allowed while current theme has blur effect enabled
+ Skyggeeffekt er ikke tilladt, når det aktuelle tema har sløringseffekt aktiveret
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Åben
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -123,40 +145,44 @@
Plugin
Plugins
Find flere plugins
- On
+ Til
Deaktiver
Action keyword Setting
Nøgleord
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay time
- Change Plugin Seach Delay Time
- Current Priority
- New Priority
- Priority
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Prioritet
+ Search Delay
+ Home Page
+ Nuværende prioritet
+ Ny prioritet
+ Prioritet
Change Plugin Results Priority
Plugin bibliotek
af
Initaliseringstid:
Søgetid:
Version
- Website
+ Hjemmeside
Uninstall
Fail to remove plugin settings
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
- Plugin Store
+ Plugin-butik
New Release
Recently Updated
Plugins
Installed
Refresh
- Install
+ Installer
Uninstall
Opdater
Plugin already installed
@@ -168,8 +194,8 @@
Tema
Appearance
Søg efter flere temaer
- How to create a theme
- Hi There
+ Hvordan man opretter et tema
+ Hejsa
Explorer
Search for files, folders and file contents
WebSearch
@@ -184,18 +210,21 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Vindue mode
Gennemsigtighed
- Theme {0} not exists, fallback to default theme
- Fail to load theme {0}, fallback to default theme
- Theme Folder
- Open Theme Folder
- Color Scheme
- System Default
- Light
- Dark
- Sound Effect
+ Temaet {0} findes ikke. Falder tilbage til standardtema
+ Kunne ikke indlæse temaet {0}. Falder tilbage til standardtema
+ Temamappe
+ Åbn temamappe
+ Farveskema
+ Systemstandard
+ Lys
+ Mørk
+ Lydeffekt
Play a small sound when the search window opens
Sound Effect Volume
Adjust the volume of the sound effect
@@ -211,12 +240,13 @@
Clock
Date
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Use Segoe Fluent Icons
Use Segoe Fluent Icons for query results where supported
Press Key
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP Proxy
@@ -302,7 +335,7 @@
Om
- Website
+ Hjemmeside
GitHub
Docs
Version
@@ -323,6 +356,7 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,29 +367,30 @@
Log Level
Debug
Info
+ Setting Window Font
Select File Manager
Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
- File Manager
- Profile Name
- File Manager Path
- Arg For Folder
- Arg For File
+ Filhåndtering
+ Profilnavn
+ Sti til filhåndtering
+ Arg for mappe
+ Arg for fil
Default Web Browser
The default setting follows the OS default browser setting. If specified separately, flow uses that browser.
Browser
Browser Name
- Browser Path
+ Sti til browser
New Window
New Tab
- Private Mode
+ Privattilstand
- Change Priority
+ Skift prioritet
Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number
Please provide an valid integer for Priority!
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Fortsæt
Completed successfully
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Tilpasset søgegenvejstast
diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml
index 4fb441d8c1f..895a2dab6b2 100644
--- a/Flow.Launcher/Languages/de.xaml
+++ b/Flow.Launcher/Languages/de.xaml
@@ -42,6 +42,7 @@
Spielmodus
Aussetzen der Verwendung von Hotkeys.
Position zurücksetzen
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Fehler bei Einstellungsstart beim Start
Flow Launcher ausblenden, wenn Fokus verloren geht
Versionsbenachrichtigungen nicht zeigen
- Position des Suchfensters
+ Search Window Location
Letzte Position merken
Monitor mit Mauscursor
Monitor mit fokussiertem Fenster
@@ -106,14 +107,35 @@
Vorschau-Panel immer öffnen, wenn Flow aktiviert ist. Drücken Sie {0}, um Vorschau umzuschalten.
Schatteneffekt ist nicht erlaubt, während das aktuelle Theme den Unschärfe-Effekt aktiviert hat
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Öffnen
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Plug-in suchen
@@ -130,8 +152,13 @@
Aktuelles Action-Schlüsselwort
Neues Aktions-Schlüsselwort
Aktions-Schlüsselwörter ändern
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Aktiviert
+ Priorität
+ Search Delay
+ Home Page
Aktuelle Priorität
Neue Priorität
Priorität
@@ -147,7 +174,6 @@
Plug-ins: {0} - Plug-in-Einstellungsdateien können nicht entfernt werden, bitte entfernen Sie diese manuell
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Plug-in-Store
@@ -184,6 +210,9 @@
Schriftart des Ergebnistitels
Schriftart des Ergebnis-Untertitels
Zurücksetzen
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Individuell anpassen
Fenstermodus
Opazität
@@ -211,12 +240,13 @@
Uhr
Datum
Backdrop-Typ
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Keine
Acrylic
Mica
Mica Alt
- Dieses Theme unterstützt zwei Modi (hell/dunkel).
+ This theme supports two (light/dark) modes.
Dieses Theme unterstützt Unschärfe und transparenten Hintergrund.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Segoe Fluent-Icons verwenden
Segoe Fluent-Icons für Abfrageergebnisse verwenden, wo unterstützt
Taste drücken
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP-Proxy
@@ -323,6 +356,7 @@
Ordner »Logs«
Logs löschen
Sind Sie sicher, dass Sie alle Logs löschen wollen?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log-Ebene
Debug
Info
+ Setting Window Font
Dateimanager auswählen
@@ -370,13 +405,16 @@
Dieses neue Aktions-Schlüsselwort ist dasselbe wie das alte, bitte wählen Sie ein anderes
Erfolg
Erfolgreich abgeschlossen
+ Failed to copy
Geben Sie die Aktions-Schlüsselwörter ein, die Sie zum Starten des Plug-ins verwenden möchten, und trennen Sie sie durch Leerzeichen voneinander ab. Verwenden Sie *, wenn Sie keine spezifizieren möchten, und das Plug-in wird ohne jegliche Aktions-Schlüsselwörter ausgelöst.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Benutzerdefinierter Abfrage-Hotkey
diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml
index 23d58eca3a1..902811a5611 100644
--- a/Flow.Launcher/Languages/es-419.xaml
+++ b/Flow.Launcher/Languages/es-419.xaml
@@ -42,6 +42,7 @@
Modo de juego
Suspender el uso de las teclas de acceso directo.
Position Reset
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Error setting launch on startup
Ocultar Flow Launcher cuando se pierde el enfoque
No mostrar notificaciones de nuevas versiones
- Search Window Position
+ Search Window Location
Remember Last Position
Monitor with Mouse Cursor
Monitor with Focused Window
@@ -106,14 +107,35 @@
Always open preview panel when Flow activates. Press {0} to toggle preview.
El efecto de sombra no está permitido mientras el tema actual tenga el efecto de desenfoque habilitado
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Abrir
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -130,8 +152,13 @@
Palabra clave actual
Nueva palabra clave
Cambiar palabras clave
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Prioridad
+ Search Delay
+ Home Page
Prioridad Actual
Nueva Prioridad
Prioridad
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Tienda de Plugins
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Modo Ventana
Opacidad
@@ -211,12 +240,13 @@
Clock
Date
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Usar Iconos de Segoe Fluent
Usar iconos de Segoe Fluent para resultados de consultas que sean soportados
Press Key
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
Proxy HTTP
@@ -323,6 +356,7 @@
Carpeta de registros
Clear Logs
Are you sure you want to delete all logs?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Seleccionar Gestor de Archivos
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Éxito
Completado con éxito
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Tecla de Acceso Personalizada
diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml
index 8b3c42fa613..0dc6833af7d 100644
--- a/Flow.Launcher/Languages/es.xaml
+++ b/Flow.Launcher/Languages/es.xaml
@@ -42,6 +42,7 @@
Modo Juego
Suspende el uso de atajos de teclado.
Restablecer posición
+ Restablece la posición de la ventana de búsqueda
Escribir aquí para buscar
@@ -106,14 +107,35 @@
Muestra siempre el panel de vista previa al iniciar Flow. Pulsar {0} para mostrar/ocultar la vista previa.
El efecto de sombra no está permitido si el tema actual tiene activado el efecto de desenfoque
Retardo de búsqueda
- Retrasa un poco la búsqueda al escribir. Esto reduce los saltos en la interfaz y la carga de resultados.
+ Añade un breve retardo al escribir para reducir el parpadeo de la interfaz de usuario y la carga de resultados. Recomendado si la velocidad de escritura es media.
+ Introduzca el tiempo de espera (en ms) hasta que la entrada se considere completa. Solo se puede editar cuando el retardo de búsqueda está activado.
Tiempo de retardo de búsqueda predeterminado
- Tiempo de retardo predeterminado del complemento tras el que aparecerán los resultados de la búsqueda cuando se deje de escribir.
- Muy largo
- Largo
- Normal
- Corto
- Muy corto
+ Tiempo de espera antes de mostrar los resultados después de dejar de teclear. A mayor valor, más tiempo de espera. (ms)
+ Información para usuario de IME coreano
+
+ El método de entrada coreano utilizado en Windows 11 puede causar algunos problemas en Flow Launcher.
+
+ Si se experimenta algún problema, es posible que se tenga que activar "Usar versión anterior del IME coreano".
+
+
+ Abrir Configuración en Windows 11 e ir a:
+
+ Hora e idioma > Idioma y región > Coreano > Opciones de idioma > Teclado - Microsoft IME > Compatibilidad,
+
+ y activar "Usar versión anterior de Microsoft IME".
+
+
+
+ Abrir idioma y región en configuración
+ Abre la ubicación de configuración del IME coreano. Ir a Coreano > Opciones de idioma > Teclado - Microsoft IME > Compatibilidad
+ Abrir
+ Utilizar IME Coreano anterior
+ Se puede cambiar la configuración anterior del IME coreano directamente desde aquí
+ Página de inicio
+ Muestra los resultados de la página de inicio cuando el texto de la consulta está vacío.
+ Mostrar historial de resultados en la página de inicio
+ Número máximo de resultados del historial en la página de inicio
+ Esto solo se puede editar si el complemento soporta la función de Inicio y la Página de Inicio está activada.
Buscar complemento
@@ -131,7 +153,12 @@
Nueva palabra clave de acción
Cambia la palabra clave de acción
Tiempo de retardo de la búsqueda del complemento
- Cambiar tiempo de retardo de la búsqueda del complemento
+ Cambia el tiempo de retardo de la búsqueda del complemento
+ Configuración avanzada:
+ Activado
+ Prioridad
+ Retardo de búsqueda
+ Página de inicio
Prioridad actual
Nueva prioridad
Prioridad
@@ -147,7 +174,6 @@
Complementos: {0} - Fallo al eliminar los archivos de configuración del complemento, por favor elimínelos manualmente
Fallo al eliminar la caché del complemento
Complementos: {0} - Fallo al eliminar los archivos de caché del complemento, por favor elimínelos manualmente
- Predeterminado
Tienda complementos
@@ -184,6 +210,9 @@
Fuente del título del resultado
Fuente del subtítulo del resultado
Restablecer
+ Restablece la configuración recomendada para la fuente y el tamaño.
+ Importar tamaño del tema
+ Si existe un valor de tamaño del tema previsto por el diseñador, este se recuperará y aplicará.
Personaliza
Modo Ventana
Opacidad
@@ -211,6 +240,7 @@
Reloj
Fecha
Tipo de telón de fondo
+ El efecto de telón de fondo no se aplica en la vista previa.
Telón de fondo compatible a partir de Windows 11 build 22000 y superiores
Ninguno
Acrílico
@@ -283,6 +313,9 @@
Iconos Segoe Fluent
Utiliza iconos Segoe Fluent para los resultados de la consulta cuando sean compatibles
Pulsar Tecla
+ Mostrar distintivos en resultados
+ Para los complementos compatibles, se muestran distintivos que ayudan a distinguirlos más fácilmente.
+ Mostrar distintivos en resultados solo para consulta global
Proxy HTTP
@@ -323,9 +356,10 @@
Carpeta de registros
Eliminar registros
¿Está seguro de que desea eliminar todos los registros?
- Clear Caches
- Are you sure you want to delete all caches?
- Failed to clear part of folders and files. Please see log file for more information
+ Carpeta del caché
+ Limpiar cachés
+ ¿Está seguro de que desea eliminar todos los cachés?
+ No se pudo eliminar parte de las carpetas y archivos. Por favor, consulte el archivo de registro para más información
Asistente
Ubicación de datos del usuario
La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portable o no.
@@ -333,6 +367,7 @@
Nivel de registro
Depurar
Información
+ Configuración de fuente de la ventana
Seleccionar administrador de archivos
@@ -370,13 +405,16 @@
Esta nueva palabra clave de acción es la misma que la anterior, por favor elija una diferente
Correcto
Finalizado correctamente
+ No se pudo copiar
Introduzca las palabras clave de acción que desea utilizar para iniciar el complemento y utilice espacios en blanco para separarlas. Utilice * si no desea especificar ninguna, para que el complemento se inicie sin ninguna palabra clave de acción.
Ajuste del tiempo de retardo de búsqueda
- Seleccionar el tiempo de retardo de búsqueda que se desea utilizar para el complemento. Seleccionar "{0}" si no se desea especificar nada, y el complemento utilizará el tiempo de retardo de búsqueda predeterminado.
- Tiempo de retardo de búsqueda actual
- Nuevo tiempo de retardo de búsqueda
+ Introducir el tiempo de retardo de búsqueda en ms que se desea utilizar para el complemento. Introducir un espacio vacío si no desea especificar ninguno, y el complemento utilizará el tiempo de retardo de búsqueda predeterminado.
+
+
+ Página de inicio
+ Activar el estado de la página de inicio del complemento si se desea mostrar los resultados del complemento cuando la consulta está vacía.
Atajo de teclado de consulta personalizada
diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml
index e46e0dc9de3..41fdbaa514d 100644
--- a/Flow.Launcher/Languages/fr.xaml
+++ b/Flow.Launcher/Languages/fr.xaml
@@ -42,6 +42,7 @@
Mode jeu
Suspend l'utilisation des raccourcis claviers.
Réinitialiser la position
+ Réinitialiser la position de la fenêtre de recherche
Tapez ici pour rechercher
@@ -55,7 +56,7 @@
Erreur lors de la configuration du lancement au démarrage
Cacher Flow Launcher lors de la perte de focus
Ne pas afficher le message de mise à jour pour les nouvelles versions
- Position de la fenêtre de recherche
+ Emplacement de la fenêtre de recherche
Se souvenir de la dernière position
Surveiller avec le curseur de la souris
Surveiller avec la fenêtre ciblée
@@ -106,14 +107,35 @@
Toujours ouvrir le panneau d'aperçu lorsque Flow s'active. Appuyez sur {0} pour activer/désactiver l'aperçu.
L'effet d'ombre n'est pas autorisé lorsque le thème actuel à un effet de flou activé
Délai de recherche
- Attendre un certain temps pour effectuer une recherche lors de la saisie. Cela permet de réduire les sauts d'interface et la charge des résultats.
+ Ajoute un court délai pendant la frappe pour réduire le scintillement de l'interface utilisateur et le chargement des résultats. Recommandé si votre vitesse de frappe est moyenne.
+ Entrez le temps d'attente (en ms) jusqu'à ce que l'entrée soit considérée comme terminée. Cela ne peut être modifié que si le délai de recherche est activé.
Délai de recherche par défaut
- Délai par défaut du plugin après lequel les résultats de la recherche s'affichent lorsque la saisie est interrompue.
- Très long
- Long
- Normal
- Court
- Très court
+ Délai d'attente avant l'affichage des résultats après l'arrêt de la saisie. Les valeurs élevées permettent d'attendre plus longtemps. (ms)
+ Information pour les utilisateurs coréens IME
+
+ La méthode de saisie coréenne utilisée dans Windows 11 peut causer des problèmes dans Flow Launcher.
+
+ Si vous rencontrez des problèmes, il se peut que vous deviez activer l'option "Utiliser la version précédente de l'IME coréen".
+
+
+ Ouvrez les Paramètres dans Windows 11 et allez dans :
+
+ Heure et langue > Langue et région > Coréen > Options linguistiques > Claviers - Microsoft IME > Compatibilité,
+
+ et activez l'option "Utiliser la version précédente de Microsoft IME".
+
+
+
+ Ouvrir les paramètres du système de langue et de région
+ Ouvre l'emplacement de réglage IME coréen. Allez dans coréen > Options linguistiques > Claviers - Microsoft IME > Compatibilité
+ Ouvrir
+ Utilisez l'IME coréenne précédente
+ Vous pouvez modifier les paramètres de l'IME coréen précédent directement à partir d'ici
+ Page d'accueil
+ Afficher les résultats de la page d'accueil lorsque le texte de la requête est vide.
+ Afficher les résultats de l'historique sur la page d'accueil
+ Maximum de résultats de l'historique affichés sur la page d'accueil
+ Ceci ne peut être édité que si le plugin prend en charge la fonction Accueil et que la page d'accueil est activée.
Rechercher des plugins
@@ -132,6 +154,11 @@
Changer les mots-clés d'action
Délai de recherche du plugin
Modifier le délai de recherche du plugin
+ Paramètres avancés :
+ Activé
+ Priorité
+ Délai de recherche
+ Page d'accueil
Priorité actuelle
Nouvelle priorité
Priorité
@@ -147,7 +174,6 @@
Plugins : {0} - Échec de la suppression des fichiers de configuration des plugins, veuillez les supprimer manuellement
Échec de la suppression du cache du plugin
Plugins : {0} - Échec de la suppression des fichiers cache des plugins, veuillez les supprimer manuellement
- Défaut
Magasin des Plugins
@@ -184,6 +210,9 @@
Police du titre du résultat
Police des sous-titres du résultat
Réinitialiser
+ Rétablir les paramètres de police et de taille recommandés.
+ Importer la taille du thème
+ Si une valeur de taille prévue par le concepteur du thème est disponible, elle sera récupérée et appliquée.
Personnaliser
Mode fenêtré
Opacité
@@ -211,6 +240,7 @@
Heure
Date
Type d'arrière-plan
+ L'effet de fond n'est pas appliqué dans l'aperçu.
Arrière-plan pris en charge à partir de Windows 11 version 22000 et plus
Aucun
Acrylique
@@ -283,6 +313,9 @@
Utiliser les icônes Segoe Fluent
Utiliser les icônes Segoe Fluent pour les résultats de requête lorsque pris en charge
Appuyez sur une touche
+ Afficher les badges de résultats
+ Pour les plugins pris en charge, des badges sont affichés afin de les distinguer plus facilement.
+ Afficher les badges de résultats pour la requête globale uniquement
Proxy HTTP
@@ -322,6 +355,7 @@
Répertoire des journaux
Effacer le journal
Êtes-vous sûr de vouloir supprimer tous les journaux ?
+ Dossier de cache
Vider les caches
Êtes-vous sûr de vouloir supprimer tous les caches ?
Échec de l'effacement d'une partie des dossiers et des fichiers. Veuillez consulter le fichier journal pour plus d'informations
@@ -332,6 +366,7 @@
Niveau de journalisation
Débogage
Info
+ Réglage de la police de la fenêtre
Sélectionner le gestionnaire de fichiers
@@ -369,13 +404,16 @@
Ce nouveau mot-clé d'action est identique à l'ancien, veuillez en choisir un autre
Ajout
Terminé avec succès
+ Échec de la copie
Saisissez les mots-clés d'action que vous souhaitez utiliser pour lancer le plugin et séparez-les par des espaces. Utilisez * si vous ne voulez en spécifier aucun, et le plugin sera déclenché sans aucun mot-clé d'action.
Réglage du délai de recherche
- Sélectionnez le délai de recherche que vous souhaitez utiliser pour le plugin. Sélectionnez "{0}" si vous ne voulez pas en spécifier, et le plugin utilisera le délai de recherche par défaut.
- Délai de recherche actuel
- Nouveau délai de recherche
+ Entrez le délai de recherche en ms que vous souhaitez utiliser pour le plugin. Laissez la case vide et le plugin utilisera le délai de recherche par défaut.
+
+
+ Page d'accueil
+ Activez l'état de la page d'accueil du plugin si vous souhaitez afficher les résultats du plugin lorsque la requête est vide.
Requêtes personnalisées
diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml
index 38e943cda2a..52eaf5e9f95 100644
--- a/Flow.Launcher/Languages/he.xaml
+++ b/Flow.Launcher/Languages/he.xaml
@@ -42,6 +42,7 @@
מצב משחק
השהה את השימוש במקשי קיצור.
איפוס מיקום
+ אפס את מיקום חלון החיפוש
הקלד כאן כדי לחפש
@@ -55,7 +56,7 @@
שגיאה בהגדרת ההפעלה בעת הפעלת windows
הסתר את Flow Launcher כאשר הוא אינו החלון הפעיל
אל תציג התראות על גרסה חדשה
- מיקום חלון החיפוש
+ מיקום חלון חיפוש
זכור את המיקום האחרון
Monitor with Mouse Cursor
Monitor with Focused Window
@@ -105,21 +106,41 @@
הצג תמיד תצוגה מקדימה
פתח תמיד את לוח התצוגה המקדימה כאשר Flow מופעל. הקש על {0} כדי להחליף את התצוגה המקדימה.
לא ניתן להחיל אפקט צל כאשר העיצוב הנוכחי מוגדר לאפקט טשטוש
- Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
- Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ השהיית חיפוש
+ מוסיף עיכוב קצר בזמן ההקלדה כדי להפחית קפיצות בממשק המשתמש ועומס בתוצאות. מומלץ אם מהירות ההקלדה שלך ממוצעת.
+ הזן את זמן ההמתנה (בשניות) עד שהקלט נחשב כמושלם. ניתן לערוך זאת רק אם השהיית חיפוש מופעלת.
+ זמן עיכוב חיפוש ברירת מחדל
+ זמן המתנה להצגת התוצאות לאחר שתפסיק להקליד. ערכים גבוהים יותר מייצגים המתנה רבה יותר. (שניות)
+ Information for Korean IME user
+
+ שיטת הקלט הקוריאנית שמשמשת ב־Windows 11 עלולה לגרום לבעיות מסוימות ב־Flow Launcher.
+
+ אם אתה נתקל בבעיות, ייתכן שתצטרך להפעיל את האפשרות "השתמש בגרסה הקודמת של IME הקוריאני".
+
+ פתח את ההגדרות ב־Windows 11 וגש אל:
+
+ זמן ושפה > שפה ואזור > קוריאנית > אפשרויות שפה > מקלדת - Microsoft IME > תאימות,
+
+ והפעל את האפשרות "השתמש בגרסה הקודמת של Microsoft IME".
+
+
+
+ פתח את הגדרות מערכת שפה ואזור
+ פותח את מיקום הגדרות ה־IME הקוריאני. עבור אל קוריאנית > אפשרויות שפה > מקלדת - Microsoft IME > תאימות
+ פתח
+ השתמש ב־IME הקוריאני הקודם
+ באפשרותך לשנות את הגדרות ה־IME הקוריאני הקודם ישירות מכאן
+ דף הבית
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
חפש תוסף
Ctrl+F לחיפוש תוסף
לא נמצאו תוצאות
- Please try a different search.
+ אנא נסה חיפוש אחר.
תוסף
תוספים
מצא תוספים נוספים
@@ -130,8 +151,13 @@
מילת מפתח נוכחית לפעולה
מילת מפתח חדשה לפעולה
שנה מילות מפתח לפעולה
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ שנה את זמן השהיית חיפוש של תוסף
+ הגדרות מתקדמות:
+ מופעל
+ עדיפות
+ עיכוב חיפוש
+ דף הבית
עדיפות נוכחית
עדיפות חדשה
עדיפות
@@ -147,7 +173,6 @@
תוספים: {0} - נכשל בהסרת קבצי הגדרות התוסף, יש להסירם ידנית
נכשל בהסרת מטמון התוסף
תוספים: {0} - נכשל בהסרת קובצי מטמון התוסף, אנא הסר אותם ידנית
- Default
חנות תוספים
@@ -184,6 +209,9 @@
גופן הכותרת לתוצאה
גופן כותרת המשנה לתוצאה
אפס
+ אפס להגדרות הגופן והגודל המומלצות.
+ ייבוא גודל ערכת נושא
+ אם ערך הגודל שתוכנן על ידי מעצב ערכת הנושא זמין, הוא יאוחזר ויוחל.
התאם אישית
מצב חלון
שקיפות
@@ -211,12 +239,13 @@
שעון
תאריך
סוג רקע
+ אפקט הרקע אינו מוחל בתצוגה המקדימה.
התמיכה ב-Backdrop קיימת החל מ-Windows 11 build 22000 ומעלה
ללא
אקריליק
מיקה
Mica Alt
- ערכת נושא זאת תומך בשני מצבים (בהיר/כהה).
+ ערכת נושא זאת תומכת בשני מצבים (בהיר/כהה).
ערכת נושא זו תומכת בטשטוש רקע שקוף.
הצג מציין מיקום
הצג מציין מיקום כאשר השאילתה ריקה
@@ -283,6 +312,9 @@
השתמש ב-Segoe Fluent Icons
השתמש ב-Segoe Fluent Icons לתוצאות חיפוש כאשר נתמך
הקש על מקש
+ הצג תגי תוצאות
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP Proxy
@@ -323,6 +355,7 @@
תיקיית יומני רישום
נקה יומני רישום
האם אתה בטוח שברצונך למחוק את כל היומנים?
+ תיקיית מטמון
נקה נתוני מטמון
האם אתה בטוח שברצונך למחוק את כל הנתונים שבמטמון?
נכשל ניקוי חלק מהתיקיות והקבצים. עיין בלוג לקבלת מידע נוסף
@@ -330,9 +363,10 @@
מיקום נתוני משתמש
הגדרות המשתמש והתוספים המותקנים נשמרים בתיקיית נתוני המשתמש. מיקום זה עשוי להשתנות אם התוכנה במצב נייד.
פתח תיקיה
- Log Level
+ רמת יומן
ניפוי שגיאות
מידע
+ Setting Window Font
בחר מנהל קבצים
@@ -370,13 +404,16 @@
מילת הפעולה החדשה זהה לישנה, נא לבחור מילת פעולה שונה
הצליח
הושלם בהצלחה
+ ההעתקה נכשלה
הזן את מילות הפעולה שבהן תרצה להשתמש כדי להפעיל את התוסף, והשתמש ברווחים כדי להפריד ביניהן. השתמש ב-* אם אינך רוצה להגדיר כלל, והתוסף יופעל ללא מילות פעולה.
- Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ הגדרת זמן עיכוב החיפוש
+ הזן את זמן עיכוב החיפוש בשניות שבו אתה רוצה להשתמש עבור התוסף. השאר ריק אם אינך רוצה לציין, והתוסף ישתמש בזמן ברירת המחדל לעיכוב חיפוש.
+
+
+ דף הבית
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
מקש קיצור לשאילתה מותאמת אישית
diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml
index fd34bf36625..1a356ad650b 100644
--- a/Flow.Launcher/Languages/it.xaml
+++ b/Flow.Launcher/Languages/it.xaml
@@ -42,6 +42,7 @@
Modalità gioco
Sospendere l'uso dei tasti di scelta rapida.
Ripristina Posizione
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Errore nell'impostazione del lancio all'avvio
Nascondi Flow Launcher quando perde il focus
Non mostrare le notifiche per una nuova versione
- Posizione Finestra Di Ricerca
+ Search Window Location
Ricorda L'Ultima Posizione
Monitora con il cursore del mouse
Monitora con la finestra in primo piano
@@ -106,14 +107,35 @@
Apri sempre il pannello di anteprima quando Flow si attiva. Premi {0} per attivare l'anteprima.
L'effetto ombra non è consentito mentre il tema corrente ha un effetto di sfocatura abilitato
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Apri
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Plugin di ricerca
@@ -130,8 +152,13 @@
Parola chiave di azione corrente
Nuova parola chiave d'azione
Cambia Keywords Azione
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Abilitato
+ Priorità
+ Search Delay
+ Home Page
Priorità Attuale
Nuova Priorità
Priorità
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Negozio dei Plugin
@@ -184,6 +210,9 @@
Font del Titolo del Risultato
Font del Sottotitolo del Risultato
Resetta
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Personalizza
Modalità finestra
Opacità
@@ -211,12 +240,13 @@
Orologio
Data
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Vuoto
Acrylic
Mica
Mica Alt
- Questo tema supporta due (chiaro/scuro) varianti.
+ This theme supports two (light/dark) modes.
Questo tema supporta lo sfondo trasparente blurrato.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Usa Icone Segoe Fluent
Usa Icone Segoe Fluent per risultati di ricerca dove supportate
Premi tasto
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
Proxy HTTP
@@ -323,6 +356,7 @@
Cartella dei Log
Cancella i log
Sei sicuro di voler cancellare tutti i log?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Seleziona Gestore File
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Successo
Completato con successo
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Tasti scelta rapida per ricerche personalizzate
diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml
index e6f2223cd22..949fe5c9973 100644
--- a/Flow.Launcher/Languages/ja.xaml
+++ b/Flow.Launcher/Languages/ja.xaml
@@ -28,7 +28,7 @@
最終実行時間:{0}
開く
設定
- Flow Launcherについて
+ 情報
終了
閉じる
コピー
@@ -42,7 +42,8 @@
ゲームモード
ホットキーの使用を一時停止します。
位置のリセット
- Type here to search
+ 検索ウィンドウの位置をリセット
+ ここに入力して検索
設定
@@ -50,8 +51,8 @@
ポータブルモード
すべての設定とユーザーデータを1つのフォルダに保存します(リムーバブルドライブやクラウドサービスで使用する場合に便利です)。
スタートアップ時にFlow Launcherを起動する
- Use logon task instead of startup entry for faster startup experience
- After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler
+ 高速起動のためにスタートアップではなくログオンタスクを使用
+ アンインストール後は、「タスク スケジューラ」からこのタスク(Flow.Launcher Startup)を手動で削除する必要があります。
Error setting launch on startup
フォーカスを失った時にFlow Launcherを隠す
最新版が入手可能であっても、アップグレードメッセージを表示しない
@@ -105,15 +106,36 @@
常にプレビューする
Flow が有効になったとき、常にプレビューパネルを開きます。 {0} を押してプレビューの表示/非表示を切り替えます。
現在のテーマでぼかしの効果が有効になっている場合、影の効果を有効にすることはできません
- Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ 検索遅延
+ 入力中に短い遅延を追加することで、UIのちらつきや結果の読み込みを軽減します。平均的なタイピング速度のユーザーにおすすめです。
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ 開く
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -130,8 +152,13 @@
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ 詳細設定:
+ Enabled
+ 重要度
+ 検索遅延
+ Home Page
Current Priority
New Priority
重要度
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
プラグインストア
@@ -178,12 +204,15 @@
管理者または別のユーザーとしてプログラムを起動します
プロセスキラー
不要なプロセスを終了します
- Search Bar Height
- Item Height
+ 検索バーの高さ
+ アイテムの高さ
検索ボックスのフォント
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
ウィンドウモード
透過度
@@ -210,20 +239,21 @@
カスタム
時刻
日付
- Backdrop Type
- Backdrop supported starting from Windows 11 build 22000 and above
- None
- Acrylic
- Mica
- Mica Alt
- This theme supports two(light/dark) modes.
+ バックドロップの種類
+ プレビューではバックドロップ効果が適用されません。
+ バックドロップは Windows 11 ビルド 22000 以降でサポートされています。
+ なし
+ アクリル
+ マイカ
+ マイカ(代替)
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
- Show placeholder
+ プレースホルダーを表示
Display placeholder when query is empty
- Placeholder text
+ 検索欄の案内文
Change placeholder text. Input empty will use: {0}
- Fixed Window Size
- The window size is not adjustable by dragging.
+ ウィンドウサイズの固定
+ ウィンドウのサイズを固定し、ドラッグでの変更を無効にします。
ホットキー
@@ -238,8 +268,8 @@
Select a modifier key to open selected result via keyboard.
ホットキーを表示
Show result selection hotkey with results.
- Auto Complete
- Runs autocomplete for the selected items.
+ 自動補完
+ 選択された項目に対して自動補完を実行します。
Select Next Item
Select Previous Item
Next Page
@@ -253,7 +283,7 @@
Toggle Game Mode
Toggle History
Open Containing Folder
- Run As Admin
+ 管理者として実行
Refresh Search Results
Reload Plugins Data
Quick Adjust Window Width
@@ -283,6 +313,9 @@
Use Segoe Fluent Icons
Use Segoe Fluent Icons for query results where supported
Press Key
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP プロキシ
@@ -301,15 +334,15 @@
プロキシ接続に失敗しました
- Flow Launcherについて
+ 情報
ウェブサイト
GitHub
- Docs
+ ドキュメント
バージョン
Icons
あなたはFlow Launcherを {0} 回利用しました
アップデートを確認する
- Become A Sponsor
+ スポンサーになる
新しいバージョン {0} が利用可能です。Flow Launcherを再起動してください。
アップデートの確認に失敗しました、api.github.com への接続とプロキシ設定を確認してください。
@@ -323,6 +356,7 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,9 +367,10 @@
Log Level
Debug
Info
+ Setting Window Font
- Select File Manager
+ デフォルトのファイルマネージャー
Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
File Manager
@@ -345,7 +380,7 @@
Arg For File
- Default Web Browser
+ デフォルトのウェブブラウザー
The default setting follows the OS default browser setting. If specified separately, flow uses that browser.
Browser
Browser Name
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
成功しました
Completed successfully
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
@@ -404,7 +442,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
保存
Overwrite
-
+ キャンセル
Reset
削除
Update
@@ -456,14 +494,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
アップデートの詳細
- Skip
- Welcome to Flow Launcher
- Hello, this is the first time you are running Flow Launcher!
- Before starting, this wizard will assist in setting up Flow Launcher. You can skip this if you wish. Please choose a language
- Search and run all files and applications on your PC
- Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.
- Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.
- Hotkeys
+ スキップ
+ Flow Launcherへようこそ
+ こんにちは!Flow Launcherを初めて起動されたんですね!
+ 開始する前に、このウィザードが Flow Launcher のセットアップをお手伝いします。ご希望の方はスキップできます。言語を選択してください。
+ PC上のファイルとアプリケーションの検索と実行
+ アプリケーション、ファイル、ブックマーク、YouTube、X などあらゆるものを検索して実行できます。マウスに触れることなく、キーボードだけで快適に操作できます。
+ Flow Launcher は以下のホットキーで起動します。さっそく試してみてください。変更するには、入力欄をクリックし、キーボードで希望のホットキーを押してください。
+ ホットキー
Action Keyword and Commands
Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.
Let's Start Flow Launcher
diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml
index 3aee3f5e4aa..9ae2e0195ea 100644
--- a/Flow.Launcher/Languages/ko.xaml
+++ b/Flow.Launcher/Languages/ko.xaml
@@ -18,7 +18,7 @@
Failed to register hotkey "{0}". The hotkey may be in use by another program. Change to a different hotkey, or exit another program.
- Failed to unregister hotkey "{0}". Please try again or see log for details
+ 단축키 "{0}" 등록 해제에 실패했습니다. 다시 시도하시거나 로그를 확인하세요
Flow Launcher
{0}을 실행할 수 없습니다.
Flow Launcher 플러그인 파일 형식이 유효하지 않습니다.
@@ -42,6 +42,7 @@
게임 모드
단축키 사용을 일시중단합니다.
창 위치 초기화
+ 검색창 위치 초기화
검색어 입력
@@ -105,15 +106,27 @@
항상 미리보기
Flow 사용시 항상 미리보기 패널을 열어둡니다. {0} 키를 눌러 프리뷰창을 켜고 끌 수 있습니다.
반투명 흐림 효과를 사용하는 경우, 그림자 효과를 쓸 수 없습니다.
- Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
- Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ 검색 지연
+ 타이핑 중 UI 깜빡임과 결과 로드를 줄이기 위해 짧은 지연을 추가합니다. 타이핑 속도가 평균 수준이라면 권장합니다.
+ 입력이 완료된 것으로 감지될 때까지의 대기 시간(밀리초 단위)을 입력하세요. 이 항목은 검색 지연이 활성화된 경우에만 편집할 수 있습니다.
+ 기본 검색 지연 시간
+ 입력이 멈춘 후 결과를 표시하기까지의 대기 시간입니다. 값이 클수록 더 오래 기다립니다. (ms)
+ 한국어 IME 사용 안내
+
+ Windows 11에서 사용하는 한국어 IME가 Flow Launcher에서 일부 문제를 일으킬 수 있습니다. 문제가 발생하는 경우, “이전 버전의 Microsoft IME 사용” 옵션을 활성화해야 할 수 있습니다. Windows 11 설정을 열고 다음으로 이동하세요: 시간 및 언어 > 언어 및 지역 > 한국어 > 언어 옵션 > 키보드 옵션 – Microsoft IME > 호환성에서 “이전 버전의 Microsoft IME 사용"을 켭니다.
+
+
+
+ 시스템의 시간 및 언어 설정 열기
+ 한국어 IME 설정 위치를 엽니다. 한국어>언어 옵션>키보드 - Microsoft IME> 호환성으로 이동하세요
+ 열기
+ 이전 버전의 Microsoft IME 사용
+ 이전 버전의 IME를 사용하도록 시스템 설정을 변경합니다
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
플러그인 검색
@@ -130,8 +143,13 @@
현재 액션 키워드
새 액션 키워드
액션 키워드 변경
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ 고급 설정:
+ 켬
+ 중요
+ 검색 지연
+ Home Page
현재 중요도:
새 중요도:
중요도
@@ -147,7 +165,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
플러그인 스토어
@@ -172,18 +189,21 @@
안녕하세요!
탐색기
Search for files, folders and file contents
- WebSearch
- Search the web with different search engine support
+ 웹 검색
+ 다양한 검색 엔진을 통해 웹을 검색합니다
프로그램
Launch programs as admin or a different user
- ProcessKiller
- Terminate unwanted processes
+ 프로세스 킬러
+ 필요없는 프로세스를 종료합니다
검색창 높이
결과 항목 높이
쿼리 상자 글꼴
결과 제목 글꼴
결과 부제목 글꼴
초기화
+ 권장되는 글꼴 및 크기 설정으로 초기화 합니다.
+ 테마 크기 가져오기
+ 테마 디자이너가 의도한 크기 값이 존재하는 경우, 해당 값을 불러와 적용합니다.
사용자 지정
윈도우 모드
투명도
@@ -211,19 +231,20 @@
시계
날짜
배경 효과 타입
- Backdrop supported starting from Windows 11 build 22000 and above
+ 프리뷰 영역에선 배경효과가 적용되지 않아요.
+ 배경 효과는 윈도우 11 빌드 22000 이상부터 지원합니다
없음
아크릴
- Mica
- Mica Alt
- This theme supports two(light/dark) modes.
- This theme supports Blur Transparent Background.
+ 마이카
+ 마이카 변형
+ This theme supports two (light/dark) modes.
+ 이 테마는 흐릿한 배경 효과를 지원합니다.
안내 텍스트 표시
입력 내용이 없을때 입력창 위치를 알 수 있는 텍스트를 표시합니다
안내 텍스트
안내 텍스트를 변경하세요. 아무것도 입력하지 않으면 다음을 사용합니다: "{0}"
- Fixed Window Size
- The window size is not adjustable by dragging.
+ 창 크기 고정
+ 창 크기를 드래그하여 조절할 수 없습니다.
단축키
@@ -233,13 +254,13 @@
미리보기 전환
미리보기 패널을 켜고 끌 때 사용할 단축키를 입력하세요.
단축키 프리셋
- List of currently registered hotkeys
+ 현재 등록된 단축키 목록
결과 선택 단축키
결과 항목을 선택하는 단축키입니다.
단축키 표시
결과창에서 결과 선택 단축키를 표시합니다.
자동 완성
- Runs autocomplete for the selected items.
+ 선택된 항목에 대해 자동 완성을 실행합니다.
다음 항목 선택
이전 항목 선택
다음 페이지
@@ -247,7 +268,7 @@
이전 쿼리로 전환
다음 쿼리로 전환
콘텍스트 메뉴 열기
- Open Native Context Menu
+ 시스템 우클릭 메뉴 열기
설정창 열기
파일 경로 복사
게임 모드 전환
@@ -283,6 +304,9 @@
플루언트 아이콘 사용
결과 및 일부 메뉴에서 플루언트 아이콘을 사용합니다.
사용할 키를 누르세요
+ 결과 뱃지 표시
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ 전역 검색 결과에서만 뱃지 표시
HTTP 프록시
@@ -323,21 +347,23 @@
로그 폴더
로그 삭제
정말 모든 로그를 삭제하시겠습니까?
- Clear Caches
- Are you sure you want to delete all caches?
+ Cache Folder
+ 캐시 지우기
+ 모든 캐시를 삭제하시겠습니까?
Failed to clear part of folders and files. Please see log file for more information
마법사
사용자 데이터 위치
사용자 설정과 설치된 플러그인은 사용자 데이터 폴더에 저장됩니다. 이 위치는 휴대용 모드 활성화 여부에 따라 달라질 수 있습니다.
폴더 열기
- Log Level
+ 로그 레벨
Debug
Info
+ Setting Window Font
파일관리자 선택
- Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files.
- For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank.
+ 사용 중인 파일 관리자의 파일 위치를 지정하고, 필요한 경우 인수를 추가하세요. "%d"는 열고자 하는 디렉터리 경로를 나타내며, 폴더용 인수 필드 및 특정 디렉터리를 여는 명령어에서 사용됩니다. "%f"는 열고자 하는 파일 경로를 나타내며, 파일용 인수 필드 및 특정 파일을 여는 명령어에서 사용됩니다.
+ 예를 들어, 파일 관리자가 totalcmd.exe /A c:\windows와 같은 명령어로 c:\windows 디렉터리를 연다면, 파일 관리자 경로는 totalcmd.exe가 되고, 폴더용 인수는 /A "%d"가 됩니다. QTTabBar와 같은 일부 파일 관리자는 경로만 전달하면 되는 경우가 있으므로, 이 경우에는 파일 관리자 경로에 "%d"를 입력하고 나머지 필드는 비워두세요.
파일관리자
프로필 이름
파일관리자 경로
@@ -367,16 +393,19 @@
플러그인을 찾을 수 없습니다.
새 액션 키워드를 입력하세요.
새 액션 키워드가 할당된 플러그인이 이미 있습니다. 다른 액션 키워드를 입력하세요.
- This new Action Keyword is the same as old, please choose a different one
+ 이 새로운 액션 키워드는 기존 것과 동일합니다. 다른 키워드를 선택해주세요.
성공
성공적으로 완료했습니다.
+ Failed to copy
플러그인을 실행할 때 사용할 액션 키워드를 입력하세요. 여러 개를 입력할 경우 공백으로 구분하세요. 아무 키워드도 지정하지 않으려면 * 를 입력하세요. 이 경우 액션 키워드 없이도 플러그인이 실행됩니다.
- Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ 검색 지연 시간 설정
+ 플러그인에서 사용할 검색 지연 시간(ms)을 입력하세요. 지정하지 않으려면 비워두세요. 기본 검색 지연 시간이 사용됩니다.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
사용자지정 쿼리 단축키
@@ -389,7 +418,7 @@
Current hotkey is unavailable.
This hotkey is reserved for "{0}" and can't be used. Please choose another hotkey.
This hotkey is already in use by "{0}". If you press "Overwrite", it will be removed from "{0}".
- Press the keys you want to use for this function.
+ 이 기능에 사용할 키를 눌러주세요.
사용자 지정 쿼리 단축어
@@ -403,13 +432,13 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
저장
- Overwrite
+ 덮어쓰기
취소
- Reset
+ 초기화
삭제
확인
- Yes
- No
+ 예
+ 아니오
배경
diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml
index b78bcb7d718..58571a1c48e 100644
--- a/Flow.Launcher/Languages/nb.xaml
+++ b/Flow.Launcher/Languages/nb.xaml
@@ -42,6 +42,7 @@
Spillmodus
Stopp bruken av hurtigtaster.
Tilbakestilling av posisjon
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Feil ved å sette kjør ved oppstart
Skjul Flow Launcher når fokus forsvinner
Ikke vis varsler om nye versjoner
- Posisjon til søkevindu
+ Search Window Location
Husk siste posisjon
Skjerm med musepekeren
Skjerm med fokusert vindu
@@ -106,14 +107,35 @@
Åpne alltid forhåndsvisningspanel når Flow aktiveres. Trykk på {0} for å velge forhåndsvisning.
Skyggeeffekt er ikke tillatt mens gjeldende tema har uskarphet-effekt aktivert
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Åpne
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Søk etter programtillegg
@@ -130,8 +152,13 @@
Nåværende handlingsnøkkelord
Nytt handlingsnøkkelord
Endre handlingsnøkkelord
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Aktivert
+ Prioritet
+ Search Delay
+ Home Page
Gjeldende prioritet
Ny prioritet
Prioritet
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Programtillegg butikk
@@ -184,6 +210,9 @@
Skrift for resultattittel
Skrift for resultatundertittel
Tilbakestill
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Tilpass
Vindumodus
Ugjennomsiktighet
@@ -211,12 +240,13 @@
Klokke
Dato
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Ingen
Acrylic
Mica
Mica Alt
- Dette temaet støtter to (lys/mørk) moduser.
+ This theme supports two (light/dark) modes.
Dette temaet støtter uskarp gjennomsiktig bakgrunn.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Bruk Segoe Fluent ikoner
Bruk Segoe Fluent Icons for spørreresultater der det støttes
Trykk tast
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP proxy
@@ -323,6 +356,7 @@
Loggmappe
Tøm logger
Er du sikker på at du vil slette alle loggene?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Velg filbehandler
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Vellykket
Fullført vellykket
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Hurtigtast for egendefinert spørring
diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml
index ce340614218..70a58e32253 100644
--- a/Flow.Launcher/Languages/nl.xaml
+++ b/Flow.Launcher/Languages/nl.xaml
@@ -42,6 +42,7 @@
Spelmodus
Stop het gebruik van Sneltoetsen.
Positie resetten
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Fout bij het instellen van uitvoeren bij opstarten
Verberg Flow Launcher als focus verloren is
Laat geen nieuwe versie notificaties zien
- Positie Zoekvenster
+ Search Window Location
Laatste Positie Onthouden
Monitor met Muiscursor
Monitor met Gefocust Venster
@@ -106,14 +107,35 @@
Open altijd het voorbeeld paneel wanneer Flow activeert. Druk op {0} om voorbeeld te schakelen.
Schaduw effect is niet toegestaan omdat het huidige thema een vervagingseffect heeft
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Openen
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Plug-ins zoeken
@@ -130,8 +152,13 @@
Huidige actie sneltoets
Nieuw actie sneltoets
Wijzig actie-sneltoets
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Priority
+ Search Delay
+ Home Page
Huidige Prioriteit
Nieuwe Prioriteit
Prioriteit
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Plugin Winkel
@@ -184,6 +210,9 @@
Resultaat titel lettertype
Result Subtitle Font
Herstellen
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Aanpassen
Venster Modus
Ondoorzichtigheid
@@ -211,12 +240,13 @@
Klok
Datum
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- Dit thema ondersteunt twee (licht/donker) modi.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Gebruik Segoe Fluent pictogrammen
Gebruik Segoe Fluent iconen voor zoekresultaten wanneer ondersteund
Press Key
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP Proxy
@@ -323,6 +356,7 @@
Log Map
Logbestanden wissen
Weet u zeker dat u alle logbestanden wilt verwijderen?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Bestandsbeheerder selecteren
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Succesvol
Succesvol afgerond
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Custom Query Sneltoets
diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml
index 12af37c3ed9..7cc6dfcb145 100644
--- a/Flow.Launcher/Languages/pl.xaml
+++ b/Flow.Launcher/Languages/pl.xaml
@@ -8,9 +8,9 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Wybierz plik wykonywalny {0}
- Your selected {0} executable is invalid.
+ Wybrany plik wykonywalny {0} jest nieprawidłowy.
{2}{2}
- Click yes if you would like select the {0} executable agian. Click no if you would like to download {1}
+ Kliknij Tak, jeśli chcesz ponownie wybrać plik wykonywalny {0}. Kliknij Nie, jeśli chcesz pobrać {1}
Nie można ustawić ścieżki do pliku wykonywalnego {0}. Spróbuj ponownie w ustawieniach Flow (przewiń na sam dół).
Nie udało się zainicjować wtyczek
@@ -42,7 +42,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Tryb grania
Wstrzymaj używanie skrótów.
Resetowanie pozycji
- Type here to search
+ Zresetuj pozycję okna wyszukiwania
+ Wpisz tutaj, aby wyszukać
Ustawienia
@@ -105,15 +106,36 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Zawsze podgląd
Zawsze otwieraj panel podglądu, gdy aktywowany jest Flow. Naciśnij {0}, aby przełączyć podgląd.
Efekt cienia jest niedozwolony, gdy bieżący motyw ma włączony efekt rozmycia
- Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
- Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Opóźnienie wyszukiwania
+ Dodaje krótkie opóźnienie podczas pisania, aby zmniejszyć migotanie interfejsu i obciążenie wynikami. Zalecane przy przeciętnej szybkości pisania.
+ Wprowadź czas oczekiwania (w ms), po którym wprowadzanie zostanie uznane za zakończone. Edycja jest możliwa tylko, gdy włączone jest Opóźnienie wyszukiwania.
+ Domyślne opóźnienie wyszukiwania
+ Opóźnienie (ms) przed pokazaniem wyników po zakończeniu pisania. Wyższe wartości oznaczają dłuższe oczekiwanie.
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Otwórz
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Szukaj wtyczek
@@ -130,8 +152,13 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Bieżące słowo kluczowe akcji
Nowe słowo kluczowe akcji
Zmień słowa kluczowe akcji
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Opóźnienie wyszukiwania wtyczek
+ Zmień opóźnienie wyszukiwania wtyczek
+ Ustawienia zaawansowane:
+ Aktywny
+ Priorytet
+ Opóźnienie wyszukiwania
+ Home Page
Obecny Priorytet
Nowy Priorytet
Priorytet
@@ -145,9 +172,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Odinstalowywanie
Nie udało się usunąć ustawień wtyczki
Wtyczki: {0} – nie udało się usunąć plików ustawień wtyczek, usuń je ręcznie
- Fail to remove plugin cache
- Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
+ Nie udało się usunąć cache wtyczki
+ Wtyczki: {0} - Nie udało się usunąć plików cache wtyczki, usuń je ręcznie
Sklep z wtyczkami
@@ -184,6 +210,9 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Czcionka tytułu wyniku
Czcionka podtytułu wyniku
Resetuj
+ Przywróć zalecane ustawienia czcionki i rozmiaru.
+ Rozmiar importu motywu
+ Jeśli wartość rozmiaru przewidziana przez projektanta motywu jest dostępna, zostanie pobrana i zastosowana.
Personalizuj
Tryb w oknie
Przeźroczystość
@@ -210,20 +239,21 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Niestandardowa
Zegar
Data
- Backdrop Type
- Backdrop supported starting from Windows 11 build 22000 and above
+ Typ tła
+ Efekt tła nie jest stosowany w podglądzie.
+ Efekt tła obsługiwany od Windows 11 kompilacja 22000 i nowszych
Brak
- Acrylic
- Mica
+ Akryl
+ Mika
Mica Alt
Ten motyw obsługuje dwa tryby (jasny/ciemny).
Ten motyw obsługuje rozmyte przezroczyste tło.
- Show placeholder
- Display placeholder when query is empty
- Placeholder text
- Change placeholder text. Input empty will use: {0}
- Fixed Window Size
- The window size is not adjustable by dragging.
+ Pokaż placeholder
+ Wyświetlaj placeholder, gdy zapytanie jest puste
+ Tekst placeholdera
+ Zmień tekst placeholdera. Jeśli pole będzie puste, zostanie użyty: {0}
+ Stały rozmiar okna
+ Nie można zmienić rozmiaru okna, przeciągając.
Skrót klawiszowy
@@ -283,6 +313,9 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Użyj ikon Segoe Fluent
Użyj ikon Segoe Fluent dla wyników wyszukiwania, gdzie jest to obsługiwane
Naciśnij klawisz
+ Pokaż odznaki wyników
+ W przypadku wspieranych wtyczek wyświetlane są odznaki, aby łatwiej je rozróżnić.
+ Pokaż odznaki wyników tylko dla zapytań globalnych
Serwer proxy HTTP
@@ -323,16 +356,18 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Folder dziennika
Wyczyść logi
Czy na pewno chcesz usunąć wszystkie logi?
- Clear Caches
- Are you sure you want to delete all caches?
- Failed to clear part of folders and files. Please see log file for more information
+ Cache Folder
+ Wyczyść pamięć podręczną
+ Czy na pewno chcesz usunąć wszystkie pamięci podręczne?
+ Nie udało się wyczyścić części folderów i plików. Więcej informacji w pliku dziennika
Kreator
Lokalizacja danych użytkownika
Ustawienia użytkownika i zainstalowane wtyczki są zapisywane w folderze danych użytkownika. Ta lokalizacja może się różnić w zależności od tego, czy aplikacja jest w trybie przenośnym, czy nie.
Otwórz folder
- Log Level
+ Poziom logowania
Debug
Info
+ Ustawienia czcionki okna
Wybierz menedżer plików
@@ -367,16 +402,19 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros
Nie można odnaleźć podanej wtyczki
Nowy wyzwalacz nie może być pusty
Ten wyzwalacz został już przypisany do innej wtyczki, musisz podać inny wyzwalacz.
- This new Action Keyword is the same as old, please choose a different one
+ Nowe słowo kluczowe akcji jest takie samo jak poprzednie. Wybierz inne
Sukces
Zakończono pomyślnie
- Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
+ Failed to copy
+ Wpisz słowa kluczowe uruchamiające wtyczkę (oddzielone spacją). Wpisz *, aby uruchamiać wtyczkę bez słów kluczowych.
+
+
+ Ustawienie opóźnienia wyszukiwania
+ Podaj czas opóźnienia wyszukiwania (w ms) dla wtyczki. Pozostaw puste, aby użyć wartości domyślnej.
- Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Skrót klawiszowy niestandardowych zapyta
diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml
index d0040d7995d..bd74d1d5fec 100644
--- a/Flow.Launcher/Languages/pt-br.xaml
+++ b/Flow.Launcher/Languages/pt-br.xaml
@@ -42,6 +42,7 @@
Modo Gamer
Suspender o uso de Teclas de Atalho.
Redefinição de Posição
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Erro ao ativar início com o sistema
Esconder Flow Launcher quando foco for perdido
Não mostrar notificações de novas versões
- Posição da Janela de Busca
+ Search Window Location
Lembrar Última Posição
Monitor com o Cursor do Mouse
Monitor com Janela em Foco
@@ -106,14 +107,35 @@
Sempre abrir o painel de pré-visualização quando o Flow é ativado. Pressione {0} para ativar ou desativar a pré-visualização.
O efeito de sombra não é permitido enquanto o tema atual tem o efeito de desfoque ativado
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Abrir
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Buscar Plugin
@@ -130,8 +152,13 @@
Palavra-chave de ação atual
Nova palavra-chave de ação
Alterar Palavras-chave de Ação
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Prioridade
+ Search Delay
+ Home Page
Prioridade atual
Nova Prioridade
Prioridade
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Loja de Plugins
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Modo Janela
Opacidade
@@ -211,12 +240,13 @@
Relógio
Data
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Usar Segoe Fluent Icons
Usar Segoe Fluent Icons para resultados da consulta quando suportado
Apertar Tecla
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
Proxy HTTP
@@ -323,6 +356,7 @@
Pasta de Registro
Limpar Registros
Tem certeza que quer excluir todos os registros?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Selecione o Gerenciador de Arquivos
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Sucesso
Concluído com sucesso
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Atalho de Consulta Personalizada
diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml
index 9dc520cbd7e..cf73129565d 100644
--- a/Flow.Launcher/Languages/pt-pt.xaml
+++ b/Flow.Launcher/Languages/pt-pt.xaml
@@ -42,6 +42,7 @@
Modo de jogo
Suspender utilização das teclas de atalho
Repor posição
+ Repor posição da janela de pesquisa
Escreva aqui para pesquisar
@@ -106,14 +107,34 @@
Abrir painel de pré-visualização ao ativar Flow Launcher. Prima {0} para comutar a pré-visualização.
O efeito sombra não é permitido com este tema porque o efeito desfocar está ativo
Atraso da pesquisa
- Tempo a esperar após a digitação. Esta definição melhora o carregamento dos resultados.
+ Adiciona um pequeno atraso durante a escrita para reduzir a oscilação ao carregar os resultados. Recomendado se a sua velocidade de escrita for média.
+ Introduza o tempo de espera (ms) até que a entrada seja considerada completa. Apenas pode editar se ativara opção Atraso de pesquisa.
Tempo de espera padrão
- O valor padrão a esperar, antes de iniciar a pesquisa após terminar a digitação.
- Muito longo
- Longo
- Normal
- Curto
- Muito curto
+ Tempo a aguardar antes de mostrar os resultados. Valores mais altos resultam num atraso maior (ms).
+ Informações para utilizadores coreanos
+
+ O método de introdução Coreano em sistemas Windows 11 pode causar erros no Flow Launcher.
+
+ Se estiver a sofrer problemas, pode ser necessário ativar "Utilizar versão anterior do IME Coreano".
+
+ Abra as definições no seu sistema e aceda a:
+
+ Hora e Idioma > Idioma e Região > Coreano > Opções de idioma > Teclado - Microsoft IME > Compatibilidade
+
+ e ative "Utilizar versão anterior de Microsoft IME".
+
+
+
+ Abrir definições de Idioma e Região
+ Abra a definição do método de introdução coreano. Aceda a Corano > Opções de idioma > Teclado - Microsoft IME > Compatibilidade
+ Abrir
+ Utilizar versão anterior de IME Coreano
+ Pode alterar as definições do método de introdução coreano aqui
+ Página inicial
+ Mostrar resultados da página inicial se o termo de pesquisa estiver vazio.
+ Mostrar histórico na página inicial
+ Máximo de resultados a mostrar na Página inicial
+ Esta opção apenas pode ser editada se o plugin tiver suporte a Página inicial e se estiver ativo.
Pesquisar plugins
@@ -132,6 +153,11 @@
Alterar palavras-chave
Tempo de espera do plugin
Alterar tempo de espera do plugin
+ Definições avançadas:
+ Ativo
+ Prioridade
+ Atraso da pesquisa
+ Página inicial
Prioridade atual
Nova prioridade
Prioridade
@@ -147,7 +173,6 @@
Plugin: {0} - Falha ao remover o ficheiro de definições do plugin. Experimente remover manualmente.
Falha ao limpar a cache do plugin
Plugin: {0} - Falha ao remover os ficheiros em cache do plugin. Experimente remover manualmente.
- Padrão
Loja de plugins
@@ -184,6 +209,9 @@
Tipo de letra dos títulos
Tipo de letra dos subtítulos
Repor
+ Repor definições recomendadas para fontes e tamanho.
+ Tamanho do tema importado
+ Se o programador do tema tiver disponibilizado o valor, este será utilizado.
Personalizar
Modo da janela
Opacidade
@@ -211,6 +239,7 @@
Relógio
Data
Tipo de fundo
+ O efeito de fundo não é aplicado na pré-visualização.
Esta opção apenas está disponível em sistemas após Windows 11 Build 22000
Nenhuma
Acrílico
@@ -283,6 +312,9 @@
Utilizar ícones Segoe Fluent
Se possível, utilizar ícones Segoe Fluent para os resultados
Prima a tecla
+ Mostrar emblemas dos resultados
+ Para plugins suportados, são mostrados emblemas para nos ajudar a distingui-los mais facilmente.
+ Mostrar emblemas apenas para a consulta global
Proxy HTTP
@@ -322,6 +354,7 @@
Pasta de registos
Limpar registos
Tem a certeza de que deseja remover todos os registos?
+ Pasta de cache
Limpar cache
Tem a certeza de que pretende limpar todas as caches?
Não foi possível limpar todas as pastas e ficheiros. Consulte o ficheiro de registo para mais informações.
@@ -332,6 +365,7 @@
Nível de registo
Depuração
Informação
+ Setting Window Font
Selecione o gestor de ficheiros
@@ -369,13 +403,16 @@
A palavra-chave escolhida é igual à anterior. Por favor escolha outra.
Sucesso
Terminado com sucesso
+ Falha ao copiar
Introduza as palavras-chave que pretende utilizar para iniciar o plugin e um espaço vazio caso queira mais do que uma. Utilize * se não quiser especificar uma palavra-chave e o plugin será ativado sem palavras-chave.
Definição do tempo de espera
- Selecione o tempo de espera que pretende utilizar com este plugin. Selecione "{0}" se não o quiser especificar e, desta forma, o plugin irá utilizar o tempo de espera padrão.
- Tempo de espera atual
- Novo tempo de espera
+ Indique o tempo de espera que pretende utilizar com este plugin. Nada escreva se não o quiser especificar e o plugin irá utilizar o tempo de espera padrão.
+
+
+ Página inicial
+ Ative o plugin Página inicial se quiser mostrar os seus resultados so termo de pesquisa estiver vazio.
Tecla de atalho personalizada
diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml
index c38855474ba..69069c5eca5 100644
--- a/Flow.Launcher/Languages/ru.xaml
+++ b/Flow.Launcher/Languages/ru.xaml
@@ -42,6 +42,7 @@
Игровой режим
Приостановить использование горячих клавиш.
Сброс положения
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Ошибка настройки запуска при запуске
Скрывать Flow Launcher, если потерян фокуc
Не отображать сообщение об обновлении, когда доступна новая версия
- Положение окна поиска
+ Search Window Location
Запомнить последнее положение
Монитор с курсором мыши
Монитор с фокусированным окном
@@ -106,14 +107,35 @@
Всегда открывать панель предварительного просмотра при запуске Flow. Нажмите {0}, чтобы переключить предварительный просмотр.
Эффект тени не допускается, если в текущей теме включён эффект размытия
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Открыть
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Поиск плагина
@@ -130,8 +152,13 @@
Ключевое слово текущего действия
Ключевое слово нового действия
Изменить ключевое слово действия
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Приоритет
+ Search Delay
+ Home Page
Текущий приоритет
Новый приоритет
Приоритет
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Магазин плагинов
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Оконный режим
Прозрачность
@@ -211,12 +240,13 @@
Часы
Дата
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Использование значков Segoe Fluent
Использовать значки Segoe Fluent для результатов запросов, где они поддерживаются
Нажмите клавишу
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
НТТР-прокси
@@ -323,6 +356,7 @@
Папка журнала
Очистить журнал
Вы уверены, что хотите удалить все журналы?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Выбор менеджера файлов
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Успешно
Выполнено успешно
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Задаваемые горячие клавиши для запросов
diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml
index 0f07387c631..88ed1c9dfcc 100644
--- a/Flow.Launcher/Languages/sk.xaml
+++ b/Flow.Launcher/Languages/sk.xaml
@@ -42,6 +42,7 @@
Herný režim
Pozastaviť používanie klávesových skratiek.
Resetovať pozíciu
+ Resetovať pozíciu vyhľadávacieho okna
Zadajte text na vyhľadávanie
@@ -55,7 +56,7 @@
Chybné nastavenie spustenia pri spustení
Schovať Flow Launcher po strate fokusu
Nezobrazovať upozornenia na novú verziu
- Pozícia vyhľadávacieho okna
+ Poloha vyhľadávacieho okna
Zapamätať si poslednú pozíciu
Monitor s kurzorom myši
Monitor s aktívnym oknom
@@ -106,14 +107,35 @@
Pri aktivácii Flowu vždy otvoriť panel s náhľadom. Stlačením klávesu {0} prepnete náhľad.
Efekt tieňa nie je povolený, kým má aktuálny motív povolený efekt rozostrenia
Oneskorenie vyhľadávania
- Pri písaní sa na chvíľu oneskorí vyhľadávanie. Tým sa zníži skákanie rozhrania a načítanie výsledkov.
+ Pridá krátke oneskorenie počas písania, aby na zníženie blikanie rozhrania počas načítavania. Odporúča sa pri priemernej rýchlosti písania.
+ Zadajte čas (v ms) čakania, kým vstup bude považovaný za ukončený. Úprava je povolená len vtedy, ak je povolené oneskorenie vyhľadávania.
Predvolené oneskorenie vyhľadávania
- Predvolené oneskorenie pluginu, po ktorom sa zobrazia výsledky vyhľadávania po zastavení písania.
- Veľmi dlhé
- Dlhé
- Normálne
- Krátke
- Veľmi krátke
+ Čas čakania pred zobrazením výsledkov po ukončení písania. Pri vyšších hodnotách sa čaká dlhšie. (ms)
+ Informácie pre kórejského používateľa IME
+
+ Kórejská metóda vstupu použitá vo Windows 11 môže spôsobiť určité problémy vo Flow Launcheri.
+
+ Ak sa vyskytnú problémy, možno bude potrebné povoliť "Použiť predchádzajúcu verziu editora Microsoft IME".
+
+
+ Otvorte nastavenia Windows 11 a prejdite do:
+
+ Čas a jazyk > Jazyk a oblasť > Kórejčina> Možnosti jazyka > Klávesnice – Microsoft IME > Možnosti klávesnice – Kompatibilita,
+
+ a povoľte "Predcházdajúca verzia editora Microsoft IME".
+
+
+
+ Otvoriť nastavenia systému Jazyk a oblasť
+ Otvorí okno s nastaveniami kórejského editora Microsoft IME. Prejdite do Kórejčina > Možnosti jazyka > Klávesnice – Microsoft IME > Možnosti klávesnice – Kompatibilita
+ Otvoriť
+ Použiť predchádzajúcu verziu editora Microsoft IME
+ Zmeniť na predchádzajúcu verziu editora Microsoft IME môžete priamo tu
+ Domovská stránka
+ Zobraziť výsledky Domovskej stránky, keď je text dopytu prázdny.
+ Zobraziť výsledky histórie na Domovskej stránke
+ Maximálny počet histórie výsledkov zobrazenej na Domovskej stránke
+ Úprava je možná len vtedy, ak plugin podporuje funkciu Domovská stránka a Domovská stránka je povolená.
Vyhľadať plugin
@@ -130,8 +152,13 @@
Aktuálny aktivačný príkaz
Nový aktivačný príkaz
Upraviť aktivačný príkaz
- Oneskorenie vyhľadávania pomocou pluginu
- Zmení oneskorenie vyhľadávania pomocou pluginu
+ Oneskorenie vyhľadávania pluginu
+ Zmení oneskorenie vyhľadávania pluginu
+ Rozšírené nastavenia:
+ Povolené
+ Priorita
+ Oneskorenie vyhľadávania
+ Domovská stránka
Aktuálna priorita
Nová priorita
Priorita
@@ -147,7 +174,6 @@
Pluginy: {0} – Nepodarilo sa odstrániť súbory s nastaveniami pluginu, odstráňte ich manuálne
Nepodarilo sa odstrániť vyrovnávaciu pamäť pluginu
Pluginy: {0} – Nepodarilo sa odstrániť vyrovnávaciu pamäť pluginu, odstráňte ju manuálne
- Predvolené
Repozitár pluginov
@@ -184,6 +210,9 @@
Písmo nadpisu výsledku
Písmo podnadpisu výsledku
Resetovať
+ Resetuje písmo a jeho veľkosť na predvolené hodnoty.
+ Importovať rozmery motívu
+ Ak je k dispozícii hodnota veľkosti definovaná autorom motívu, načíta sa a použije.
Prispôsobiť
Režim okno
Nepriehľadnosť
@@ -210,8 +239,9 @@
Vlastné
Hodiny
Dátum
- Typ pozadia
- Backdrop je podporovaný od Windows 11 zostava 22000 a novších
+ Typ pozadia (backdrop)
+ Efekt pozadia sa v náhľade nezobrazuje.
+ Pozadie je podporované od Windows 11 zostava 22000 a novších
Žiadna
Acrylic
Mica
@@ -283,6 +313,9 @@
Použiť ikony Segoe Fluent
Použiť ikony Segoe Fluent, ak sú podporované
Stlačte kláves
+ Zobraziť výsledok v odznaku
+ Ak to plugin podporuje, zobrazí sa jeho ikona v odznaku na jednoduchšie odlíšenie.
+ Zobraziť výsledok v odznaku len pre globálne vyhľadávanie
HTTP proxy
@@ -323,6 +356,7 @@
Priečinok s logmi
Vymazať logy
Naozaj chcete odstrániť všetky logy?
+ Priečinok vyrovnávacej pamäte
Vymazať vyrovnávaciu pamäť
Naozaj chcete vymazať všetky vyrovnávacie pamäte?
Nepodarilo sa odstrániť niektoré priečinky a súbory. Pre viac informácií si pozrite súbor logu
@@ -333,6 +367,7 @@
Úroveň logovania
Debug
Info
+ Nastavenie písma okna
Vyberte správcu súborov
@@ -370,13 +405,16 @@
Tento nový aktivačný príkaz je rovnaký ako starý, vyberte iný
Úspešné
Úspešne dokončené
+ Nepodarilo sa skopírovať
Zadajte aktivačné príkazy, ktoré chcete používať na spustenie pluginu a oddeľte ich medzerou. Ak nechcete zadať aktivačný príkaz, použite * a plugin bude spustený bez aktivačného príkazu.
Nastavenie oneskoreného vyhľadávania
- Vyberte oneskorenie vyhľadávania, ktoré chcete použiť pre plugin. Ak vyberiete "{0}", plugin použije predvolené oneskorenie vyhľadávania.
- Aktuálne oneskorenie vyhľadávania
- Nové oneskorenie vyhľadávania
+ Zadajte oneskorenie vyhľadávania v ms, ktoré chcete použiť pre plugin. Nechajte prázdne, ak nechcete zadať žiadne, plugin použije predvolené oneskorenie vyhľadávania.
+
+
+ Domovská stránka
+ Ak chcete zobrazovať výsledky pluginu, keď je dopyt prázdny, povoľte funkciu Domovská stránka.
Klávesová skratka vlastného vyhľadávania
diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml
index 1d1eb912047..4b3e3bc0cf1 100644
--- a/Flow.Launcher/Languages/sr.xaml
+++ b/Flow.Launcher/Languages/sr.xaml
@@ -42,6 +42,7 @@
Game Mode
Suspend the use of Hotkeys.
Position Reset
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Error setting launch on startup
Sakri Flow Launcher kada se izgubi fokus
Ne prikazuj obaveštenje o novoj verziji
- Search Window Position
+ Search Window Location
Remember Last Position
Monitor with Mouse Cursor
Monitor with Focused Window
@@ -106,14 +107,35 @@
Always open preview panel when Flow activates. Press {0} to toggle preview.
Shadow effect is not allowed while current theme has blur effect enabled
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Otvori
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -130,8 +152,13 @@
Current action keyword
New action keyword
Change Action Keywords
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Priority
+ Search Delay
+ Home Page
Current Priority
New Priority
Priority
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Plugin Store
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
Režim prozora
Neprozirnost
@@ -211,12 +240,13 @@
Clock
Date
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Use Segoe Fluent Icons
Use Segoe Fluent Icons for query results where supported
Press Key
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP proksi
@@ -323,6 +356,7 @@
Log Folder
Clear Logs
Are you sure you want to delete all logs?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Select File Manager
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Uspešno
Completed successfully
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
prečica za ručno dodat upit
diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml
index b9b5d351edd..665694acef5 100644
--- a/Flow.Launcher/Languages/tr.xaml
+++ b/Flow.Launcher/Languages/tr.xaml
@@ -42,6 +42,7 @@
Oyun Modu
Kısayol tuşlarının kullanımını durdurun.
Pencere Konumunu Sıfırla
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Sistemle başlatma ayarı başarısız oldu
Odak Pencereden Ayrıldığında Gizle
Güncelleme bildirimlerini gösterme
- Pencere Konumu
+ Search Window Location
Son Konumu Hatırla
Fare İmlecinin Bulunduğu Monitör
Aktif Pencerenin Bulunduğu Monitör
@@ -106,14 +107,35 @@
Önizleme panelini her zaman aç. Önizlemeyi bu ayardan bağımsız {0} kısayolu ile açıp kapatabilirsiniz.
Mevcut temada bulanıklık efekti etkinken gölgelendirme efektine izin verilmez
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Aç
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Eklenti Ara
@@ -130,8 +152,13 @@
Geçerli anahtar kelime
Yeni anahtar kelime
Anahtar kelimeyi değiştir
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Enabled
+ Priority
+ Search Delay
+ Home Page
Mevcut öncelik
Yeni Öncelik
Öncelik
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Eklenti Mağazası
@@ -184,6 +210,9 @@
Arama Sonuçları Yazı Tipi
Arama Sonuçları Yazı Tipi
Sıfırla
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Kişiselleştir
Pencere Modu
Saydamlık
@@ -211,12 +240,13 @@
Saat
Tarih
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Hiçbiri
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Segoe Fluent Simgeleri
Arama sonuçlarında mümkünse Segoe Fluent simgelerini kullan.
Tuşa basın
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
Vekil Sunucu
@@ -323,6 +356,7 @@
Günlük Klasörü
Günlükleri Temizle
Tüm günlük kayıtlarını silmek istediğinize emin misiniz?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Dosya Yöneticisi Seçenekleri
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Başarılı
Başarıyla tamamlandı
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Özel Sorgu Kısayolları
diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml
index 427511c6630..b3dc2cd16f6 100644
--- a/Flow.Launcher/Languages/uk-UA.xaml
+++ b/Flow.Launcher/Languages/uk-UA.xaml
@@ -42,6 +42,7 @@
Режим гри
Призупинити використання гарячих клавіш.
Скидання позиції
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Помилка запуску налаштування під час запуску
Сховати Flow Launcher, якщо втрачено фокус
Не повідомляти про доступні нові версії
- Положення вікна пошуку
+ Search Window Location
Пам'ятати останню позицію
Монітор з курсором миші
Монітор зі сфокусованим вікном
@@ -106,14 +107,35 @@
Завжди відкривати панель попереднього перегляду при активації Flow. Натисніть {0}, щоб переключити попередній перегляд.
Ефект тіні не дозволено, коли поточна тема має ефект розмиття
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Відкрити
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Плагін для пошуку
@@ -130,8 +152,13 @@
Поточна гаряча клавіша
Нова гаряча клавіша
Змінити гарячі клавіши
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Увімкнено
+ Пріоритет
+ Search Delay
+ Home Page
Поточний пріоритет
Новий пріоритет
Пріоритет
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Магазин плагінів
@@ -184,6 +210,9 @@
Шрифт заголовка результату
Шрифт підзаголовка результату
Скинути
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Підлаштувати
Віконний режим
Прозорість
@@ -211,12 +240,13 @@
Годинник
Дата
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Нема
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
Ця тема підтримує розмитий прозорий фон.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Використання іконок Segoe Fluent
Використання іконок Segoe Fluent Icons для результатів запитів, де це підтримується
Натисніть клавішу
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP-проксі
@@ -323,6 +356,7 @@
Тека журналу
Очистити журнали
Ви впевнені, що хочете видалити всі журнали?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
Виберіть файловий менеджер
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
Успішно
Успішно завершено
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Задані гарячі клавіші для запитів
diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml
index 6223efc0006..b7b56213b45 100644
--- a/Flow.Launcher/Languages/vi.xaml
+++ b/Flow.Launcher/Languages/vi.xaml
@@ -42,6 +42,7 @@
Chế độ trò chơi
Tạm dừng sử dụng phím nóng.
Đặt lại vị trí
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Không lưu được tính năng tự khởi động khi khởi động hệ thống
Ẩn Flow Launcher khi mất tiêu điểm
Không hiển thị thông báo khi có phiên bản mới
- Vị trí Suchfenster
+ Search Window Location
Ghi nhớ vị trí cuối cùng
Màn hình bằng con trỏ chuột
Màn hình có cửa sổ được tập trung
@@ -106,14 +107,35 @@
Luôn mở bảng xem trước khi Flow kích hoạt. Nhấn {0} để chuyển đổi chế độ xem trước.
Hiệu ứng đổ bóng không được phép nếu chủ đề hiện tại bật hiệu ứng làm mờ
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ Mở
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Plugin tìm kiếm
@@ -130,8 +152,13 @@
Từ hành động hiện tại
Từ hành động mới
Thay đổi từ hành động
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ Đã bật
+ Ưu tiên
+ Search Delay
+ Home Page
Ưu tiên hiện tại
Ưu tiên mới
Ưu tiên
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
Tải tiện ích mở rộng
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Đặt lại
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
chế độ cửa sổ
độ mờ
@@ -211,12 +240,13 @@
Giờ
Ngày
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
Không
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
Sử dụng biểu tượng Segoe
Sử dụng Biểu tượng Segoe Fluent cho kết quả truy vấn nếu được hỗ trợ
Nhấn phím
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
Proxy HTTP
@@ -325,6 +358,7 @@
Thư mục nhật ký
Xóa tệp nhật ký
Bạn có chắc chắn muốn xóa tất cả nhật ký không?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -335,6 +369,7 @@
Log Level
Debug
Info
+ Setting Window Font
Chọn trình quản lý tệp
@@ -372,13 +407,16 @@
This new Action Keyword is the same as old, please choose a different one
Thành công
Đã hoàn tất thành công
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
Phím nóng truy vấn tùy chỉnh
diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml
index 3d302da5ba1..bd314299210 100644
--- a/Flow.Launcher/Languages/zh-cn.xaml
+++ b/Flow.Launcher/Languages/zh-cn.xaml
@@ -42,6 +42,7 @@
游戏模式
暂停使用热键。
重置位置
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
设置开机自启时出错
失去焦点时自动隐藏 Flow Launcher
不显示新版本提示
- 搜索窗口位置
+ Search Window Location
记住上次的位置
鼠标光标所在显示器
聚焦窗口所在显示器
@@ -106,14 +107,35 @@
Flow 启动时总是打开预览面板。按 {0} 以切换预览。
当前主题已启用模糊效果,不允许启用阴影效果
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ 打开
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
搜索插件
@@ -130,8 +152,13 @@
当前触发关键字
新触发关键字
更改触发关键字
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ 启用
+ 优先级
+ Search Delay
+ Home Page
当前优先级
新优先级
优先级
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
插件商店
@@ -184,6 +210,9 @@
结果标题字体
结果字幕字体
重置
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
自定义
窗口模式
透明度
@@ -211,12 +240,13 @@
时钟
日期
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
无
Acrylic
Mica
Mica Alt
- 该主题支持两种(浅色/深色)模式。
+ This theme supports two (light/dark) modes.
该主题支持模糊透明背景。
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
使用 Segoe Fluent 图标
在支持时在选项中显示 Segoe Fluent 图标
按下按键
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP 代理
@@ -323,6 +356,7 @@
日志目录
清除日志
你确定要删除所有的日志吗?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
默认文件管理器
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
成功
成功完成
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
自定义查询热键
diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml
index cecad8e0dcb..1a71ae13500 100644
--- a/Flow.Launcher/Languages/zh-tw.xaml
+++ b/Flow.Launcher/Languages/zh-tw.xaml
@@ -42,6 +42,7 @@
遊戲模式
暫停使用快捷鍵。
重設位置
+ Reset search window position
Type here to search
@@ -55,7 +56,7 @@
Error setting launch on startup
失去焦點時自動隱藏 Flow Launcher
不顯示新版本提示
- 搜尋視窗位置
+ Search Window Location
記住最後位置
Monitor with Mouse Cursor
Monitor with Focused Window
@@ -106,14 +107,35 @@
當 Flow 啟動時,一律開啟預覽面板。按下 {0} 可切換預覽。
Shadow effect is not allowed while current theme has blur effect enabled
Search Delay
- Delay for a while to search when typing. This reduces interface jumpiness and result load.
+ Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.
+ Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.
Default Search Delay Time
- Plugin default delay time after which search results appear when typing is stopped.
- Very long
- Long
- Normal
- Short
- Very short
+ Wait time before showing results after typing stops. Higher values wait longer. (ms)
+ Information for Korean IME user
+
+ The Korean input method used in Windows 11 may cause some issues in Flow Launcher.
+
+ If you experience any problems, you may need to enable "Use previous version of Korean IME".
+
+
+ Open Setting in Windows 11 and go to:
+
+ Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility,
+
+ and enable "Use previous version of Microsoft IME".
+
+
+
+ Open Language and Region System Settings
+ Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility
+ 開啟
+ Use Previous Korean IME
+ You can change the Previous Korean IME settings directly from here
+ Home Page
+ Show home page results when query text is empty.
+ Show History Results in Home Page
+ Maximum History Results Shown in Home Page
+ This can only be edited if plugin supports Home feature and Home Page is enabled.
Search Plugin
@@ -130,8 +152,13 @@
目前觸發關鍵字
新觸發關鍵字
更改觸發關鍵字
- Plugin seach delay time
- Change Plugin Seach Delay Time
+ Plugin search delay time
+ Change Plugin Search Delay Time
+ Advanced Settings:
+ 已啟用
+ 優先
+ Search Delay
+ Home Page
目前優先
新增優先
優先
@@ -147,7 +174,6 @@
Plugins: {0} - Fail to remove plugin settings files, please remove them manually
Fail to remove plugin cache
Plugins: {0} - Fail to remove plugin cache files, please remove them manually
- Default
插件商店
@@ -184,6 +210,9 @@
Result Title Font
Result Subtitle Font
Reset
+ Reset to the recommended font and size settings.
+ Import Theme Size
+ If a size value intended by the theme designer is available, it will be retrieved and applied.
Customize
視窗模式
透明度
@@ -211,12 +240,13 @@
時鐘
日期
Backdrop Type
+ The backdrop effect is not applied in the preview.
Backdrop supported starting from Windows 11 build 22000 and above
None
Acrylic
Mica
Mica Alt
- This theme supports two(light/dark) modes.
+ This theme supports two (light/dark) modes.
This theme supports Blur Transparent Background.
Show placeholder
Display placeholder when query is empty
@@ -283,6 +313,9 @@
使用 Segoe Fluent 圖示
在支援的情況下,在查詢結果使用 Segoe Fluent 圖示
按下按鍵
+ Show Result Badges
+ For supported plugins, badges are displayed to help distinguish them more easily.
+ Show Result Badges for Global Query Only
HTTP 代理
@@ -323,6 +356,7 @@
日誌資料夾
清除日誌
請確認要刪除所有日誌嗎?
+ Cache Folder
Clear Caches
Are you sure you want to delete all caches?
Failed to clear part of folders and files. Please see log file for more information
@@ -333,6 +367,7 @@
Log Level
Debug
Info
+ Setting Window Font
選擇檔案管理器
@@ -370,13 +405,16 @@
This new Action Keyword is the same as old, please choose a different one
成功
成功完成
+ Failed to copy
Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.
Search Delay Time Setting
- Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.
- Current search delay time
- New search delay time
+ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time.
+
+
+ Home Page
+ Enable the plugin home page state if you like to show the plugin results when query is empty.
自定義快捷鍵查詢
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
index d278faf98ed..e553a1b7e5f 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ja.xaml
@@ -2,8 +2,8 @@
- Browser Bookmarks
- Search your browser bookmarks
+ ブラウザブックマーク
+ ブラウザのブックマークを検索します
Bookmark Data
@@ -12,16 +12,16 @@
New tab
Set browser from path:
Choose
- Copy url
- Copy the bookmark's url to clipboard
+ URLをコピー
+ ブックマークのURLをクリップボードにコピー
Load Browser From:
Browser Name
Data Directory Path
- 追
- 編
+ 追加
+ 編集
削除
Browse
- Others
+ その他のブラウザ
Browser Engine
If you are not using Chrome, Firefox or Edge, or you are using their portable version, you need to add bookmarks data directory and select correct browser engine to make this plugin work.
For example: Brave's engine is Chromium; and its default bookmarks data location is: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". For Firefox engine, the bookmarks directory is the userdata folder contains the places.sqlite file.
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
index 93916ffaa01..a374e7fc18b 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/ko.xaml
@@ -12,8 +12,8 @@
새 탭
Set browser from path:
선택
- Copy url
- Copy the bookmark's url to clipboard
+ URL 복사
+ 북마크의 URL을 클립보드에 복사
데이터를 가져올 브라우저:
브라우저 이름
데이터 디렉토리 위치
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
index 4344e8c3d84..06af5ea5bcd 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/pt-pt.xaml
@@ -24,5 +24,5 @@
Outros
Motor do navegador
Se não estiver a usar o Chrome, Firefox ou Edge ou se estiver a usar a versão portátil, tem que adicionar o diretório de dados dos marcadores e selecionar o motor do navegador para que este plugin funcione.
- Por exemplo: o motor do Brave é Chromium e a localização padrão dos marcadores é "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Para o navegafor Firefox, o diretório de marcadores é a pasta do utilizador que contém o ficheiro places.sqlite.
+ Por exemplo: o motor do Brave é Chromium e a localização padrão dos marcadores é "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". Para o navegador Firefox, o diretório de marcadores é a pasta de utilizador que contém o ficheiro places.sqlite.
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/ja.xaml
index 15598118cbc..757394b4cb5 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/ja.xaml
@@ -1,11 +1,11 @@
- Calculator
- Allows to do mathematical calculations.(Try 5*3-2 in Flow Launcher)
+ 電卓
+ 数式の計算ができます(Flow Launcherで「5*3-2」と入力してみてください)
Not a number (NaN)
Expression wrong or incomplete (Did you forget some parentheses?)
- Copy this number to the clipboard
+ この数字をクリップボードにコピーします
Decimal separator
The decimal separator to be used in the output.
Use system locale
diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/pt-pt.xaml
index c61f8b3df6c..b751f3f397b 100644
--- a/Plugins/Flow.Launcher.Plugin.Calculator/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Calculator/Languages/pt-pt.xaml
@@ -7,7 +7,7 @@
Expressão errada ou incompleta (esqueceu-se de algum parêntese?)
Copiar número para a área de transferência
Separador decimal
- O separador decimal a ser usado no resultado.
+ O separador decimal para utilizar no resultado.
Utilizar definições do sistema
Vírgula (,)
Ponto (.)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
index df619997671..29c97a65192 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/ja.xaml
@@ -21,26 +21,26 @@
削除
- 編
- 追
- General Setting
- Customise Action Keywords
+ 編集
+ 追加
+ 一般設定
+ アクションキーワードのカスタマイズ
Quick Access Links
Everything Setting
- Preview Panel
+ プレビューパネル
サイズ
- Date Created
- Date Modified
- Display File Info
- Date and time format
+ 作成日時
+ 更新日時
+ ファイル情報の表示
+ 日付と時刻の形式
Sort Option:
Everything Path:
Launch Hidden
Editor Path
Shell Path
- Index Search Excluded Paths
- Use search result's location as the working directory of the executable
- Hit Enter to open folder in Default File Manager
+ インデックス検索の除外パス
+ 検索結果の場所を実行ファイルの作業ディレクトリとして使用
+ Enterキーで既定のファイルマネージャーでフォルダーを開く
Use Index Search For Path Search
Indexing Options
Search:
@@ -49,7 +49,7 @@
Index Search:
Quick Access:
Current Action Keyword
- 完
+ 完了
Enabled
When disabled Flow will not execute this search option, and will additionally revert back to '*' to free up the action keyword
Everything
@@ -63,57 +63,57 @@
Content Search Engine
Directory Recursive Search Engine
Index Search Engine
- Open Windows Index Option
+ Windowsのインデックスオプションを開く
Excluded File Types (comma seperated)
For example: exe,jpg,png
Maximum results
The maximum number of results requested from active search engine
- Explorer
- Find and manage files and folders via Windows Search or Everything
+ エクスプローラー
+ Windows SearchまたはEverythingを使って、ファイルやフォルダーを検索・管理します
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
- Copy path
- Copy path of current item to clipboard
- Copy
- Copy current file to clipboard
- Copy current folder to clipboard
+ パスをコピー
+ 現在の項目のパスをコピー
+ コピー
+ 現在のファイルをコピー
+ 現在のフォルダーをコピー
削除
- Permanently delete current file
- Permanently delete current folder
+ 現在のファイルを完全に削除
+ 現在のフォルダーを完全に削除
Path:
Delete the selected
Run as different user
Run the selected using a different user account
- Open containing folder
- Open the location that contains current item
- Open With Editor:
+ フォルダーを開く
+ 現在の項目が含まれている場所を開きます
+ エディターで開く:
Failed to open file at {0} with Editor {1} at {2}
- Open With Shell:
+ シェルで開く:
Failed to open folder {0} with Shell {1} at {2}
Exclude current and sub-directories from Index Search
Excluded from Index Search
- Open Windows Indexing Options
+ Windowsインデックスオプションを開く
Manage indexed files and folders
- Failed to open Windows Indexing Options
- Add to Quick Access
- Add current item to Quick Access
+ Windowsインデックスオプションを開けませんでした
+ クイックアクセスに追加
+ 現在の項目をクイックアクセスに追加
Successfully Added
- Successfully added to Quick Access
+ クイックアクセスに追加しました
Successfully Removed
Successfully removed from Quick Access
- Add to Quick Access so it can be opened with Explorer's Search Activation action keyword
- Remove from Quick Access
- Remove from Quick Access
- Remove current item from Quick Access
- Show Windows Context Menu
- Open With
- Select a program to open with
+ エクスプローラーの検索アクティベーション用アクションキーワードで開けるように、クイックアクセスに追加します
+ クイックアクセスから削除
+ クイックアクセスから削除
+ 現在の項目をクイックアクセスから削除
+ Windowsの右クリックメニューを表示
+ アプリで開く
+ 開くためのプログラムを選択します
{0} free of {1}
@@ -153,7 +153,7 @@
Successfully installed Everything service
Failed to automatically install Everything service. Please manually install it from https://www.voidtools.com
Click here to start it
- Unable to find an Everything installation, would you like to manually select a location?{0}{0}Click no and Everything will be automatically installed for you
+ Everythingのインストールが見つかりませんでした。手動で場所を指定しますか?{0}{0}「いいえ」をクリックすると、Everythingが自動的にインストールされます。
Do you want to enable content search for Everything?
It can be very slow without index (which is only supported in Everything v1.5+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
index 27f98449f8b..39d056e28c3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/pt-pt.xaml
@@ -6,7 +6,7 @@
Selecione a ligação para a pasta
Tem a certeza de que deseja eliminar {0}?
Tem a certeza de que pretende eliminar permanentemente este ficheiro?
- Tem a certeza de que pretende eliminar permanentemente este ficheiro ou pasta?
+ Tem a certeza de que pretende eliminar permanentemente este ficheiro/pasta?
Eliminada com sucesso
{0} eliminado(a) com sucesso.
A atribuição de uma palavra-chave global pode devolver demasiados resultados. Deve escolher uma palavra-chave específica.
diff --git a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
index cc78c9a9a47..7af9e93064d 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginIndicator/Languages/ko.xaml
@@ -1,9 +1,9 @@
- Activate {0} plugin action keyword
+ {0} 플러그인의 액션 키워드
- 플러그인 인디케이터
+ 플러그인 키워드 힌트
사용중인 플러그인들의 전체 액션 키워드 목록을 보여줍니다
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
index 04619239de1..006dd93d6f7 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ar.xaml
@@ -8,6 +8,7 @@
قتل عمليات {0}
قتل جميع الأمثلة
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
index d621b63c4d5..d53616cc08c 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/cs.xaml
@@ -8,6 +8,7 @@
ukončit {0} procesů
ukončit všechny instance
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/da.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
index 766d170a49b..7968ef2d843 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/de.xaml
@@ -8,6 +8,7 @@
{0} Prozesse beenden
Alle Instanzen beenden
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
index 9b4a20a69ab..50799dca26f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es-419.xaml
@@ -8,6 +8,7 @@
terminar {0} procesos
termina todas las instancias
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
index ab788075e73..6ab3f979760 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/es.xaml
@@ -8,6 +8,7 @@
finalizar {0} procesos
finalizar todas las instancias
+ Mostrar el título de los procesos con ventanas visibles
Colocar procesos con ventanas visibles en la parte superior
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
index 7064de1fe1b..ae3b6bab286 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/fr.xaml
@@ -8,6 +8,7 @@
Tuer {0} processus
Tuer toutes les instances
+ Afficher le titre des processus avec des fenêtres visibles
Placer les processus dont les fenêtres sont visibles en haut de la page
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
index 8567b541255..15d14a42c7b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/he.xaml
@@ -8,6 +8,7 @@
סגור {0} תהליכים
סגור את כל המופעים
+ הצג כותרת עבור תהליכים בעלי חלונות גלויים
הצב תהליכים עם חלונות גלויים בחלק העליון
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
index 1333fe573be..5bd4a9eaccf 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/it.xaml
@@ -8,6 +8,7 @@
termina {0} processi
termina tutte le istanze
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ja.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
index c3d1f6d083f..09679a58b72 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ko.xaml
@@ -8,6 +8,7 @@
{0} 프로세스 종료
모든 인스턴스 종료
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
index 1210818bfc7..37413385d37 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nb.xaml
@@ -8,6 +8,7 @@
terminer {0} processes
terminer alle forekomstene
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
index cfcd71c3775..ea9f9a59161 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/nl.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Zet processen met zichtbare vensters bovenaan
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
index 650f146575d..7e59db5ec06 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pl.xaml
@@ -8,6 +8,7 @@
zamknij {0} procesów
zamknij wszystkie instancje
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-br.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
index 944a883c933..b50a3174481 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/pt-pt.xaml
@@ -8,6 +8,7 @@
terminar {0} processos
terminar todas as instâncias
+ Mostrar título dos processos com janelas visíveis
Colocar processos com janelas visíveis por cima
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
index 0e2bef05283..d030a778e10 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/ru.xaml
@@ -8,6 +8,7 @@
удалить {0} процессов
удалить все экземпляры
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
index 2b06d3bbe13..6c85b947614 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sk.xaml
@@ -8,6 +8,7 @@
ukončiť {0} procesov
ukončiť všetky inštancie
+ Zobraziť nadpis pre procesy s viditeľnými oknami
Zobraziť procesy s viditeľným oknom navrchu
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/sr.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/tr.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
index 02dab46ba7b..56004028bb7 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/uk-UA.xaml
@@ -8,6 +8,7 @@
вбити {0} процесів
вбити всі екземпляри
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
index 89fd67635fa..5ce54a0dc5b 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/vi.xaml
@@ -8,6 +8,7 @@
Buộc tắt các tiến trình {0}
Tắt tất cả phên bản
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
index 15e717c79c3..ceb909db114 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-cn.xaml
@@ -8,6 +8,7 @@
杀死 {0} 进程
杀死所有实例
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
index 8563f49a0e2..0a7176d2c4f 100644
--- a/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.ProcessKiller/Languages/zh-tw.xaml
@@ -8,6 +8,7 @@
kill {0} processes
kill all instances
+ Show title for processes with visible windows
Put processes with visible windows on the top
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
index 69ca16b69f6..d352368cbbd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ar.xaml
@@ -74,7 +74,7 @@
التشغيل كمستخدم مختلف
التشغيل كمسؤول
فتح المجلد المحتوي
- تعطيل عرض هذا البرنامج
+ Hide
فتح المجلد الهدف
البرنامج
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
index 1c70c6b6f02..ca57bf0275d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/cs.xaml
@@ -74,7 +74,7 @@
Spustit jako jiný uživatel
Spustit jako správce
Otevřít umístění složky
- Zakázat zobrazování tohoto programu
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
index 0f39f5d5664..a0f09a3b502 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/da.xaml
@@ -74,7 +74,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
index 14e228b2ad4..ec5d273d6fa 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/de.xaml
@@ -74,7 +74,7 @@
Als anderer Benutzer ausführen
Als Administrator ausführen
Enthaltenden Ordner öffnen
- Dieses Programm von der Anzeige deaktivieren
+ Hide
Zielordner öffnen
Programm
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
index b928bd1ce7e..d9ffa668c87 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/es-419.xaml
@@ -74,7 +74,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
index 57b5c94b765..d0b6851d98e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/es.xaml
@@ -74,7 +74,7 @@
Ejecutar como usuario diferente
Ejecutar como administrador
Abrir carpeta contenedora
- Desactivar la visualización de este programa
+ Ocultar
Abrir carpeta de destino
Programa
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
index 7cccd5a4285..e6fd679362f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/fr.xaml
@@ -74,7 +74,7 @@
Exécuter en tant qu'utilisateur différent
Exécuter en tant qu'administrateur
Ouvrir l'emplacement du fichier
- Masquer ce programme des résultats
+ Masquer
Ouvrir le répertoire cible
Programmes
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
index af272fb4635..88053ac57d9 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/he.xaml
@@ -74,7 +74,7 @@
הפעל כמשתמש אחר
הפעל כמנהל
פתח תיקייה מכילה
- השבת הצגת תוכנה זו
+ הסתר
פתח תיקיית יעד
תוכנה
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
index cf5de9bab9c..5004d41cf72 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/it.xaml
@@ -74,7 +74,7 @@
Esegui Come Utente Differente
Esegui Come Amministratore
Apri percorso file
- Disabilita questo programma dalla visualizzazione
+ Hide
Open target folder
Programma
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
index 1f1dd4d3734..96ca3af6079 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ja.xaml
@@ -4,12 +4,12 @@
Reset Default
削除
- 編
- 追
+ 編集
+ 追加
Name
有効
Enabled
- Disable
+ 無効
Status
Enabled
Disabled
@@ -28,11 +28,11 @@
When enabled, Flow will load programs from the registry
PATH
When enabled, Flow will load programs from the PATH environment variable
- Hide app path
- For executable files such as UWP or lnk, hide the file path from being visible
+ アプリのパスを非表示
+ UWPやlnkなどの実行可能ファイルについて、サブタイトル領域にファイルパスが表示されないようにします。
Hide uninstallers
Hides programs with common uninstaller names, such as unins000.exe
- Search in Program Description
+ プログラムの説明で検索
Flow will search program's description
Hide duplicated apps
Hide duplicated Win32 programs that are already in the UWP list
@@ -71,14 +71,14 @@
Insert protocols of .url files you want to index. Protocols should be separated by ';', and should end with "://". (ex>ftp://;mailto://)
- Run As Different User
- Run As Administrator
+ 別のユーザーとして実行
+ 管理者として実行
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
- Program
- Search programs in Flow Launcher
+ プログラム
+ Flow Launcherでプログラムを検索
Invalid Path
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
index affa7567f83..266aa4b45c4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ko.xaml
@@ -34,7 +34,7 @@
Unins000처럼 일반적으로 사용되는 설치 삭제(Uninstaller) 프로그램의 이름을 숨깁니다.
프로그램 설명 검색
Flow will search program's description
- Hide duplicated apps
+ 중복된 앱 숨기기
Hide duplicated Win32 programs that are already in the UWP list
확장자
최대 깊이
@@ -74,8 +74,8 @@
다른 유저 권한으로 실행
관리자 권한으로 실행
포함된 폴더 열기
- 이 프로그램 표시 비활성화
- Open target folder
+ Hide
+ 대상 폴더 열기
프로그램
Flow Launcher에서 프로그램을 검색합니다
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
index 3fa53aba826..c4b2182043d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/nb.xaml
@@ -74,7 +74,7 @@
Kjør som en annen bruker
Kjør som administrator
Åpne inneholdende mappe
- Deaktiver visningen av dette programmet
+ Hide
Åpne målmappe
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
index 8a86dc511c4..495296694cb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/nl.xaml
@@ -74,7 +74,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
index 8a163de7ae5..f38fd962326 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pl.xaml
@@ -74,7 +74,7 @@
Uruchom jako inny użytkownik
Uruchom jako administrator
Otwórz folder nadrzędny
- Wyłącz wyświetlanie tego programu
+ Hide
Otwórz folder docelowy
Programy
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
index bab077683aa..3ff8be55188 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-br.xaml
@@ -74,7 +74,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
index c7b39459367..aa3c500a3db 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/pt-pt.xaml
@@ -74,7 +74,7 @@
Executar com outro utilizador
Executar como administrador
Abrir pasta de destino
- Desativar exibição deste programa
+ Ocultar
Abrir pasta de destino
Programas
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
index 8cb62137edb..a75a6d836fe 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/ru.xaml
@@ -74,7 +74,7 @@
Запустить от имени другого пользователя
Запустить от имени администратора
Открыть содержащую папку
- Отключить отображение этой программы
+ Hide
Open target folder
Программа
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
index ee0705b96f1..7fda651601f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/sk.xaml
@@ -74,7 +74,7 @@
Spustiť ako iný používateľ
Spustiť ako správca
Otvoriť umiestnenie priečinka
- Zakázať zobrazovanie tohto programu
+ Skryť
Otvoriť cieľový priečinok
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
index a69d7e96b1d..f2da895b0c6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/sr.xaml
@@ -74,7 +74,7 @@
Run As Different User
Run As Administrator
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
index d46de059232..6bda659dddf 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/tr.xaml
@@ -74,7 +74,7 @@
Run As Different User
Yönetici Olarak Çalıştır
Open containing folder
- Disable this program from displaying
+ Hide
Open target folder
Program
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
index 8e8d55f47bd..3686925a97f 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/uk-UA.xaml
@@ -74,7 +74,7 @@
Запустити від імені іншого користувача
Запустити від імені адміністратора
Відкрити папку
- Вимкнути відображення цієї програми
+ Hide
Відкрити цільову папку
Програма
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
index 21a3981c5a8..6b238c63854 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/vi.xaml
@@ -74,7 +74,7 @@
Xóa lựa chọn đã chọn
Chạy với quyền quản trị
Mở thư mục chứa
- Vô hiệu hóa chương trình này hiển thị
+ Hide
Mở thư mục đích
Chương trình
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml
index 6d5c0079f13..b36b72b9b97 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-cn.xaml
@@ -74,7 +74,7 @@
以其他用户身份运行
以管理员身份运行
打开文件所在文件夹
- 禁止显示该程序
+ Hide
打开目标文件夹
程序
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
index fd0bd427a70..084adfbac9c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml
@@ -74,7 +74,7 @@
Run As Different User
以系統管理員身分執行
開啟檔案位置
- Disable this program from displaying
+ Hide
Open target folder
程式
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
index 90eb4931716..781227267d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Languages/ja.xaml
@@ -12,7 +12,7 @@
Allows to execute system commands from Flow Launcher
this command has been executed {0} times
execute command through command shell
- Run As Administrator
+ 管理者として実行
Copy the command
Only show number of most used commands:
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
index 86688a130f8..b02a89a0a7b 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/he.xaml
@@ -26,7 +26,7 @@
מדריך Flow Launcher
תיקיית הנתונים של Flow Launcher
מצב משחק
- Set the Flow Launcher Theme
+ הגדר את ערכת הנושא של Flow Launcher
ערו
@@ -51,7 +51,7 @@
עיין במדריך של Flow Launcher לקבלת מידע נוסף וטיפים
פתח את מיקום תיקיית ההגדרות של Flow Launcher
הפעל/כבה מצב משחק
- Quickly change the Flow Launcher theme
+ שנה במהירות את ערכת הנושא של Flow Launcher
הצליח
@@ -62,14 +62,14 @@
האם אתה בטוח שברצונך להפעיל מחדש את המחשב עם אפשרויות אתחול מתקדמות?
האם אתה בטוח שברצונך להתנתק?
- Command Keyword Setting
- Custom Command Keyword
- Enter a keyword to search for command: {0}. This keyword is used to match your query.
- Command Keyword
+ הגדרת מילת מפתח לפקודה
+ מילת מפתח מותאמת לפקודה
+ הזן מילת מפתח כדי לחפש את הפקודה: {0}. מילת מפתח זו משמשת להתאמה לשאילתה שלך.
+ מילת מפתח לפקודה
אפס
אישו
ביטול
- Please enter a non-empty command keyword
+ אנא הזן מילת מפתח תקינה לפקודה
פקודות מערכת
מספק פקודות הקשורות למערכת, כגון כיבוי, נעילה, הגדרות ועוד.
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
index bc7dff59f4a..27fee87be24 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ja.xaml
@@ -6,20 +6,20 @@
説明
コマンド
- Shutdown
- Restart
+ シャットダウン
+ 再起動
Restart With Advanced Boot Options
Log Off/Sign Out
Lock
Sleep
Hibernate
Index Option
- Empty Recycle Bin
- Open Recycle Bin
- 終
- Save Settings
+ ごみ箱を空にする
+ ごみ箱を開く
+ 終了
+ 設定を保存
Flow Launcherを再起動する
- 設
+ 設定
プラグインデータのリロード
Check For Update
Open Log Location
@@ -28,7 +28,7 @@
Toggle Game Mode
Set the Flow Launcher Theme
- 編
+ 編集
コンピュータをシャットダウンする
@@ -41,7 +41,7 @@
このアプリの設定
スリープ
ゴミ箱を空にする
- Open recycle bin
+ ごみ箱を開く
Indexing Options
Hibernate computer
Save all Flow Launcher settings
@@ -58,17 +58,17 @@
All Flow Launcher settings saved
Reloaded all applicable plugin data
Are you sure you want to shut the computer down?
- Are you sure you want to restart the computer?
- Are you sure you want to restart the computer with Advanced Boot Options?
- Are you sure you want to log off?
+ 本当にコンピューターを再起動しますか?
+ 高度な起動オプションでコンピューターを再起動しますか?
+ 本当にログオフしますか?
Command Keyword Setting
Custom Command Keyword
Enter a keyword to search for command: {0}. This keyword is used to match your query.
Command Keyword
Reset
- Confirm
-
+ 確認
+ キャンセル
Please enter a non-empty command keyword
システムコマンド
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
index f2049038faa..e38e6e68b4a 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/ko.xaml
@@ -66,7 +66,7 @@
Custom Command Keyword
Enter a keyword to search for command: {0}. This keyword is used to match your query.
Command Keyword
- Reset
+ 초기화
확인
취소
Please enter a non-empty command keyword
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
index 9ae62885333..4112f41ff91 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ja.xaml
@@ -34,7 +34,7 @@
タイトル
- Status
+ 状態
アイコンを選択
アイコン
キャンセル
diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
index 3ac9f6a6c72..c8f069ca754 100644
--- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
+++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/ko.xaml
@@ -21,20 +21,18 @@
자동완성 데이터 출처:
웹 검색을 선택하세요
Are you sure you want to delete {0}?
- If you want to add a search for a particular website to Flow, first enter a dummy text string in the search bar of that website, and launch the search. Now copy the contents of the browser's address bar, and paste it in the URL field below. Replace your test string with {q}. For example, if you search for casino on Netflix, its address bar reads
+ 특정 웹사이트의 검색 기능을 Flow에 추가하고 싶다면, 먼저 해당 웹사이트의 검색창에 임의의 텍스트를 입력하고 검색을 실행하세요. 그런 다음 브라우저의 주소 표시줄에 표시된 내용을 복사하여 아래의 URL 필드에 붙여넣습니다. 이때, 검색에 사용한 테스트 문자열을 {q}로 바꿔주세요. 예를 들어, Netflix에서 casino를 검색하면 주소 표시줄에는 다음과 같이 표시됩니다.
https://www.netflix.com/search?q=Casino
- Now copy this entire string and paste it in the URL field below.
- Then replace casino with {q}.
- Thus, the generic formula for a search on Netflix is https://www.netflix.com/search?q={q}
+ 이제 이 전체 문자열을 복사해서 아래의 URL 필드에 붙여넣으세요. 그런 다음 casino를 **{q}**로 바꿔주세요. 따라서 Netflix에서의 일반적인 검색 형식은 다음과 같습니다: https://www.netflix.com/search?q={q}
- Copy URL
- Copy search URL to clipboard
+ URL 복사
+ 검색 주소를 클립보드에 복사
이름
- Status
+ 상태
아이콘 선택
아이콘
취소
diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
index faa8c2dcc86..5bf27c7462a 100644
--- a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
+++ b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Properties/Resources.he-IL.resx
@@ -416,7 +416,7 @@
Area Privacy
- Cangjie IME
+ קלט Cangjie
Area TimeAndLanguage
@@ -547,7 +547,7 @@
Area Control Panel (legacy settings)
- deuteranopia
+ עיוורון צבעים – אדום־ירוק
Medical: Mean you don't can see red colors
@@ -697,7 +697,7 @@
Area Control Panel (legacy settings)
- Game DVR
+ מקליט משחקים
Area Gaming
@@ -721,7 +721,7 @@
Area Control Panel (legacy settings)
- Glance
+ הצצה
Area Personalization, Deprecated in Windows 10, version 1809 and later
@@ -1251,7 +1251,7 @@
Area System
- protanopia
+ עיוורון צבעים – אדום
Medical: Mean you don't can see green colors
@@ -1297,7 +1297,7 @@
Mean the weakness you can't differ between red and green colors
- Red week
+ שבוע אדום
Mean you don't can see red colors
@@ -1332,7 +1332,7 @@
Area Control Panel (legacy settings)
- schedtasks
+ משימות מתוזמנות
File name, Should not translated
@@ -1544,7 +1544,7 @@
שקיפות
- tritanopia
+ עיוורון צבעים – כחול
Medical: Mean you don't can see yellow and blue colors
From 71b6cb2ca53ce28697fb9ed0ee75004aaf712e49 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sun, 11 May 2025 20:56:21 +0800
Subject: [PATCH 1210/1335] Fix sound effect issue after sleep or hiberation
---
Flow.Launcher/MainWindow.xaml.cs | 33 +++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index e243549e31e..46eeb2adc6e 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -22,6 +22,7 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
+using Microsoft.Win32;
using ModernWpf.Controls;
using DataObject = System.Windows.DataObject;
using Key = System.Windows.Input.Key;
@@ -88,6 +89,8 @@ public MainWindow()
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, QueryTextBox_OnPaste);
+
+ SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
#endregion
@@ -540,16 +543,29 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
#region Window Sound Effects
+ private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+ {
+ // Fix for sound not playing after sleep / hibernate
+ // https://stackoverflow.com/questions/64805186/mediaplayer-doesnt-play-after-computer-sleeps
+ if (e.Mode == PowerModes.Resume)
+ {
+ InitSoundEffects();
+ }
+ }
+
private void InitSoundEffects()
{
if (_settings.WMPInstalled)
{
+ animationSoundWMP?.Close();
animationSoundWMP = new MediaPlayer();
animationSoundWMP.Open(new Uri(AppContext.BaseDirectory + "Resources\\open.wav"));
}
else
{
+ animationSoundWPF?.Dispose();
animationSoundWPF = new SoundPlayer(AppContext.BaseDirectory + "Resources\\open.wav");
+ animationSoundWPF.Load();
}
}
@@ -816,7 +832,7 @@ private void InitProgressbarAnimation()
{
Name = progressBarAnimationName, Storyboard = progressBarStoryBoard
};
-
+
var stopStoryboard = new StopStoryboard()
{
BeginStoryboardName = progressBarAnimationName
@@ -837,7 +853,7 @@ private void InitProgressbarAnimation()
progressStyle.Triggers.Add(trigger);
ProgressBar.Style = progressStyle;
-
+
_viewModel.ProgressBarVisibility = Visibility.Hidden;
}
@@ -885,7 +901,7 @@ private void WindowAnimation()
Duration = TimeSpan.FromMilliseconds(animationLength),
FillBehavior = FillBehavior.HoldEnd
};
-
+
var rightMargin = GetThicknessFromStyle(ClockPanel.Style, new Thickness(0, 0, DefaultRightMargin, 0)).Right;
var thicknessAnimation = new ThicknessAnimation
@@ -913,10 +929,10 @@ private void WindowAnimation()
clocksb.Children.Add(ClockOpacity);
iconsb.Children.Add(IconMotion);
iconsb.Children.Add(IconOpacity);
-
+
_settings.WindowLeft = Left;
_isArrowKeyPressed = false;
-
+
clocksb.Begin(ClockPanel);
iconsb.Begin(SearchIcon);
}
@@ -1088,7 +1104,7 @@ private void QueryTextBox_OnPreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
}
-
+
#endregion
#region Placeholder
@@ -1140,7 +1156,7 @@ private void SetupResizeMode()
}
#endregion
-
+
#region Search Delay
private void QueryTextBox_TextChanged1(object sender, TextChangedEventArgs e)
@@ -1162,6 +1178,9 @@ protected virtual void Dispose(bool disposing)
{
_hwndSource?.Dispose();
_notifyIcon?.Dispose();
+ animationSoundWMP?.Close();
+ animationSoundWPF?.Dispose();
+ SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
}
_disposed = true;
From 165e498a9450c6bb5f05a256b2e96e87564ed340 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 12 May 2025 15:12:23 +0800
Subject: [PATCH 1211/1335] Fix exception when deleteing temp files
---
.../ChromiumBookmarkLoader.cs | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
index 66be0890388..e859976bdc2 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs
@@ -131,7 +131,17 @@ private void LoadFaviconsFromDb(string dbPath, List bookmarks)
}
catch (Exception ex)
{
- File.Delete(tempDbPath);
+ try
+ {
+ if (File.Exists(tempDbPath))
+ {
+ File.Delete(tempDbPath);
+ }
+ }
+ catch (Exception ex1)
+ {
+ Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex1);
+ }
Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
return;
}
From 4931a1436a5b12c99f49a596b75b13115ddf4797 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 12 May 2025 17:19:16 +0800
Subject: [PATCH 1212/1335] Validate the cache directory before loading all
bookmarks
---
Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
index 9ad31ad1401..155069495bc 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs
@@ -37,8 +37,6 @@ public void Init(PluginInitContext context)
context.CurrentPluginMetadata.PluginCacheDirectoryPath,
"FaviconCache");
- FilesFolders.ValidateDirectory(_faviconCacheDir);
-
LoadBookmarksIfEnabled();
}
@@ -50,6 +48,9 @@ private static void LoadBookmarksIfEnabled()
return;
}
+ // Validate the cache directory before loading all bookmarks because Flow needs this directory to storage favicons
+ FilesFolders.ValidateDirectory(_faviconCacheDir);
+
_cachedBookmarks = BookmarkLoader.LoadAllBookmarks(_settings);
_ = MonitorRefreshQueueAsync();
_initialized = true;
From ed148267de6bce771b554b647b64d45ab507f36d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 12 May 2025 20:37:37 +0800
Subject: [PATCH 1213/1335] Do not show error message for initialization if
plugin is already disabled
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index a3e80a73f74..eb775c2f0a7 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -220,9 +220,17 @@ public static async Task InitializePluginsAsync()
catch (Exception e)
{
API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
- pair.Metadata.Disabled = true;
- pair.Metadata.HomeDisabled = true;
- failedPlugins.Enqueue(pair);
+ if (pair.Metadata.Disabled && pair.Metadata.HomeDisabled)
+ {
+ // If this plugin is already disabled, do not show error message again
+ // Or else it will be shown every time
+ }
+ else
+ {
+ pair.Metadata.Disabled = true;
+ pair.Metadata.HomeDisabled = true;
+ failedPlugins.Enqueue(pair);
+ }
}
}));
From b96a69a5b636c91ff00b681adad785446b98f5c4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 12 May 2025 22:03:00 +0800
Subject: [PATCH 1214/1335] Fix Window Positioning with Multiple Montiors
Co-authored-by: onesounds
---
.../UserSettings/Settings.cs | 4 +
Flow.Launcher/MainWindow.xaml.cs | 87 +++++++++++++++++--
Flow.Launcher/SettingWindow.xaml.cs | 30 ++++++-
3 files changed, 109 insertions(+), 12 deletions(-)
diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index 34bf4f90e5c..ce1269a2995 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -293,6 +293,10 @@ public SearchPrecisionScore QuerySearchPrecision
public double WindowLeft { get; set; }
public double WindowTop { get; set; }
+ public double PreviousScreenWidth { get; set; }
+ public double PreviousScreenHeight { get; set; }
+ public double PreviousDpiX { get; set; }
+ public double PreviousDpiY { get; set; }
///
/// Custom left position on selected monitor
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 46eeb2adc6e..230472d8804 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -711,8 +711,26 @@ void InitializePositionInner()
{
if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
{
- Top = _settings.WindowTop;
+ var previousScreenWidth = _settings.PreviousScreenWidth;
+ var previousScreenHeight = _settings.PreviousScreenHeight;
+ GetDpi(out var previousDpiX, out var previousDpiY);
+
+ _settings.PreviousScreenWidth = SystemParameters.VirtualScreenWidth;
+ _settings.PreviousScreenHeight = SystemParameters.VirtualScreenHeight;
+ GetDpi(out var currentDpiX, out var currentDpiY);
+
+ if (previousScreenWidth != 0 && previousScreenHeight != 0 &&
+ previousDpiX != 0 && previousDpiY != 0 &&
+ (previousScreenWidth != SystemParameters.VirtualScreenWidth ||
+ previousScreenHeight != SystemParameters.VirtualScreenHeight ||
+ previousDpiX != currentDpiX || previousDpiY != currentDpiY))
+ {
+ AdjustPositionForResolutionChange();
+ return;
+ }
+
Left = _settings.WindowLeft;
+ Top = _settings.WindowTop;
}
else
{
@@ -725,27 +743,73 @@ void InitializePositionInner()
break;
case SearchWindowAligns.CenterTop:
Left = HorizonCenter(screen);
- Top = 10;
+ Top = VerticalTop(screen);
break;
case SearchWindowAligns.LeftTop:
Left = HorizonLeft(screen);
- Top = 10;
+ Top = VerticalTop(screen);
break;
case SearchWindowAligns.RightTop:
Left = HorizonRight(screen);
- Top = 10;
+ Top = VerticalTop(screen);
break;
case SearchWindowAligns.Custom:
- Left = Win32Helper.TransformPixelsToDIP(this,
- screen.WorkingArea.X + _settings.CustomWindowLeft, 0).X;
- Top = Win32Helper.TransformPixelsToDIP(this, 0,
- screen.WorkingArea.Y + _settings.CustomWindowTop).Y;
+ var customLeft = Win32Helper.TransformPixelsToDIP(this,
+ screen.WorkingArea.X + _settings.CustomWindowLeft, 0);
+ var customTop = Win32Helper.TransformPixelsToDIP(this, 0,
+ screen.WorkingArea.Y + _settings.CustomWindowTop);
+ Left = customLeft.X;
+ Top = customTop.Y;
break;
}
}
}
}
+ private void AdjustPositionForResolutionChange()
+ {
+ var screenWidth = SystemParameters.VirtualScreenWidth;
+ var screenHeight = SystemParameters.VirtualScreenHeight;
+ GetDpi(out var currentDpiX, out var currentDpiY);
+
+ var previousLeft = _settings.WindowLeft;
+ var previousTop = _settings.WindowTop;
+ GetDpi(out var previousDpiX, out var previousDpiY);
+
+ var widthRatio = screenWidth / _settings.PreviousScreenWidth;
+ var heightRatio = screenHeight / _settings.PreviousScreenHeight;
+ var dpiXRatio = currentDpiX / previousDpiX;
+ var dpiYRatio = currentDpiY / previousDpiY;
+
+ var newLeft = previousLeft * widthRatio * dpiXRatio;
+ var newTop = previousTop * heightRatio * dpiYRatio;
+
+ var screenLeft = SystemParameters.VirtualScreenLeft;
+ var screenTop = SystemParameters.VirtualScreenTop;
+
+ var maxX = screenLeft + screenWidth - ActualWidth;
+ var maxY = screenTop + screenHeight - ActualHeight;
+
+ Left = Math.Max(screenLeft, Math.Min(newLeft, maxX));
+ Top = Math.Max(screenTop, Math.Min(newTop, maxY));
+ }
+
+ private void GetDpi(out double dpiX, out double dpiY)
+ {
+ var source = PresentationSource.FromVisual(this);
+ if (source != null && source.CompositionTarget != null)
+ {
+ var matrix = source.CompositionTarget.TransformToDevice;
+ dpiX = 96 * matrix.M11;
+ dpiY = 96 * matrix.M22;
+ }
+ else
+ {
+ dpiX = 96;
+ dpiY = 96;
+ }
+ }
+
private Screen SelectedScreen()
{
Screen screen;
@@ -806,6 +870,13 @@ private double HorizonLeft(Screen screen)
return left;
}
+ public double VerticalTop(Screen screen)
+ {
+ var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
+ var top = dip1.Y + 10;
+ return top;
+ }
+
#endregion
#region Window Animation
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 79bd171edfe..cf84317acb0 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -137,18 +137,40 @@ public void UpdatePositionAndState()
if (previousTop == null || previousLeft == null || !IsPositionValid(previousTop.Value, previousLeft.Value))
{
- Top = WindowTop();
- Left = WindowLeft();
+ SetWindowPosition(WindowTop(), WindowLeft());
}
else
{
- Top = previousTop.Value;
- Left = previousLeft.Value;
+ var left = _settings.SettingWindowLeft.Value;
+ var top = _settings.SettingWindowTop.Value;
+ AdjustWindowPosition(ref top, ref left);
+ SetWindowPosition(top, left);
}
WindowState = _settings.SettingWindowState;
}
+ private void SetWindowPosition(double top, double left)
+ {
+ // Ensure window does not exceed screen boundaries
+ top = Math.Max(top, SystemParameters.VirtualScreenTop);
+ left = Math.Max(left, SystemParameters.VirtualScreenLeft);
+ top = Math.Min(top, SystemParameters.VirtualScreenHeight - ActualHeight);
+ left = Math.Min(left, SystemParameters.VirtualScreenWidth - ActualWidth);
+
+ Top = top;
+ Left = left;
+ }
+
+ private void AdjustWindowPosition(ref double top, ref double left)
+ {
+ // Adjust window position if it exceeds screen boundaries
+ top = Math.Max(top, SystemParameters.VirtualScreenTop);
+ left = Math.Max(left, SystemParameters.VirtualScreenLeft);
+ top = Math.Min(top, SystemParameters.VirtualScreenHeight - ActualHeight);
+ left = Math.Min(left, SystemParameters.VirtualScreenWidth - ActualWidth);
+ }
+
private static bool IsPositionValid(double top, double left)
{
foreach (var screen in Screen.AllScreens)
From 7509a86cbfde81f7a0696049b2e0438e6bff4f9a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 09:47:46 +0800
Subject: [PATCH 1215/1335] Use skip message for failed initialization when
plugin is already disabled
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index eb775c2f0a7..c9d13b61db3 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -219,17 +219,18 @@ public static async Task InitializePluginsAsync()
}
catch (Exception e)
{
- API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
if (pair.Metadata.Disabled && pair.Metadata.HomeDisabled)
{
// If this plugin is already disabled, do not show error message again
// Or else it will be shown every time
+ API.LogDebug(ClassName, $"Skip init for <{pair.Metadata.Name}>");
}
else
{
pair.Metadata.Disabled = true;
pair.Metadata.HomeDisabled = true;
failedPlugins.Enqueue(pair);
+ API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
}
}
}));
From 810f7bb4a79e76f6c8a950240113500199948702 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 09:58:24 +0800
Subject: [PATCH 1216/1335] Add disable information
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index c9d13b61db3..690fda011f0 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -219,6 +219,7 @@ public static async Task InitializePluginsAsync()
}
catch (Exception e)
{
+ API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
if (pair.Metadata.Disabled && pair.Metadata.HomeDisabled)
{
// If this plugin is already disabled, do not show error message again
@@ -230,7 +231,7 @@ public static async Task InitializePluginsAsync()
pair.Metadata.Disabled = true;
pair.Metadata.HomeDisabled = true;
failedPlugins.Enqueue(pair);
- API.LogException(ClassName, $"Fail to Init plugin: {pair.Metadata.Name}", e);
+ API.LogDebug(ClassName, $"Disable plugin <{pair.Metadata.Name}> because init failed");
}
}
}));
From 58f80996b7691ad8e59d0b8a3b5e20717653f6e8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 10:36:46 +0800
Subject: [PATCH 1217/1335] Fix results context menu display issue
---
.../ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
Flow.Launcher/ViewModel/MainViewModel.cs | 12 +++++++++---
Flow.Launcher/ViewModel/ResultsViewModel.cs | 16 +++++++++++++---
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index d542eb019f9..f1f3e22c68c 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,7 +479,7 @@ public SettingsPaneThemeViewModel(Settings settings, Theme theme)
)
}
};
- var vm = new ResultsViewModel(Settings);
+ var vm = new ResultsViewModel(Settings, null);
vm.AddResults(results, "PREVIEW");
PreviewResults = vm;
}
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 401f71ae3ef..ac339b715c9 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -148,19 +148,19 @@ public MainViewModel()
_userSelectedRecord = _userSelectedRecordStorage.Load();
_topMostRecord = _topMostRecordStorage.Load();
- ContextMenu = new ResultsViewModel(Settings)
+ ContextMenu = new ResultsViewModel(Settings, this)
{
LeftClickResultCommand = OpenResultCommand,
RightClickResultCommand = LoadContextMenuCommand,
IsPreviewOn = Settings.AlwaysPreview
};
- Results = new ResultsViewModel(Settings)
+ Results = new ResultsViewModel(Settings, this)
{
LeftClickResultCommand = OpenResultCommand,
RightClickResultCommand = LoadContextMenuCommand,
IsPreviewOn = Settings.AlwaysPreview
};
- History = new ResultsViewModel(Settings)
+ History = new ResultsViewModel(Settings, this)
{
LeftClickResultCommand = OpenResultCommand,
RightClickResultCommand = LoadContextMenuCommand,
@@ -1662,6 +1662,12 @@ private bool HistorySelected()
return selected;
}
+ internal bool ResultsSelected(ResultsViewModel results)
+ {
+ var selected = SelectedResults == results;
+ return selected;
+ }
+
#endregion
#region Hotkey
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index cd2736afa37..799546808ab 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -21,6 +21,7 @@ public class ResultsViewModel : BaseModel
private readonly object _collectionLock = new();
private readonly Settings _settings;
+ private readonly MainViewModel _mainVM;
private int MaxResults => _settings?.MaxResultsToShow ?? 6;
public ResultsViewModel()
@@ -29,9 +30,10 @@ public ResultsViewModel()
BindingOperations.EnableCollectionSynchronization(Results, _collectionLock);
}
- public ResultsViewModel(Settings settings) : this()
+ public ResultsViewModel(Settings settings, MainViewModel mainVM) : this()
{
_settings = settings;
+ _mainVM = mainVM;
_settings.PropertyChanged += (s, e) =>
{
switch (e.PropertyName)
@@ -179,6 +181,7 @@ public void AddResults(List newRawResults, string resultId)
UpdateResults(newResults);
}
+
///
/// To avoid deadlock, this method should not called from main thread
///
@@ -202,11 +205,18 @@ private void UpdateResults(List newResults, bool reselect = tru
SelectedItem = Results[0];
}
+ if (token.IsCancellationRequested)
+ return;
+
switch (Visibility)
{
case Visibility.Collapsed when Results.Count > 0:
- SelectedIndex = 0;
- Visibility = Visibility.Visible;
+ // Show it only if the results are selected
+ if (_mainVM == null || _mainVM.ResultsSelected(this))
+ {
+ SelectedIndex = 0;
+ Visibility = Visibility.Visible;
+ }
break;
case Visibility.Visible when Results.Count == 0:
Visibility = Visibility.Collapsed;
From fa350ddb0779f70d2fa0fbd0f7bf37c84c110638 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 10:48:00 +0800
Subject: [PATCH 1218/1335] Add code comments
---
Flow.Launcher/ViewModel/ResultsViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 799546808ab..b91bf0f309e 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,8 +211,8 @@ private void UpdateResults(List newResults, bool reselect = tru
switch (Visibility)
{
case Visibility.Collapsed when Results.Count > 0:
- // Show it only if the results are selected
- if (_mainVM == null || _mainVM.ResultsSelected(this))
+ if (_mainVM == null || // The results is for preview only in apprerance page
+ _mainVM.ResultsSelected(this)) // The results are selected
{
SelectedIndex = 0;
Visibility = Visibility.Visible;
From 8e7e1738507a0f99f75f5b7898743d8b6bf66821 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 10:49:40 +0800
Subject: [PATCH 1219/1335] Add code comments
---
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 1 +
Flow.Launcher/ViewModel/ResultsViewModel.cs | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index f1f3e22c68c..07d70a67cff 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,6 +479,7 @@ public SettingsPaneThemeViewModel(Settings settings, Theme theme)
)
}
};
+ // Set main view model to null because this results are for preview only
var vm = new ResultsViewModel(Settings, null);
vm.AddResults(results, "PREVIEW");
PreviewResults = vm;
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index b91bf0f309e..0dc1b85c44b 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,7 +211,7 @@ private void UpdateResults(List newResults, bool reselect = tru
switch (Visibility)
{
case Visibility.Collapsed when Results.Count > 0:
- if (_mainVM == null || // The results is for preview only in apprerance page
+ if (_mainVM == null || // The results are for preview only in apprerance page
_mainVM.ResultsSelected(this)) // The results are selected
{
SelectedIndex = 0;
From 03b558c1fc0947d6994f0c71d5ae002f50e52123 Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Tue, 13 May 2025 10:51:44 +0800
Subject: [PATCH 1220/1335] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher/ViewModel/ResultsViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/ViewModel/ResultsViewModel.cs b/Flow.Launcher/ViewModel/ResultsViewModel.cs
index 0dc1b85c44b..b100bba2518 100644
--- a/Flow.Launcher/ViewModel/ResultsViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultsViewModel.cs
@@ -211,7 +211,7 @@ private void UpdateResults(List newResults, bool reselect = tru
switch (Visibility)
{
case Visibility.Collapsed when Results.Count > 0:
- if (_mainVM == null || // The results are for preview only in apprerance page
+ if (_mainVM == null || // The results are for preview only in appearance page
_mainVM.ResultsSelected(this)) // The results are selected
{
SelectedIndex = 0;
From a73ff5f1227598231420e7778a0f76ded73a9c14 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 13 May 2025 13:07:49 +1000
Subject: [PATCH 1221/1335] update comment
---
Flow.Launcher.Core/Plugin/PluginManager.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs
index 690fda011f0..aae8dd76419 100644
--- a/Flow.Launcher.Core/Plugin/PluginManager.cs
+++ b/Flow.Launcher.Core/Plugin/PluginManager.cs
@@ -224,7 +224,7 @@ public static async Task InitializePluginsAsync()
{
// If this plugin is already disabled, do not show error message again
// Or else it will be shown every time
- API.LogDebug(ClassName, $"Skip init for <{pair.Metadata.Name}>");
+ API.LogDebug(ClassName, $"Skipped init for <{pair.Metadata.Name}> due to error");
}
else
{
From 93a9a92a4068906a67d46178503e09f312cb43a0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 11:11:50 +0800
Subject: [PATCH 1222/1335] Fix typos
---
.../SettingPages/ViewModels/SettingsPaneThemeViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
index 07d70a67cff..79465cd71dc 100644
--- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
+++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs
@@ -479,7 +479,7 @@ public SettingsPaneThemeViewModel(Settings settings, Theme theme)
)
}
};
- // Set main view model to null because this results are for preview only
+ // Set main view model to null because the results are for preview only
var vm = new ResultsViewModel(Settings, null);
vm.AddResults(results, "PREVIEW");
PreviewResults = vm;
From e0ac6d5feed2b4f86e7cfcf19a476506d538b362 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 12:49:35 +0800
Subject: [PATCH 1223/1335] Improve Program plugin delete button logic
---
.../Languages/en.xaml | 1 +
.../Views/ProgramSetting.xaml | 6 ++
.../Views/ProgramSetting.xaml.cs | 72 ++++++++++++-------
3 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index ee6b4379d12..c19347f2a7a 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -48,6 +48,7 @@
Please select a program source
Are you sure you want to delete the selected program sources?
+ Please select program sources that you added
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
index 5c0ba8d0bd8..3bf1c6ad1db 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml
@@ -203,6 +203,12 @@
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Click="btnEditProgramSource_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_edit}" />
+
0
@@ -141,6 +142,7 @@ private void ViewRefresh()
{
btnProgramSourceStatus.Visibility = Visibility.Visible;
btnEditProgramSource.Visibility = Visibility.Visible;
+ btnDeleteProgramSource.Visibility = Visibility.Visible;
}
programSourceView.Items.Refresh();
@@ -270,8 +272,8 @@ private void programSourceView_Drop(object sender, DragEventArgs e)
if (directoriesToAdd.Count > 0)
{
- directoriesToAdd.ForEach(x => _settings.ProgramSources.Add(x));
- directoriesToAdd.ForEach(x => ProgramSettingDisplayList.Add(x));
+ directoriesToAdd.ForEach(_settings.ProgramSources.Add);
+ directoriesToAdd.ForEach(ProgramSettingDisplayList.Add);
ViewRefresh();
ReIndexing();
@@ -296,24 +298,12 @@ private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs
if (selectedItems.Count == 0)
{
- string msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
+ var msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
context.API.ShowMsgBox(msg);
return;
}
- if (IsAllItemsUserAdded(selectedItems))
- {
- var msg = string.Format(
- context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source"));
-
- if (context.API.ShowMsgBox(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
- {
- return;
- }
-
- DeleteProgramSources(selectedItems);
- }
- else if (HasMoreOrEqualEnabledItems(selectedItems))
+ if (HasMoreOrEqualEnabledItems(selectedItems))
{
await ProgramSettingDisplay.SetProgramSourcesStatusAsync(selectedItems, false);
@@ -341,10 +331,9 @@ private void ProgramSourceView_PreviewMouseRightButtonUp(object sender, MouseBut
private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
- var headerClicked = e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;
- if (headerClicked != null)
+ if (e.OriginalSource is GridViewColumnHeader headerClicked)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
@@ -397,11 +386,7 @@ private void programSourceView_SelectionChanged(object sender, SelectionChangedE
.SelectedItems.Cast()
.ToList();
- if (IsAllItemsUserAdded(selectedItems))
- {
- btnProgramSourceStatus.Content = context.API.GetTranslation("flowlauncher_plugin_program_delete");
- }
- else if (HasMoreOrEqualEnabledItems(selectedItems))
+ if (HasMoreOrEqualEnabledItems(selectedItems))
{
btnProgramSourceStatus.Content = context.API.GetTranslation("flowlauncher_plugin_program_disable");
}
@@ -420,6 +405,43 @@ private void programSourceView_MouseDoubleClick(object sender, MouseButtonEventA
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")]
+ private async void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
+ {
+ var selectedItems = programSourceView
+ .SelectedItems.Cast()
+ .ToList();
+
+ if (selectedItems.Count == 0)
+ {
+ var msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
+ context.API.ShowMsgBox(msg);
+ return;
+ }
+
+ if (!IsAllItemsUserAdded(selectedItems))
+ {
+ var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_not_user_added");
+ context.API.ShowMsgBox(msg1);
+ return;
+ }
+
+ var msg2 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source");
+ if (context.API.ShowMsgBox(msg2, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ {
+ return;
+ }
+
+ DeleteProgramSources(selectedItems);
+
+ if (await selectedItems.IsReindexRequiredAsync())
+ ReIndexing();
+
+ programSourceView.SelectedItems.Clear();
+
+ ViewRefresh();
+ }
+
private bool IsAllItemsUserAdded(List items)
{
return items.All(x => _settings.ProgramSources.Any(y => y.UniqueIdentifier == x.UniqueIdentifier));
@@ -427,8 +449,8 @@ private bool IsAllItemsUserAdded(List items)
private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
- ListView listView = sender as ListView;
- GridView gView = listView.View as GridView;
+ var listView = sender as ListView;
+ var gView = listView.View as GridView;
var workingWidth =
listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
From 284729afb5ef3e5450f15e5f278612d3c4f5a3d7 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 13:01:24 +0800
Subject: [PATCH 1224/1335] Improve message noticification
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 3 ++-
.../Views/ProgramSetting.xaml.cs | 7 +++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index c19347f2a7a..bf6de50fe2c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -48,7 +48,8 @@
Please select a program source
Are you sure you want to delete the selected program sources?
- Please select program sources that you added
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 71879181e0f..59ee40c1231 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -303,6 +303,13 @@ private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs
return;
}
+ if (IsAllItemsUserAdded(selectedItems))
+ {
+ var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_not_user_added");
+ context.API.ShowMsgBox(msg1);
+ return;
+ }
+
if (HasMoreOrEqualEnabledItems(selectedItems))
{
await ProgramSettingDisplay.SetProgramSourcesStatusAsync(selectedItems, false);
From a0999351697248e1f90a6198eb2bbd5a0eae839c Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 13:03:04 +0800
Subject: [PATCH 1225/1335] Fix message
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 4 ++--
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index bf6de50fe2c..65fd8951c57 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -48,8 +48,8 @@
Please select a program source
Are you sure you want to delete the selected program sources?
- Please select program sources that are not added by you
- Please select program sources that are added by you
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 59ee40c1231..8b19ba81c8d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -428,7 +428,7 @@ private async void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs
if (!IsAllItemsUserAdded(selectedItems))
{
- var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_not_user_added");
+ var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_user_added");
context.API.ShowMsgBox(msg1);
return;
}
From 204d1d285a4cb26b29692588704fba4c9d95270d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 13:04:26 +0800
Subject: [PATCH 1226/1335] Improve string keys
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 4 ++--
.../Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 65fd8951c57..e551a7dcb4e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -48,8 +48,8 @@
Please select a program source
Are you sure you want to delete the selected program sources?
- Please select program sources that are not added by you
- Please select program sources that are added by you
+ Please select program sources that are not added by you
+ Please select program sources that are added by you
Another program source with the same location already exists.
Program Source
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 8b19ba81c8d..6ae1c4422c5 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -305,7 +305,7 @@ private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs
if (IsAllItemsUserAdded(selectedItems))
{
- var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_not_user_added");
+ var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_select_not_user_added");
context.API.ShowMsgBox(msg1);
return;
}
@@ -428,7 +428,7 @@ private async void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs
if (!IsAllItemsUserAdded(selectedItems))
{
- var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_user_added");
+ var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_select_user_added");
context.API.ShowMsgBox(msg1);
return;
}
From e961ffaa7a8d7dd52ab0dcb66bf081a0eb97c991 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 13 May 2025 13:08:20 +0800
Subject: [PATCH 1227/1335] Disable auto restart after plugin install by
default
---
Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
index 811bec50c50..f23ff71f01f 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
@@ -10,6 +10,6 @@ internal class Settings
public bool WarnFromUnknownSource { get; set; } = true;
- public bool AutoRestartAfterChanging { get; set; } = true;
+ public bool AutoRestartAfterChanging { get; set; } = false;
}
}
From da770855083b33eb6fab955eda4a06ac052da54f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 14 May 2025 11:37:55 +0800
Subject: [PATCH 1228/1335] Fix logic & Improve code quality
---
.../Views/ProgramSetting.xaml.cs | 22 +++++--------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index 6ae1c4422c5..9ac44708594 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -298,15 +298,7 @@ private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs
if (selectedItems.Count == 0)
{
- var msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- context.API.ShowMsgBox(msg);
- return;
- }
-
- if (IsAllItemsUserAdded(selectedItems))
- {
- var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_select_not_user_added");
- context.API.ShowMsgBox(msg1);
+ context.API.ShowMsgBox(context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source"));
return;
}
@@ -376,7 +368,7 @@ private void Sort(string sortBy, ListSortDirection direction)
var dataView = CollectionViewSource.GetDefaultView(programSourceView.ItemsSource);
dataView.SortDescriptions.Clear();
- SortDescription sd = new SortDescription(sortBy, direction);
+ var sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
@@ -421,20 +413,18 @@ private async void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs
if (selectedItems.Count == 0)
{
- var msg = context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source");
- context.API.ShowMsgBox(msg);
+ context.API.ShowMsgBox(context.API.GetTranslation("flowlauncher_plugin_program_pls_select_program_source"));
return;
}
if (!IsAllItemsUserAdded(selectedItems))
{
- var msg1 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_select_user_added");
- context.API.ShowMsgBox(msg1);
+ context.API.ShowMsgBox(context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source_select_user_added"));
return;
}
- var msg2 = context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source");
- if (context.API.ShowMsgBox(msg2, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
+ if (context.API.ShowMsgBox(context.API.GetTranslation("flowlauncher_plugin_program_delete_program_source"),
+ string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return;
}
From f0aa285199266843b447635a1cafa8aa5f0c97bd Mon Sep 17 00:00:00 2001
From: DB P
Date: Wed, 14 May 2025 12:50:45 +0900
Subject: [PATCH 1229/1335] Add theme change handler to refresh frame on
application theme change
---
Flow.Launcher/MainWindow.xaml.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 46eeb2adc6e..0b7ebf14811 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -89,7 +89,7 @@ public MainWindow()
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, QueryTextBox_OnPaste);
-
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged += ThemeManager_ActualApplicationThemeChanged;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
@@ -543,6 +543,10 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
#region Window Sound Effects
+ private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
+ {
+ _theme.RefreshFrameAsync();
+ }
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
// Fix for sound not playing after sleep / hibernate
From 1e51bdc37b147cd4c9125951e7953d28da7142e0 Mon Sep 17 00:00:00 2001
From: DB P
Date: Wed, 14 May 2025 13:03:31 +0900
Subject: [PATCH 1230/1335] Unsubscribe from theme change event to prevent
memory leaks
---
Flow.Launcher/MainWindow.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 0b7ebf14811..ab26d417c60 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -1184,6 +1184,7 @@ protected virtual void Dispose(bool disposing)
_notifyIcon?.Dispose();
animationSoundWMP?.Close();
animationSoundWPF?.Dispose();
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged;
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
}
From c128a667722ece5c67b3370765a0c2d5e83bc9f3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 14 May 2025 12:09:18 +0800
Subject: [PATCH 1231/1335] Manage handle in dispose
---
Flow.Launcher/MainWindow.xaml.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 0b7ebf14811..4465c8e33ae 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -99,6 +99,11 @@ public MainWindow()
#pragma warning disable VSTHRD100 // Avoid async void methods
+ private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
+ {
+ _theme.RefreshFrameAsync();
+ }
+
private void OnSourceInitialized(object sender, EventArgs e)
{
var handle = Win32Helper.GetWindowHandle(this, true);
@@ -543,10 +548,6 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
#region Window Sound Effects
- private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
- {
- _theme.RefreshFrameAsync();
- }
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
// Fix for sound not playing after sleep / hibernate
@@ -1184,6 +1185,7 @@ protected virtual void Dispose(bool disposing)
_notifyIcon?.Dispose();
animationSoundWMP?.Close();
animationSoundWPF?.Dispose();
+ ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged;
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
}
From 8325963047c112e9762cf1ab25089bd11d563a90 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 14 May 2025 14:23:35 +0800
Subject: [PATCH 1232/1335] Fix size changed width issue
---
.../Views/ProgramSetting.xaml.cs | 3 +++
Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs | 11 +++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
index deb110698b3..57c1542e485 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs
@@ -432,6 +432,9 @@ private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
var workingWidth =
listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
+
+ if (workingWidth <= 0) return;
+
var col1 = 0.25;
var col2 = 0.15;
var col3 = 0.60;
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
index 0a38fda0432..1a8621eeb97 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/SysSettings.xaml.cs
@@ -21,16 +21,15 @@ private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
ListView listView = sender as ListView;
GridView gView = listView.View as GridView;
- var workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
+ var workingWidth =
+ listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
+
+ if (workingWidth <= 0) return;
+
var col1 = 0.2;
var col2 = 0.6;
var col3 = 0.2;
- if (workingWidth <= 0)
- {
- return;
- }
-
gView.Columns[0].Width = workingWidth * col1;
gView.Columns[1].Width = workingWidth * col2;
gView.Columns[2].Width = workingWidth * col3;
From e417a1d3a6eed686eef4934b7c0bbde05cc26303 Mon Sep 17 00:00:00 2001
From: DB P
Date: Thu, 15 May 2025 16:42:11 +0900
Subject: [PATCH 1233/1335] Add dynamic font family to SettingWindow
---
Flow.Launcher/SettingWindow.xaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index a75a51c8fbb..da128266c2c 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -13,6 +13,7 @@
MinHeight="600"
d:DataContext="{d:DesignInstance vm:SettingWindowViewModel}"
Closed="OnClosed"
+ FontFamily="{DynamicResource SettingWindowFont}"
Icon="Images\app.ico"
Left="{Binding SettingWindowLeft, Mode=TwoWay}"
Loaded="OnLoaded"
From 57dccce1bf04664b7e49721ab5e720a8d21dca18 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 15 May 2025 18:35:57 +0800
Subject: [PATCH 1234/1335] Fix setting window navigation update issue & Check
view model null instead of IsInitialized flag
---
.../Resources/Pages/WelcomePage1.xaml.cs | 2 +-
.../Resources/Pages/WelcomePage2.xaml.cs | 2 +-
.../Resources/Pages/WelcomePage3.xaml.cs | 2 +-
.../Resources/Pages/WelcomePage4.xaml.cs | 2 +-
.../Resources/Pages/WelcomePage5.xaml.cs | 2 +-
.../Views/SettingsPaneAbout.xaml.cs | 8 ++++-
.../Views/SettingsPaneGeneral.xaml.cs | 8 ++++-
.../Views/SettingsPaneHotkey.xaml.cs | 8 ++++-
.../Views/SettingsPanePluginStore.xaml.cs | 7 +++-
.../Views/SettingsPanePlugins.xaml.cs | 7 +++-
.../Views/SettingsPaneProxy.xaml.cs | 8 ++++-
.../Views/SettingsPaneTheme.xaml.cs | 8 ++++-
Flow.Launcher/SettingWindow.xaml.cs | 33 +++++++++++++++++--
.../ViewModel/SettingWindowViewModel.cs | 18 +++++++++-
14 files changed, 100 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index a3b008206d6..1b1dd21e9e9 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -14,7 +14,7 @@ public partial class WelcomePage1
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index a63edbcda7c..7408d8a14f0 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,7 +16,7 @@ public partial class WelcomePage2
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index 4a6610e6173..bd14bf0f7b9 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -12,7 +12,7 @@ public partial class WelcomePage3
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index 1ee3284d22e..b20e4ce0a47 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -12,7 +12,7 @@ public partial class WelcomePage4
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index 6328c991449..84d298966d7 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -15,7 +15,7 @@ public partial class WelcomePage5
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index e57cba6d409..93515caec5b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -1,21 +1,27 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneAbout
{
private SettingsPaneAboutViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneAbout);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index 31653962dfd..fa3406bd914 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -1,21 +1,27 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneGeneral
{
private SettingsPaneGeneralViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneGeneral);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 8b757bd60a5..e590dc9a82a 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -1,21 +1,27 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneHotkey
{
private SettingsPaneHotkeyViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneHotkey);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index 5ddfe465009..aa6900dae6f 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -11,16 +11,21 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPanePluginStore
{
private SettingsPanePluginStoreViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPanePluginStore);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index e9490804ab5..6424aabdfeb 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -11,16 +11,21 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPanePlugins
{
private SettingsPanePluginsViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPanePlugins);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
index 258f2a4adbf..c89a050f5da 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
@@ -1,21 +1,27 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneProxy
{
private SettingsPaneProxyViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneProxy);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index cee8e4ae468..8759c8efc80 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -1,21 +1,27 @@
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
+using Flow.Launcher.ViewModel;
namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneTheme
{
private SettingsPaneThemeViewModel _viewModel = null!;
+ private SettingWindowViewModel _settingViewModel = null;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- if (!IsInitialized)
+ if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
+ _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
InitializeComponent();
}
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneTheme);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index cf84317acb0..14e4343e3c8 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -18,6 +19,7 @@ public partial class SettingWindow
#region Private Fields
private readonly Settings _settings;
+ private readonly SettingWindowViewModel _viewModel;
#endregion
@@ -26,8 +28,8 @@ public partial class SettingWindow
public SettingWindow()
{
_settings = Ioc.Default.GetRequiredService();
- var viewModel = Ioc.Default.GetRequiredService();
- DataContext = viewModel;
+ _viewModel = Ioc.Default.GetRequiredService();
+ DataContext = _viewModel;
InitializeComponent();
UpdatePositionAndState();
@@ -48,10 +50,37 @@ private void OnLoaded(object sender, RoutedEventArgs e)
hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
UpdatePositionAndState();
+
+ _viewModel.PropertyChanged += ViewModel_PropertyChanged;
+ }
+
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to update the selected item here
+ private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ switch (e.PropertyName)
+ {
+ case nameof(SettingWindowViewModel.PageType):
+ var selectedIndex = _viewModel.PageType.Name switch
+ {
+ nameof(SettingsPaneGeneral) => 0,
+ nameof(SettingsPanePlugins) => 1,
+ nameof(SettingsPanePluginStore) => 2,
+ nameof(SettingsPaneTheme) => 3,
+ nameof(SettingsPaneHotkey) => 4,
+ nameof(SettingsPaneProxy) => 5,
+ nameof(SettingsPaneAbout) => 6,
+ _ => 0
+ };
+ NavView.SelectedItem = NavView.MenuItems[selectedIndex];
+ break;
+ }
}
private void OnClosed(object sender, EventArgs e)
{
+ _viewModel.PropertyChanged -= ViewModel_PropertyChanged;
+
// If app is exiting, settings save is not needed because main window closing event will handle this
if (App.Exiting) return;
// Save settings when window is closed
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 17a1a2b50f1..9e7eaf6e86a 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,5 +1,7 @@
-using Flow.Launcher.Infrastructure.UserSettings;
+using System;
+using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
+using Flow.Launcher.SettingPages.Views;
namespace Flow.Launcher.ViewModel;
@@ -12,6 +14,20 @@ public SettingWindowViewModel(Settings settings)
_settings = settings;
}
+ private Type _pageType = typeof(SettingsPaneGeneral);
+ public Type PageType
+ {
+ get => _pageType;
+ set
+ {
+ if (_pageType != value)
+ {
+ _pageType = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
public double SettingWindowWidth
{
get => _settings.SettingWindowWidth;
From 1a67c8906b42a9e0bffba8a497a57703de7ae7e8 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 15 May 2025 19:36:45 +0800
Subject: [PATCH 1235/1335] Fix component initialization issue
---
Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs | 4 ++++
Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs | 4 ++++
Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs | 4 ++++
Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs | 4 ++++
Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs | 4 ++++
.../SettingPages/Views/SettingsPanePluginStore.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs | 4 ++++
Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs | 4 ++++
12 files changed, 48 insertions(+)
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 1b1dd21e9e9..3199e81b776 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -14,10 +14,14 @@ public partial class WelcomePage1
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 7408d8a14f0..1eef9fc8c79 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -16,10 +16,14 @@ public partial class WelcomePage2
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index bd14bf0f7b9..d27368aa1b4 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -12,10 +12,14 @@ public partial class WelcomePage3
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
index b20e4ce0a47..b0999504b31 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs
@@ -12,10 +12,14 @@ public partial class WelcomePage4
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
index 84d298966d7..2ece4ce8800 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs
@@ -15,10 +15,14 @@ public partial class WelcomePage5
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
Settings = Ioc.Default.GetRequiredService();
_viewModel = Ioc.Default.GetRequiredService();
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index 93515caec5b..00426546ab5 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -12,11 +12,15 @@ public partial class SettingsPaneAbout
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index fa3406bd914..524e4f5f581 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -12,11 +12,15 @@ public partial class SettingsPaneGeneral
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index e590dc9a82a..53a639aa564 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -12,11 +12,15 @@ public partial class SettingsPaneHotkey
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index aa6900dae6f..34cd33ec10b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -15,11 +15,15 @@ public partial class SettingsPanePluginStore
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index 6424aabdfeb..94e0d24a24c 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -15,11 +15,15 @@ public partial class SettingsPanePlugins
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
index c89a050f5da..aa47383e850 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
@@ -12,11 +12,15 @@ public partial class SettingsPaneProxy
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index 8759c8efc80..215a8c70c40 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -12,11 +12,15 @@ public partial class SettingsPaneTheme
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
_settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
+ }
+ if (!IsInitialized)
+ {
InitializeComponent();
}
// Sometimes the navigation is not triggered by button click,
From 5b17fad67cab25ba9da890d188c988f03835f74a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 15 May 2025 19:51:30 +0800
Subject: [PATCH 1236/1335] Fix duplicated value change
---
Flow.Launcher/SettingWindow.xaml.cs | 1 +
Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index 14e4343e3c8..d8444d45d5c 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -263,6 +263,7 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
nameof(About) => typeof(SettingsPaneAbout),
_ => typeof(SettingsPaneGeneral)
};
+ _viewModel.SetPageType(pageType);
ContentFrame.Navigate(pageType);
}
}
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 9e7eaf6e86a..5b130eb6d24 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -14,6 +14,11 @@ public SettingWindowViewModel(Settings settings)
_settings = settings;
}
+ public void SetPageType(Type pageType)
+ {
+ _pageType = pageType;
+ }
+
private Type _pageType = typeof(SettingsPaneGeneral);
public Type PageType
{
From d0e799b8edaf7378d38a7ef8bf71311dda29e262 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 15 May 2025 20:16:50 +0800
Subject: [PATCH 1237/1335] Fix double navigation issue
---
.../SettingPages/Views/SettingsPaneAbout.xaml.cs | 10 +++++-----
.../SettingPages/Views/SettingsPaneGeneral.xaml.cs | 10 +++++-----
.../SettingPages/Views/SettingsPaneHotkey.xaml.cs | 10 +++++-----
.../Views/SettingsPanePluginStore.xaml.cs | 10 +++++-----
.../SettingPages/Views/SettingsPanePlugins.xaml.cs | 10 +++++-----
.../SettingPages/Views/SettingsPaneProxy.xaml.cs | 10 +++++-----
.../SettingPages/Views/SettingsPaneTheme.xaml.cs | 10 +++++-----
Flow.Launcher/SettingWindow.xaml.cs | 11 ++++++++---
Flow.Launcher/ViewModel/SettingWindowViewModel.cs | 8 +++++---
9 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
index 00426546ab5..47532b243eb 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs
@@ -8,24 +8,24 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneAbout
{
private SettingsPaneAboutViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneAbout);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPaneAbout);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
index 524e4f5f581..753cb7b0e3b 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs
@@ -8,24 +8,24 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneGeneral
{
private SettingsPaneGeneralViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneGeneral);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPaneGeneral);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
index 53a639aa564..202869bc5d0 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs
@@ -8,24 +8,24 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneHotkey
{
private SettingsPaneHotkeyViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneHotkey);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPaneHotkey);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
index 34cd33ec10b..c0a77957ac8 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs
@@ -11,15 +11,18 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPanePluginStore
{
private SettingsPanePluginStoreViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPanePluginStore);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
@@ -27,9 +30,6 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPanePluginStore);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
index 94e0d24a24c..f486a3443ce 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs
@@ -11,15 +11,18 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPanePlugins
{
private SettingsPanePluginsViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPanePlugins);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
@@ -27,9 +30,6 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
InitializeComponent();
}
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPanePlugins);
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
index aa47383e850..3e617229d4f 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs
@@ -8,24 +8,24 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneProxy
{
private SettingsPaneProxyViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneProxy);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPaneProxy);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
index 215a8c70c40..170003994ed 100644
--- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
+++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs
@@ -8,24 +8,24 @@ namespace Flow.Launcher.SettingPages.Views;
public partial class SettingsPaneTheme
{
private SettingsPaneThemeViewModel _viewModel = null!;
- private SettingWindowViewModel _settingViewModel = null;
+ private readonly SettingWindowViewModel _settingViewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page type
+ _settingViewModel.PageType = typeof(SettingsPaneTheme);
+
// If the navigation is not triggered by button click, view model will be null again
if (_viewModel == null)
{
_viewModel = Ioc.Default.GetRequiredService();
- _settingViewModel = Ioc.Default.GetRequiredService();
DataContext = _viewModel;
}
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page type
- _settingViewModel.PageType = typeof(SettingsPaneTheme);
base.OnNavigatedTo(e);
}
}
diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs
index d8444d45d5c..ebbb3841482 100644
--- a/Flow.Launcher/SettingWindow.xaml.cs
+++ b/Flow.Launcher/SettingWindow.xaml.cs
@@ -241,6 +241,7 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
{
if (args.IsSettingsSelected)
{
+ _viewModel.SetPageType(typeof(SettingsPaneGeneral));
ContentFrame.Navigate(typeof(SettingsPaneGeneral));
}
else
@@ -263,8 +264,11 @@ private void NavigationView_SelectionChanged(NavigationView sender, NavigationVi
nameof(About) => typeof(SettingsPaneAbout),
_ => typeof(SettingsPaneGeneral)
};
- _viewModel.SetPageType(pageType);
- ContentFrame.Navigate(pageType);
+ // Only navigate if the page type changes to fix navigation forward/back issue
+ if (_viewModel.SetPageType(pageType))
+ {
+ ContentFrame.Navigate(pageType);
+ }
}
}
@@ -282,7 +286,8 @@ private void NavView_Loaded(object sender, RoutedEventArgs e)
private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
- NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
+ _viewModel.SetPageType(null); // Set page type to null so that NavigationView_SelectionChanged can navigate the frame
+ NavView.SelectedItem = NavView.MenuItems[0]; /* Set First Page */
}
#endregion
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 5b130eb6d24..1134a81b896 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -1,7 +1,6 @@
using System;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Flow.Launcher.SettingPages.Views;
namespace Flow.Launcher.ViewModel;
@@ -14,12 +13,15 @@ public SettingWindowViewModel(Settings settings)
_settings = settings;
}
- public void SetPageType(Type pageType)
+ public bool SetPageType(Type pageType)
{
+ if (_pageType == pageType) return false;
+
_pageType = pageType;
+ return true;
}
- private Type _pageType = typeof(SettingsPaneGeneral);
+ private Type _pageType = null;
public Type PageType
{
get => _pageType;
From ad94ebadcfc8c175c4406be9b2b055fe448cacd2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 15 May 2025 20:23:38 +0800
Subject: [PATCH 1238/1335] Fix possible issue in welcome pages
---
.../Resources/Pages/WelcomePage1.xaml.cs | 17 ++++++-----------
.../Resources/Pages/WelcomePage2.xaml.cs | 17 ++++++-----------
.../Resources/Pages/WelcomePage3.xaml.cs | 17 ++++++-----------
.../Resources/Pages/WelcomePage4.xaml.cs | 17 ++++++-----------
.../Resources/Pages/WelcomePage5.xaml.cs | 17 ++++++-----------
5 files changed, 30 insertions(+), 55 deletions(-)
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
index 3199e81b776..16252086e2b 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs
@@ -9,24 +9,19 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage1
{
- public Settings Settings { get; private set; }
- private WelcomeViewModel _viewModel;
+ public Settings Settings { get; } = Ioc.Default.GetRequiredService();
+ private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- // If the navigation is not triggered by button click, view model will be null again
- if (_viewModel == null)
- {
- Settings = Ioc.Default.GetRequiredService();
- _viewModel = Ioc.Default.GetRequiredService();
- }
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ _viewModel.PageNum = 1;
+
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page number
- _viewModel.PageNum = 1;
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
index 1eef9fc8c79..37767f1285f 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs
@@ -11,24 +11,19 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage2
{
- public Settings Settings { get; private set; }
- private WelcomeViewModel _viewModel;
+ public Settings Settings { get; } = Ioc.Default.GetRequiredService();
+ private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- // If the navigation is not triggered by button click, view model will be null again
- if (_viewModel == null)
- {
- Settings = Ioc.Default.GetRequiredService();
- _viewModel = Ioc.Default.GetRequiredService();
- }
+ // Sometimes the navigation is not triggered by button click,
+ // so we need to reset the page number
+ _viewModel.PageNum = 2;
+
if (!IsInitialized)
{
InitializeComponent();
}
- // Sometimes the navigation is not triggered by button click,
- // so we need to reset the page number
- _viewModel.PageNum = 2;
base.OnNavigatedTo(e);
}
diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
index d27368aa1b4..4c3184f8c57 100644
--- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
+++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs
@@ -7,24 +7,19 @@ namespace Flow.Launcher.Resources.Pages
{
public partial class WelcomePage3
{
- public Settings Settings { get; private set; }
- private WelcomeViewModel _viewModel;
+ public Settings Settings { get; } = Ioc.Default.GetRequiredService();
+ private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
- // If the navigation is not triggered by button click, view model will be null again
- if (_viewModel == null)
- {
- Settings = Ioc.Default.GetRequiredService();
- _viewModel = Ioc.Default.GetRequiredService